@@ -1177,9 +1177,7 @@ struct UseError<'a> {
1177
1177
}
1178
1178
1179
1179
struct AmbiguityError < ' a > {
1180
- span : Span ,
1181
- name : Name ,
1182
- lexical : bool ,
1180
+ ident : Ident ,
1183
1181
b1 : & ' a NameBinding < ' a > ,
1184
1182
b2 : & ' a NameBinding < ' a > ,
1185
1183
}
@@ -1283,6 +1281,26 @@ impl<'a> NameBinding<'a> {
1283
1281
fn descr ( & self ) -> & ' static str {
1284
1282
if self . is_extern_crate ( ) { "extern crate" } else { self . def ( ) . kind_name ( ) }
1285
1283
}
1284
+
1285
+ // Suppose that we resolved macro invocation with `invoc_id` to binding `binding` at some
1286
+ // expansion round `max(invoc_id, binding)` when they both emerged from macros.
1287
+ // Then this function returns `true` if `self` may emerge from a macro *after* that
1288
+ // in some later round and screw up our previously found resolution.
1289
+ // See more detailed explanation in
1290
+ // https://github.com/rust-lang/rust/pull/53778#issuecomment-419224049
1291
+ fn may_appear_after ( & self , invoc_id : Mark , binding : & NameBinding ) -> bool {
1292
+ // self > max(invoc_id, binding) => !(self <= invoc_id || self <= binding)
1293
+ // Expansions are partially ordered, so "may appear after" is an inversion of
1294
+ // "certainly appears before or simultaneously" and includes unordered cases.
1295
+ let self_parent_expansion = self . expansion ;
1296
+ let other_parent_expansion = binding. expansion ;
1297
+ let invoc_parent_expansion = invoc_id. parent ( ) ;
1298
+ let certainly_before_other_or_simultaneously =
1299
+ other_parent_expansion. is_descendant_of ( self_parent_expansion) ;
1300
+ let certainly_before_invoc_or_simultaneously =
1301
+ invoc_parent_expansion. is_descendant_of ( self_parent_expansion) ;
1302
+ !( certainly_before_other_or_simultaneously || certainly_before_invoc_or_simultaneously)
1303
+ }
1286
1304
}
1287
1305
1288
1306
/// Interns the names of the primitive types.
@@ -1416,8 +1434,6 @@ pub struct Resolver<'a, 'b: 'a> {
1416
1434
proc_mac_errors : Vec < macros:: ProcMacError > ,
1417
1435
/// crate-local macro expanded `macro_export` referred to by a module-relative path
1418
1436
macro_expanded_macro_export_errors : BTreeSet < ( Span , Span ) > ,
1419
- /// macro-expanded `macro_rules` shadowing existing macros
1420
- disallowed_shadowing : Vec < & ' a LegacyBinding < ' a > > ,
1421
1437
1422
1438
arenas : & ' a ResolverArenas < ' a > ,
1423
1439
dummy_binding : & ' a NameBinding < ' a > ,
@@ -1729,7 +1745,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
1729
1745
ambiguity_errors : Vec :: new ( ) ,
1730
1746
use_injections : Vec :: new ( ) ,
1731
1747
proc_mac_errors : Vec :: new ( ) ,
1732
- disallowed_shadowing : Vec :: new ( ) ,
1733
1748
macro_expanded_macro_export_errors : BTreeSet :: new ( ) ,
1734
1749
1735
1750
arenas,
@@ -1815,7 +1830,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
1815
1830
self . arenas . alloc_module ( module)
1816
1831
}
1817
1832
1818
- fn record_use ( & mut self , ident : Ident , ns : Namespace , binding : & ' a NameBinding < ' a > , span : Span )
1833
+ fn record_use ( & mut self , ident : Ident , ns : Namespace , binding : & ' a NameBinding < ' a > )
1819
1834
-> bool /* true if an error was reported */ {
1820
1835
match binding. kind {
1821
1836
NameBindingKind :: Import { directive, binding, ref used }
@@ -1824,13 +1839,11 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
1824
1839
directive. used . set ( true ) ;
1825
1840
self . used_imports . insert ( ( directive. id , ns) ) ;
1826
1841
self . add_to_glob_map ( directive. id , ident) ;
1827
- self . record_use ( ident, ns, binding, span )
1842
+ self . record_use ( ident, ns, binding)
1828
1843
}
1829
1844
NameBindingKind :: Import { .. } => false ,
1830
1845
NameBindingKind :: Ambiguity { b1, b2 } => {
1831
- self . ambiguity_errors . push ( AmbiguityError {
1832
- span, name : ident. name , lexical : false , b1, b2,
1833
- } ) ;
1846
+ self . ambiguity_errors . push ( AmbiguityError { ident, b1, b2 } ) ;
1834
1847
true
1835
1848
}
1836
1849
_ => false
@@ -2850,7 +2863,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
2850
2863
Def :: Const ( ..) if is_syntactic_ambiguity => {
2851
2864
// Disambiguate in favor of a unit struct/variant
2852
2865
// or constant pattern.
2853
- self . record_use ( ident, ValueNS , binding. unwrap ( ) , ident . span ) ;
2866
+ self . record_use ( ident, ValueNS , binding. unwrap ( ) ) ;
2854
2867
Some ( PathResolution :: new ( def) )
2855
2868
}
2856
2869
Def :: StructCtor ( ..) | Def :: VariantCtor ( ..) |
@@ -3483,6 +3496,20 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
3483
3496
record_used : bool ,
3484
3497
path_span : Span ,
3485
3498
crate_lint : CrateLint ,
3499
+ ) -> PathResult < ' a > {
3500
+ self . resolve_path_with_invoc_id ( base_module, path, opt_ns, Mark :: root ( ) ,
3501
+ record_used, path_span, crate_lint)
3502
+ }
3503
+
3504
+ fn resolve_path_with_invoc_id (
3505
+ & mut self ,
3506
+ base_module : Option < ModuleOrUniformRoot < ' a > > ,
3507
+ path : & [ Ident ] ,
3508
+ opt_ns : Option < Namespace > , // `None` indicates a module path
3509
+ invoc_id : Mark ,
3510
+ record_used : bool ,
3511
+ path_span : Span ,
3512
+ crate_lint : CrateLint ,
3486
3513
) -> PathResult < ' a > {
3487
3514
let mut module = base_module;
3488
3515
let mut allow_super = true ;
@@ -3572,8 +3599,9 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
3572
3599
self . resolve_ident_in_module ( module, ident, ns, record_used, path_span)
3573
3600
} else if opt_ns == Some ( MacroNS ) {
3574
3601
assert ! ( ns == TypeNS ) ;
3575
- self . resolve_lexical_macro_path_segment ( ident, ns, record_used, record_used,
3576
- false , path_span) . map ( |( b, _) | b)
3602
+ self . resolve_lexical_macro_path_segment ( ident, ns, invoc_id, record_used,
3603
+ record_used, false , path_span)
3604
+ . map ( |( binding, _) | binding)
3577
3605
} else {
3578
3606
let record_used_id =
3579
3607
if record_used { crate_lint. node_id ( ) . or ( Some ( CRATE_NODE_ID ) ) } else { None } ;
@@ -4514,35 +4542,33 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
4514
4542
vis. is_accessible_from ( module. normal_ancestor_id , self )
4515
4543
}
4516
4544
4517
- fn report_ambiguity_error (
4518
- & self , name : Name , span : Span , _lexical : bool ,
4519
- def1 : Def , is_import1 : bool , is_glob1 : bool , from_expansion1 : bool , span1 : Span ,
4520
- def2 : Def , is_import2 : bool , _is_glob2 : bool , _from_expansion2 : bool , span2 : Span ,
4521
- ) {
4545
+ fn report_ambiguity_error ( & self , ident : Ident , b1 : & NameBinding , b2 : & NameBinding ) {
4522
4546
let participle = |is_import : bool | if is_import { "imported" } else { "defined" } ;
4523
- let msg1 = format ! ( "`{}` could refer to the name {} here" , name, participle( is_import1) ) ;
4547
+ let msg1 =
4548
+ format ! ( "`{}` could refer to the name {} here" , ident, participle( b1. is_import( ) ) ) ;
4524
4549
let msg2 =
4525
- format ! ( "`{}` could also refer to the name {} here" , name , participle( is_import2 ) ) ;
4526
- let note = if from_expansion1 {
4527
- Some ( if let Def :: Macro ( ..) = def1 {
4550
+ format ! ( "`{}` could also refer to the name {} here" , ident , participle( b2 . is_import ( ) ) ) ;
4551
+ let note = if b1 . expansion != Mark :: root ( ) {
4552
+ Some ( if let Def :: Macro ( ..) = b1 . def ( ) {
4528
4553
format ! ( "macro-expanded {} do not shadow" ,
4529
- if is_import1 { "macro imports" } else { "macros" } )
4554
+ if b1 . is_import ( ) { "macro imports" } else { "macros" } )
4530
4555
} else {
4531
4556
format ! ( "macro-expanded {} do not shadow when used in a macro invocation path" ,
4532
- if is_import1 { "imports" } else { "items" } )
4557
+ if b1 . is_import ( ) { "imports" } else { "items" } )
4533
4558
} )
4534
- } else if is_glob1 {
4535
- Some ( format ! ( "consider adding an explicit import of `{}` to disambiguate" , name ) )
4559
+ } else if b1 . is_glob_import ( ) {
4560
+ Some ( format ! ( "consider adding an explicit import of `{}` to disambiguate" , ident ) )
4536
4561
} else {
4537
4562
None
4538
4563
} ;
4539
4564
4540
- let mut err = struct_span_err ! ( self . session, span, E0659 , "`{}` is ambiguous" , name) ;
4541
- err. span_note ( span1, & msg1) ;
4542
- match def2 {
4543
- Def :: Macro ( ..) if span2. is_dummy ( ) =>
4544
- err. note ( & format ! ( "`{}` is also a builtin macro" , name) ) ,
4545
- _ => err. span_note ( span2, & msg2) ,
4565
+ let mut err = struct_span_err ! ( self . session, ident. span, E0659 , "`{}` is ambiguous" , ident) ;
4566
+ err. span_label ( ident. span , "ambiguous name" ) ;
4567
+ err. span_note ( b1. span , & msg1) ;
4568
+ match b2. def ( ) {
4569
+ Def :: Macro ( ..) if b2. span . is_dummy ( ) =>
4570
+ err. note ( & format ! ( "`{}` is also a builtin macro" , ident) ) ,
4571
+ _ => err. span_note ( b2. span , & msg2) ,
4546
4572
} ;
4547
4573
if let Some ( note) = note {
4548
4574
err. note ( & note) ;
@@ -4551,7 +4577,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
4551
4577
}
4552
4578
4553
4579
fn report_errors ( & mut self , krate : & Crate ) {
4554
- self . report_shadowing_errors ( ) ;
4555
4580
self . report_with_use_injections ( krate) ;
4556
4581
self . report_proc_macro_import ( krate) ;
4557
4582
let mut reported_spans = FxHashSet ( ) ;
@@ -4567,15 +4592,9 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
4567
4592
) ;
4568
4593
}
4569
4594
4570
- for & AmbiguityError { span, name, b1, b2, lexical } in & self . ambiguity_errors {
4571
- if reported_spans. insert ( span) {
4572
- self . report_ambiguity_error (
4573
- name, span, lexical,
4574
- b1. def ( ) , b1. is_import ( ) , b1. is_glob_import ( ) ,
4575
- b1. expansion != Mark :: root ( ) , b1. span ,
4576
- b2. def ( ) , b2. is_import ( ) , b2. is_glob_import ( ) ,
4577
- b2. expansion != Mark :: root ( ) , b2. span ,
4578
- ) ;
4595
+ for & AmbiguityError { ident, b1, b2 } in & self . ambiguity_errors {
4596
+ if reported_spans. insert ( ident. span ) {
4597
+ self . report_ambiguity_error ( ident, b1, b2) ;
4579
4598
}
4580
4599
}
4581
4600
@@ -4595,20 +4614,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
4595
4614
}
4596
4615
}
4597
4616
4598
- fn report_shadowing_errors ( & mut self ) {
4599
- let mut reported_errors = FxHashSet ( ) ;
4600
- for binding in replace ( & mut self . disallowed_shadowing , Vec :: new ( ) ) {
4601
- if self . resolve_legacy_scope ( & binding. parent , binding. ident , false ) . is_some ( ) &&
4602
- reported_errors. insert ( ( binding. ident , binding. span ) ) {
4603
- let msg = format ! ( "`{}` is already in scope" , binding. ident) ;
4604
- self . session . struct_span_err ( binding. span , & msg)
4605
- . note ( "macro-expanded `macro_rules!`s may not shadow \
4606
- existing macros (see RFC 1560)")
4607
- . emit ( ) ;
4608
- }
4609
- }
4610
- }
4611
-
4612
4617
fn report_conflict < ' b > ( & mut self ,
4613
4618
parent : Module ,
4614
4619
ident : Ident ,
0 commit comments