@@ -72,11 +72,10 @@ use syntax_pos::{Span, DUMMY_SP, MultiSpan};
72
72
use errors:: { Applicability , DiagnosticBuilder , DiagnosticId } ;
73
73
74
74
use std:: cell:: { Cell , RefCell } ;
75
- use std:: cmp;
75
+ use std:: { cmp, fmt , iter , ptr } ;
76
76
use std:: collections:: BTreeSet ;
77
- use std:: fmt;
78
- use std:: iter;
79
77
use std:: mem:: replace;
78
+ use rustc_data_structures:: ptr_key:: PtrKey ;
80
79
use rustc_data_structures:: sync:: Lrc ;
81
80
82
81
use resolve_imports:: { ImportDirective , ImportDirectiveSubclass , NameResolution , ImportResolver } ;
@@ -1114,6 +1113,17 @@ impl<'a> ModuleData<'a> {
1114
1113
fn nearest_item_scope ( & ' a self ) -> Module < ' a > {
1115
1114
if self . is_trait ( ) { self . parent . unwrap ( ) } else { self }
1116
1115
}
1116
+
1117
+ fn is_ancestor_of ( & self , mut other : & Self ) -> bool {
1118
+ while !ptr:: eq ( self , other) {
1119
+ if let Some ( parent) = other. parent {
1120
+ other = parent;
1121
+ } else {
1122
+ return false ;
1123
+ }
1124
+ }
1125
+ true
1126
+ }
1117
1127
}
1118
1128
1119
1129
impl < ' a > fmt:: Debug for ModuleData < ' a > {
@@ -1411,6 +1421,7 @@ pub struct Resolver<'a, 'b: 'a> {
1411
1421
block_map : NodeMap < Module < ' a > > ,
1412
1422
module_map : FxHashMap < DefId , Module < ' a > > ,
1413
1423
extern_module_map : FxHashMap < ( DefId , bool /* MacrosOnly? */ ) , Module < ' a > > ,
1424
+ binding_parent_modules : FxHashMap < PtrKey < ' a , NameBinding < ' a > > , Module < ' a > > ,
1414
1425
1415
1426
pub make_glob_map : bool ,
1416
1427
/// Maps imports to the names of items actually imported (this actually maps
@@ -1714,6 +1725,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
1714
1725
module_map,
1715
1726
block_map : NodeMap ( ) ,
1716
1727
extern_module_map : FxHashMap ( ) ,
1728
+ binding_parent_modules : FxHashMap ( ) ,
1717
1729
1718
1730
make_glob_map : make_glob_map == MakeGlobMap :: Yes ,
1719
1731
glob_map : NodeMap ( ) ,
@@ -4596,6 +4608,31 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
4596
4608
vis. is_accessible_from ( module. normal_ancestor_id , self )
4597
4609
}
4598
4610
4611
+ fn set_binding_parent_module ( & mut self , binding : & ' a NameBinding < ' a > , module : Module < ' a > ) {
4612
+ if let Some ( old_module) = self . binding_parent_modules . insert ( PtrKey ( binding) , module) {
4613
+ if !ptr:: eq ( module, old_module) {
4614
+ span_bug ! ( binding. span, "parent module is reset for binding" ) ;
4615
+ }
4616
+ }
4617
+ }
4618
+
4619
+ fn disambiguate_legacy_vs_modern (
4620
+ & self ,
4621
+ legacy : & ' a NameBinding < ' a > ,
4622
+ modern : & ' a NameBinding < ' a > ,
4623
+ ) -> bool {
4624
+ // Some non-controversial subset of ambiguities "modern macro name" vs "macro_rules"
4625
+ // is disambiguated to mitigate regressions from macro modularization.
4626
+ // Scoping for `macro_rules` behaves like scoping for `let` at module level, in general.
4627
+ match ( self . binding_parent_modules . get ( & PtrKey ( legacy) ) ,
4628
+ self . binding_parent_modules . get ( & PtrKey ( modern) ) ) {
4629
+ ( Some ( legacy) , Some ( modern) ) =>
4630
+ legacy. normal_ancestor_id == modern. normal_ancestor_id &&
4631
+ modern. is_ancestor_of ( legacy) ,
4632
+ _ => false ,
4633
+ }
4634
+ }
4635
+
4599
4636
fn report_ambiguity_error ( & self , ident : Ident , b1 : & NameBinding , b2 : & NameBinding ) {
4600
4637
let participle = |is_import : bool | if is_import { "imported" } else { "defined" } ;
4601
4638
let msg1 =
0 commit comments