@@ -9,7 +9,7 @@ use GenericParameters::*;
9
9
use RibKind :: * ;
10
10
11
11
use crate :: { path_names_to_string, BindingError , CrateLint , LexicalScopeBinding } ;
12
- use crate :: { Module , ModuleOrUniformRoot , NameBinding , NameBindingKind , ParentScope , PathResult } ;
12
+ use crate :: { Module , ModuleOrUniformRoot , NameBindingKind , ParentScope , PathResult } ;
13
13
use crate :: { ResolutionError , Resolver , Segment , UseError } ;
14
14
15
15
use log:: debug;
@@ -1327,78 +1327,37 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
1327
1327
& mut self . ribs [ ns] . last_mut ( ) . unwrap ( ) . bindings
1328
1328
}
1329
1329
1330
- fn resolve_pattern ( & mut self ,
1331
- pat : & Pat ,
1332
- pat_src : PatternSource ,
1333
- // Maps idents to the node ID for the
1334
- // outermost pattern that binds them.
1335
- bindings : & mut FxHashMap < Ident , NodeId > ) {
1330
+ fn resolve_pattern (
1331
+ & mut self ,
1332
+ pat : & Pat ,
1333
+ pat_src : PatternSource ,
1334
+ // Maps idents to the node ID for the outermost pattern that binds them.
1335
+ bindings : & mut FxHashMap < Ident , NodeId > ,
1336
+ ) {
1336
1337
// Visit all direct subpatterns of this pattern.
1337
1338
let outer_pat_id = pat. id ;
1338
1339
pat. walk ( & mut |pat| {
1339
1340
debug ! ( "resolve_pattern pat={:?} node={:?}" , pat, pat. node) ;
1340
1341
match pat. node {
1341
- PatKind :: Ident ( bmode, ident, ref opt_pat) => {
1342
- // First try to resolve the identifier as some existing
1343
- // entity, then fall back to a fresh binding.
1344
- let binding = self . resolve_ident_in_lexical_scope ( ident, ValueNS ,
1345
- None , pat. span )
1346
- . and_then ( LexicalScopeBinding :: item) ;
1347
- let res = binding. map ( NameBinding :: res) . and_then ( |res| {
1348
- let is_syntactic_ambiguity = opt_pat. is_none ( ) &&
1349
- bmode == BindingMode :: ByValue ( Mutability :: Immutable ) ;
1350
- match res {
1351
- Res :: Def ( DefKind :: Ctor ( _, CtorKind :: Const ) , _) |
1352
- Res :: Def ( DefKind :: Const , _) if is_syntactic_ambiguity => {
1353
- // Disambiguate in favor of a unit struct/variant
1354
- // or constant pattern.
1355
- self . r . record_use ( ident, ValueNS , binding. unwrap ( ) , false ) ;
1356
- Some ( res)
1357
- }
1358
- Res :: Def ( DefKind :: Ctor ( ..) , _)
1359
- | Res :: Def ( DefKind :: Const , _)
1360
- | Res :: Def ( DefKind :: Static , _) => {
1361
- // This is unambiguously a fresh binding, either syntactically
1362
- // (e.g., `IDENT @ PAT` or `ref IDENT`) or because `IDENT` resolves
1363
- // to something unusable as a pattern (e.g., constructor function),
1364
- // but we still conservatively report an error, see
1365
- // issues/33118#issuecomment-233962221 for one reason why.
1366
- self . r . report_error (
1367
- ident. span ,
1368
- ResolutionError :: BindingShadowsSomethingUnacceptable (
1369
- pat_src. descr ( ) , ident. name , binding. unwrap ( ) )
1370
- ) ;
1371
- None
1372
- }
1373
- Res :: Def ( DefKind :: Fn , _) | Res :: Err => {
1374
- // These entities are explicitly allowed
1375
- // to be shadowed by fresh bindings.
1376
- None
1377
- }
1378
- res => {
1379
- span_bug ! ( ident. span, "unexpected resolution for an \
1380
- identifier in pattern: {:?}", res) ;
1381
- }
1382
- }
1383
- } ) . unwrap_or_else ( || {
1384
- self . fresh_binding ( ident, pat. id , outer_pat_id, pat_src, bindings)
1385
- } ) ;
1386
-
1342
+ PatKind :: Ident ( bmode, ident, ref sub) => {
1343
+ // First try to resolve the identifier as some existing entity,
1344
+ // then fall back to a fresh binding.
1345
+ let has_sub = sub. is_some ( ) ;
1346
+ let res = self . try_resolve_as_non_binding ( pat_src, pat, bmode, ident, has_sub)
1347
+ . unwrap_or_else ( || {
1348
+ self . fresh_binding ( ident, pat. id , outer_pat_id, pat_src, bindings)
1349
+ } ) ;
1387
1350
self . r . record_partial_res ( pat. id , PartialRes :: new ( res) ) ;
1388
1351
}
1389
-
1390
1352
PatKind :: TupleStruct ( ref path, ..) => {
1391
1353
self . smart_resolve_path ( pat. id , None , path, PathSource :: TupleStruct ) ;
1392
1354
}
1393
-
1394
1355
PatKind :: Path ( ref qself, ref path) => {
1395
1356
self . smart_resolve_path ( pat. id , qself. as_ref ( ) , path, PathSource :: Pat ) ;
1396
1357
}
1397
-
1398
1358
PatKind :: Struct ( ref path, ..) => {
1399
1359
self . smart_resolve_path ( pat. id , None , path, PathSource :: Struct ) ;
1400
1360
}
1401
-
1402
1361
_ => { }
1403
1362
}
1404
1363
true
@@ -1407,6 +1366,58 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
1407
1366
visit:: walk_pat ( self , pat) ;
1408
1367
}
1409
1368
1369
+ fn try_resolve_as_non_binding (
1370
+ & mut self ,
1371
+ pat_src : PatternSource ,
1372
+ pat : & Pat ,
1373
+ bm : BindingMode ,
1374
+ ident : Ident ,
1375
+ has_sub : bool ,
1376
+ ) -> Option < Res > {
1377
+ let binding = self . resolve_ident_in_lexical_scope ( ident, ValueNS , None , pat. span ) ?. item ( ) ?;
1378
+ let res = binding. res ( ) ;
1379
+
1380
+ // An immutable (no `mut`) by-value (no `ref`) binding pattern without
1381
+ // a sub pattern (no `@ $pat`) is syntactically ambiguous as it could
1382
+ // also be interpreted as a path to e.g. a constant, variant, etc.
1383
+ let is_syntactic_ambiguity = !has_sub && bm == BindingMode :: ByValue ( Mutability :: Immutable ) ;
1384
+
1385
+ match res {
1386
+ Res :: Def ( DefKind :: Ctor ( _, CtorKind :: Const ) , _) |
1387
+ Res :: Def ( DefKind :: Const , _) if is_syntactic_ambiguity => {
1388
+ // Disambiguate in favor of a unit struct/variant or constant pattern.
1389
+ self . r . record_use ( ident, ValueNS , binding, false ) ;
1390
+ Some ( res)
1391
+ }
1392
+ Res :: Def ( DefKind :: Ctor ( ..) , _)
1393
+ | Res :: Def ( DefKind :: Const , _)
1394
+ | Res :: Def ( DefKind :: Static , _) => {
1395
+ // This is unambiguously a fresh binding, either syntactically
1396
+ // (e.g., `IDENT @ PAT` or `ref IDENT`) or because `IDENT` resolves
1397
+ // to something unusable as a pattern (e.g., constructor function),
1398
+ // but we still conservatively report an error, see
1399
+ // issues/33118#issuecomment-233962221 for one reason why.
1400
+ self . r . report_error (
1401
+ ident. span ,
1402
+ ResolutionError :: BindingShadowsSomethingUnacceptable (
1403
+ pat_src. descr ( ) ,
1404
+ ident. name ,
1405
+ binding,
1406
+ ) ,
1407
+ ) ;
1408
+ None
1409
+ }
1410
+ Res :: Def ( DefKind :: Fn , _) | Res :: Err => {
1411
+ // These entities are explicitly allowed to be shadowed by fresh bindings.
1412
+ None
1413
+ }
1414
+ res => {
1415
+ span_bug ! ( ident. span, "unexpected resolution for an \
1416
+ identifier in pattern: {:?}", res) ;
1417
+ }
1418
+ }
1419
+ }
1420
+
1410
1421
// High-level and context dependent path resolution routine.
1411
1422
// Resolves the path and records the resolution into definition map.
1412
1423
// If resolution fails tries several techniques to find likely
0 commit comments