@@ -71,11 +71,10 @@ use syntax_pos::{Span, DUMMY_SP, MultiSpan};
71
71
use errors:: { Applicability , DiagnosticBuilder , DiagnosticId } ;
72
72
73
73
use std:: cell:: { Cell , RefCell } ;
74
- use std:: cmp;
74
+ use std:: { cmp, fmt , iter , ptr } ;
75
75
use std:: collections:: BTreeSet ;
76
- use std:: fmt;
77
- use std:: iter;
78
76
use std:: mem:: replace;
77
+ use rustc_data_structures:: ptr_key:: PtrKey ;
79
78
use rustc_data_structures:: sync:: Lrc ;
80
79
81
80
use resolve_imports:: { ImportDirective , ImportDirectiveSubclass , NameResolution , ImportResolver } ;
@@ -1113,6 +1112,17 @@ impl<'a> ModuleData<'a> {
1113
1112
fn nearest_item_scope ( & ' a self ) -> Module < ' a > {
1114
1113
if self . is_trait ( ) { self . parent . unwrap ( ) } else { self }
1115
1114
}
1115
+
1116
+ fn is_ancestor_of ( & self , mut other : & Self ) -> bool {
1117
+ while !ptr:: eq ( self , other) {
1118
+ if let Some ( parent) = other. parent {
1119
+ other = parent;
1120
+ } else {
1121
+ return false ;
1122
+ }
1123
+ }
1124
+ true
1125
+ }
1116
1126
}
1117
1127
1118
1128
impl < ' a > fmt:: Debug for ModuleData < ' a > {
@@ -1407,6 +1417,7 @@ pub struct Resolver<'a, 'b: 'a> {
1407
1417
block_map : NodeMap < Module < ' a > > ,
1408
1418
module_map : FxHashMap < DefId , Module < ' a > > ,
1409
1419
extern_module_map : FxHashMap < ( DefId , bool /* MacrosOnly? */ ) , Module < ' a > > ,
1420
+ binding_parent_modules : FxHashMap < PtrKey < ' a , NameBinding < ' a > > , Module < ' a > > ,
1410
1421
1411
1422
pub make_glob_map : bool ,
1412
1423
/// Maps imports to the names of items actually imported (this actually maps
@@ -1709,6 +1720,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
1709
1720
module_map,
1710
1721
block_map : NodeMap ( ) ,
1711
1722
extern_module_map : FxHashMap ( ) ,
1723
+ binding_parent_modules : FxHashMap ( ) ,
1712
1724
1713
1725
make_glob_map : make_glob_map == MakeGlobMap :: Yes ,
1714
1726
glob_map : NodeMap ( ) ,
@@ -4526,6 +4538,31 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
4526
4538
vis. is_accessible_from ( module. normal_ancestor_id , self )
4527
4539
}
4528
4540
4541
+ fn set_binding_parent_module ( & mut self , binding : & ' a NameBinding < ' a > , module : Module < ' a > ) {
4542
+ if let Some ( old_module) = self . binding_parent_modules . insert ( PtrKey ( binding) , module) {
4543
+ if !ptr:: eq ( module, old_module) {
4544
+ span_bug ! ( binding. span, "parent module is reset for binding" ) ;
4545
+ }
4546
+ }
4547
+ }
4548
+
4549
+ fn disambiguate_legacy_vs_modern (
4550
+ & self ,
4551
+ legacy : & ' a NameBinding < ' a > ,
4552
+ modern : & ' a NameBinding < ' a > ,
4553
+ ) -> bool {
4554
+ // Some non-controversial subset of ambiguities "modern macro name" vs "macro_rules"
4555
+ // is disambiguated to mitigate regressions from macro modularization.
4556
+ // Scoping for `macro_rules` behaves like scoping for `let` at module level, in general.
4557
+ match ( self . binding_parent_modules . get ( & PtrKey ( legacy) ) ,
4558
+ self . binding_parent_modules . get ( & PtrKey ( modern) ) ) {
4559
+ ( Some ( legacy) , Some ( modern) ) =>
4560
+ legacy. normal_ancestor_id == modern. normal_ancestor_id &&
4561
+ modern. is_ancestor_of ( legacy) ,
4562
+ _ => false ,
4563
+ }
4564
+ }
4565
+
4529
4566
fn report_ambiguity_error ( & self , ident : Ident , b1 : & NameBinding , b2 : & NameBinding ) {
4530
4567
let participle = |is_import : bool | if is_import { "imported" } else { "defined" } ;
4531
4568
let msg1 =
0 commit comments