@@ -72,11 +72,10 @@ use syntax_pos::{Span, DUMMY_SP, MultiSpan};
7272use errors:: { Applicability , DiagnosticBuilder , DiagnosticId } ;
7373
7474use std:: cell:: { Cell , RefCell } ;
75- use std:: cmp;
75+ use std:: { cmp, fmt , iter , ptr } ;
7676use std:: collections:: BTreeSet ;
77- use std:: fmt;
78- use std:: iter;
7977use std:: mem:: replace;
78+ use rustc_data_structures:: ptr_key:: PtrKey ;
8079use rustc_data_structures:: sync:: Lrc ;
8180
8281use resolve_imports:: { ImportDirective , ImportDirectiveSubclass , NameResolution , ImportResolver } ;
@@ -1114,6 +1113,17 @@ impl<'a> ModuleData<'a> {
11141113 fn nearest_item_scope ( & ' a self ) -> Module < ' a > {
11151114 if self . is_trait ( ) { self . parent . unwrap ( ) } else { self }
11161115 }
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+ }
11171127}
11181128
11191129impl < ' a > fmt:: Debug for ModuleData < ' a > {
@@ -1411,6 +1421,7 @@ pub struct Resolver<'a, 'b: 'a> {
14111421 block_map : NodeMap < Module < ' a > > ,
14121422 module_map : FxHashMap < DefId , Module < ' a > > ,
14131423 extern_module_map : FxHashMap < ( DefId , bool /* MacrosOnly? */ ) , Module < ' a > > ,
1424+ binding_parent_modules : FxHashMap < PtrKey < ' a , NameBinding < ' a > > , Module < ' a > > ,
14141425
14151426 pub make_glob_map : bool ,
14161427 /// Maps imports to the names of items actually imported (this actually maps
@@ -1714,6 +1725,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
17141725 module_map,
17151726 block_map : NodeMap ( ) ,
17161727 extern_module_map : FxHashMap ( ) ,
1728+ binding_parent_modules : FxHashMap ( ) ,
17171729
17181730 make_glob_map : make_glob_map == MakeGlobMap :: Yes ,
17191731 glob_map : NodeMap ( ) ,
@@ -4596,6 +4608,31 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
45964608 vis. is_accessible_from ( module. normal_ancestor_id , self )
45974609 }
45984610
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+
45994636 fn report_ambiguity_error ( & self , ident : Ident , b1 : & NameBinding , b2 : & NameBinding ) {
46004637 let participle = |is_import : bool | if is_import { "imported" } else { "defined" } ;
46014638 let msg1 =
0 commit comments