@@ -1177,9 +1177,7 @@ struct UseError<'a> {
11771177}
11781178
11791179struct AmbiguityError < ' a > {
1180- span : Span ,
1181- name : Name ,
1182- lexical : bool ,
1180+ ident : Ident ,
11831181 b1 : & ' a NameBinding < ' a > ,
11841182 b2 : & ' a NameBinding < ' a > ,
11851183}
@@ -1283,6 +1281,26 @@ impl<'a> NameBinding<'a> {
12831281 fn descr ( & self ) -> & ' static str {
12841282 if self . is_extern_crate ( ) { "extern crate" } else { self . def ( ) . kind_name ( ) }
12851283 }
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+ }
12861304}
12871305
12881306/// Interns the names of the primitive types.
@@ -1416,8 +1434,6 @@ pub struct Resolver<'a, 'b: 'a> {
14161434 proc_mac_errors : Vec < macros:: ProcMacError > ,
14171435 /// crate-local macro expanded `macro_export` referred to by a module-relative path
14181436 macro_expanded_macro_export_errors : BTreeSet < ( Span , Span ) > ,
1419- /// macro-expanded `macro_rules` shadowing existing macros
1420- disallowed_shadowing : Vec < & ' a LegacyBinding < ' a > > ,
14211437
14221438 arenas : & ' a ResolverArenas < ' a > ,
14231439 dummy_binding : & ' a NameBinding < ' a > ,
@@ -1729,7 +1745,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
17291745 ambiguity_errors : Vec :: new ( ) ,
17301746 use_injections : Vec :: new ( ) ,
17311747 proc_mac_errors : Vec :: new ( ) ,
1732- disallowed_shadowing : Vec :: new ( ) ,
17331748 macro_expanded_macro_export_errors : BTreeSet :: new ( ) ,
17341749
17351750 arenas,
@@ -1815,7 +1830,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
18151830 self . arenas . alloc_module ( module)
18161831 }
18171832
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 > )
18191834 -> bool /* true if an error was reported */ {
18201835 match binding. kind {
18211836 NameBindingKind :: Import { directive, binding, ref used }
@@ -1824,13 +1839,11 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
18241839 directive. used . set ( true ) ;
18251840 self . used_imports . insert ( ( directive. id , ns) ) ;
18261841 self . add_to_glob_map ( directive. id , ident) ;
1827- self . record_use ( ident, ns, binding, span )
1842+ self . record_use ( ident, ns, binding)
18281843 }
18291844 NameBindingKind :: Import { .. } => false ,
18301845 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 } ) ;
18341847 true
18351848 }
18361849 _ => false
@@ -2850,7 +2863,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
28502863 Def :: Const ( ..) if is_syntactic_ambiguity => {
28512864 // Disambiguate in favor of a unit struct/variant
28522865 // or constant pattern.
2853- self . record_use ( ident, ValueNS , binding. unwrap ( ) , ident . span ) ;
2866+ self . record_use ( ident, ValueNS , binding. unwrap ( ) ) ;
28542867 Some ( PathResolution :: new ( def) )
28552868 }
28562869 Def :: StructCtor ( ..) | Def :: VariantCtor ( ..) |
@@ -3483,6 +3496,20 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
34833496 record_used : bool ,
34843497 path_span : Span ,
34853498 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 ,
34863513 ) -> PathResult < ' a > {
34873514 let mut module = base_module;
34883515 let mut allow_super = true ;
@@ -3572,8 +3599,9 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
35723599 self . resolve_ident_in_module ( module, ident, ns, record_used, path_span)
35733600 } else if opt_ns == Some ( MacroNS ) {
35743601 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)
35773605 } else {
35783606 let record_used_id =
35793607 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> {
45144542 vis. is_accessible_from ( module. normal_ancestor_id , self )
45154543 }
45164544
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 ) {
45224546 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( ) ) ) ;
45244549 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 ( ) {
45284553 format ! ( "macro-expanded {} do not shadow" ,
4529- if is_import1 { "macro imports" } else { "macros" } )
4554+ if b1 . is_import ( ) { "macro imports" } else { "macros" } )
45304555 } else {
45314556 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" } )
45334558 } )
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 ) )
45364561 } else {
45374562 None
45384563 } ;
45394564
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) ,
45464572 } ;
45474573 if let Some ( note) = note {
45484574 err. note ( & note) ;
@@ -4551,7 +4577,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
45514577 }
45524578
45534579 fn report_errors ( & mut self , krate : & Crate ) {
4554- self . report_shadowing_errors ( ) ;
45554580 self . report_with_use_injections ( krate) ;
45564581 self . report_proc_macro_import ( krate) ;
45574582 let mut reported_spans = FxHashSet ( ) ;
@@ -4567,15 +4592,9 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
45674592 ) ;
45684593 }
45694594
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) ;
45794598 }
45804599 }
45814600
@@ -4595,20 +4614,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
45954614 }
45964615 }
45974616
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-
46124617 fn report_conflict < ' b > ( & mut self ,
46134618 parent : Module ,
46144619 ident : Ident ,
0 commit comments