@@ -784,6 +784,11 @@ impl LocalDef {
784
784
}
785
785
}
786
786
787
+ enum LexicalScopeBinding < ' a > {
788
+ Item ( & ' a NameBinding < ' a > ) ,
789
+ LocalDef ( LocalDef ) ,
790
+ }
791
+
787
792
/// The link from a module up to its nearest parent node.
788
793
#[ derive( Clone , Debug ) ]
789
794
enum ParentLink < ' a > {
@@ -1430,40 +1435,66 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
1430
1435
span)
1431
1436
}
1432
1437
1433
- /// This function resolves `name` in `namespace` in the current lexical scope, returning
1434
- /// Success(binding) if `name` resolves to an item, or Failed(None) if `name` does not resolve
1435
- /// or resolves to a type parameter or local variable.
1436
- /// n.b. `resolve_identifier_in_local_ribs` also resolves names in the current lexical scope.
1438
+ /// This resolves the identifier `ident` in the namespace `ns` in the current lexical scope.
1439
+ /// More specifically, we proceed up the hierarchy of scopes and return the binding for
1440
+ /// `ident` in the first scope that defines it (or None if no scopes define it).
1441
+ ///
1442
+ /// A block's items are above its local variables in the scope hierarchy, regardless of where
1443
+ /// the items are defined in the block. For example,
1444
+ /// ```rust
1445
+ /// fn f() {
1446
+ /// g(); // Since there are no local variables in scope yet, this resolves to the item.
1447
+ /// let g = || {};
1448
+ /// fn g() {}
1449
+ /// g(); // This resolves to the local variable `g` since it shadows the item.
1450
+ /// }
1451
+ /// ```
1437
1452
///
1438
1453
/// Invariant: This must only be called during main resolution, not during
1439
1454
/// import resolution.
1440
- fn resolve_item_in_lexical_scope ( & mut self ,
1441
- name : Name ,
1442
- namespace : Namespace ,
1443
- record_used : bool )
1444
- -> ResolveResult < & ' a NameBinding < ' a > > {
1455
+ fn resolve_ident_in_lexical_scope ( & mut self ,
1456
+ ident : hir:: Ident ,
1457
+ ns : Namespace ,
1458
+ record_used : bool )
1459
+ -> Option < LexicalScopeBinding < ' a > > {
1460
+ let name = match ns { ValueNS => ident. name , TypeNS => ident. unhygienic_name } ;
1461
+
1445
1462
// Walk backwards up the ribs in scope.
1446
- for i in ( 0 .. self . get_ribs ( namespace) . len ( ) ) . rev ( ) {
1447
- if let Some ( _) = self . get_ribs ( namespace) [ i] . bindings . get ( & name) . cloned ( ) {
1448
- // The name resolves to a type parameter or local variable, so return Failed(None).
1449
- return Failed ( None ) ;
1450
- }
1451
-
1452
- if let ModuleRibKind ( module) = self . get_ribs ( namespace) [ i] . kind {
1453
- if let Success ( binding) = self . resolve_name_in_module ( module,
1454
- name,
1455
- namespace,
1456
- true ,
1457
- record_used) {
1458
- // The name resolves to an item.
1459
- return Success ( binding) ;
1463
+ for i in ( 0 .. self . get_ribs ( ns) . len ( ) ) . rev ( ) {
1464
+ if let Some ( def) = self . get_ribs ( ns) [ i] . bindings . get ( & name) . cloned ( ) {
1465
+ // The ident resolves to a type parameter or local variable.
1466
+ return Some ( LexicalScopeBinding :: LocalDef ( LocalDef {
1467
+ ribs : Some ( ( ns, i) ) ,
1468
+ def : def,
1469
+ } ) ) ;
1470
+ }
1471
+
1472
+ if let ModuleRibKind ( module) = self . get_ribs ( ns) [ i] . kind {
1473
+ let name = ident. unhygienic_name ;
1474
+ let item = self . resolve_name_in_module ( module, name, ns, true , record_used) ;
1475
+ if let Success ( binding) = item {
1476
+ // The ident resolves to an item.
1477
+ return Some ( LexicalScopeBinding :: Item ( binding) ) ;
1460
1478
}
1479
+
1461
1480
// We can only see through anonymous modules
1462
- if module. def . is_some ( ) { return Failed ( None ) ; }
1481
+ if module. def . is_some ( ) { return None ; }
1463
1482
}
1464
1483
}
1465
1484
1466
- Failed ( None )
1485
+ None
1486
+ }
1487
+
1488
+ fn resolve_item_in_lexical_scope ( & mut self ,
1489
+ name : Name ,
1490
+ namespace : Namespace ,
1491
+ record_used : bool )
1492
+ -> ResolveResult < & ' a NameBinding < ' a > > {
1493
+ let ident = hir:: Ident :: from_name ( name) ;
1494
+ match self . resolve_ident_in_lexical_scope ( ident, namespace, record_used) {
1495
+ Some ( LexicalScopeBinding :: Item ( binding) ) => Success ( binding) ,
1496
+ _ => Failed ( None ) ,
1497
+ }
1467
1498
}
1468
1499
1469
1500
/// Returns the nearest normal module parent of the given module.
@@ -2861,33 +2892,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
2861
2892
namespace : Namespace ,
2862
2893
record_used : bool )
2863
2894
-> Option < LocalDef > {
2864
- // Check the local set of ribs.
2865
- let name = match namespace { ValueNS => ident. name , TypeNS => ident. unhygienic_name } ;
2866
-
2867
- for i in ( 0 .. self . get_ribs ( namespace) . len ( ) ) . rev ( ) {
2868
- if let Some ( def) = self . get_ribs ( namespace) [ i] . bindings . get ( & name) . cloned ( ) {
2869
- return Some ( LocalDef {
2870
- ribs : Some ( ( namespace, i) ) ,
2871
- def : def,
2872
- } ) ;
2873
- }
2874
-
2875
- if let ModuleRibKind ( module) = self . get_ribs ( namespace) [ i] . kind {
2876
- if let Success ( binding) = self . resolve_name_in_module ( module,
2877
- ident. unhygienic_name ,
2878
- namespace,
2879
- true ,
2880
- record_used) {
2881
- if let Some ( def) = binding. def ( ) {
2882
- return Some ( LocalDef :: from_def ( def) ) ;
2883
- }
2884
- }
2885
- // We can only see through anonymous modules
2886
- if module. def . is_some ( ) { return None ; }
2887
- }
2888
- }
2889
-
2890
- None
2895
+ Some ( match self . resolve_ident_in_lexical_scope ( ident, namespace, record_used) {
2896
+ Some ( LexicalScopeBinding :: LocalDef ( local_def) ) => local_def,
2897
+ Some ( LexicalScopeBinding :: Item ( binding) ) => LocalDef :: from_def ( binding. def ( ) . unwrap ( ) ) ,
2898
+ None => return None ,
2899
+ } )
2891
2900
}
2892
2901
2893
2902
fn with_no_errors < T , F > ( & mut self , f : F ) -> T
0 commit comments