@@ -45,6 +45,7 @@ use std::mem;
4545use rustc_data_structures:: sync:: Lrc ;
4646use rustc_data_structures:: small_vec:: ExpectOne ;
4747
48+ #[ derive( Clone , Copy ) ]
4849crate struct FromPrelude ( bool ) ;
4950
5051#[ derive( Clone ) ]
@@ -578,15 +579,18 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
578579 assert ! ( force || !record_used) ; // `record_used` implies `force`
579580 ident = ident. modern ( ) ;
580581
581- // Names from inner scope that can't shadow names from outer scopes, e.g.
582- // mod m { ... }
582+ // This is *the* result, resolution from the scope closest to the resolved identifier.
583+ // However, sometimes this result is "weak" because it comes from a glob import or
584+ // a macro expansion, and in this case it cannot shadow names from outer scopes, e.g.
585+ // mod m { ... } // solution in outer scope
583586 // {
584- // use prefix::*; // if this imports another `m`, then it can't shadow the outer `m`
585- // // and we have and ambiguity error
587+ // use prefix::*; // imports another `m` - innermost solution
588+ // // weak, cannot shadow the outer `m`, need to report ambiguity error
586589 // m::mac!();
587590 // }
588- // This includes names from globs and from macro expansions.
589- let mut potentially_ambiguous_result: Option < ( & NameBinding , FromPrelude ) > = None ;
591+ // So we have to save the innermost solution and continue searching in outer scopes
592+ // to detect potential ambiguities.
593+ let mut innermost_result: Option < ( & NameBinding , FromPrelude ) > = None ;
590594
591595 enum WhereToResolve < ' a > {
592596 Module ( Module < ' a > ) ,
@@ -729,32 +733,25 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
729733 return Ok ( result) ;
730734 }
731735
732- // Found a solution that is ambiguous with a previously found solution.
733- // Push an ambiguity error for later reporting and
734- // return something for better recovery.
735- if let Some ( previous_result ) = potentially_ambiguous_result {
736- if result . 0 . def ( ) != previous_result . 0 . def ( ) {
736+ if let Some ( innermost_result ) = innermost_result {
737+ // Found another solution, if the first one was "weak", report an error.
738+ if result . 0 . def ( ) != innermost_result . 0 . def ( ) &&
739+ ( innermost_result . 0 . is_glob_import ( ) ||
740+ innermost_result . 0 . expansion != Mark :: root ( ) ) {
737741 self . ambiguity_errors . push ( AmbiguityError {
738742 span : path_span,
739743 name : ident. name ,
740- b1 : previous_result . 0 ,
744+ b1 : innermost_result . 0 ,
741745 b2 : result. 0 ,
742746 } ) ;
743- return Ok ( previous_result ) ;
747+ return Ok ( innermost_result ) ;
744748 }
749+ } else {
750+ // Found the first solution.
751+ innermost_result = Some ( result) ;
745752 }
746753
747- // Found a solution that's not an ambiguity yet, but is "suspicious" and
748- // can participate in ambiguities later on.
749- // Remember it and go search for other solutions in outer scopes.
750- if result. 0 . is_glob_import ( ) || result. 0 . expansion != Mark :: root ( ) {
751- potentially_ambiguous_result = Some ( result) ;
752-
753- continue_search ! ( ) ;
754- }
755-
756- // Found a solution that can't be ambiguous, great success.
757- return Ok ( result) ;
754+ continue_search ! ( ) ;
758755 } ,
759756 Err ( Determinacy :: Determined ) => {
760757 continue_search ! ( ) ;
@@ -763,9 +760,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
763760 }
764761 }
765762
766- // Previously found potentially ambiguous result turned out to not be ambiguous after all .
767- if let Some ( previous_result ) = potentially_ambiguous_result {
768- return Ok ( previous_result ) ;
763+ // The first found solution was the only one, return it .
764+ if let Some ( innermost_result ) = innermost_result {
765+ return Ok ( innermost_result ) ;
769766 }
770767
771768 let determinacy = Determinacy :: determined ( force) ;
@@ -784,30 +781,31 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
784781 }
785782
786783 fn resolve_legacy_scope ( & mut self ,
787- scope : & ' a Cell < LegacyScope < ' a > > ,
784+ invocation_legacy_scope : & ' a Cell < LegacyScope < ' a > > ,
788785 ident : Ident ,
789786 record_used : bool )
790787 -> Option < & ' a NameBinding < ' a > > {
791788 let ident = ident. modern ( ) ;
792789
793- // Names from inner scope that can't shadow names from outer scopes, e.g.
794- // macro_rules! mac { ... }
790+ // This is *the* result, resolution from the scope closest to the resolved identifier.
791+ // However, sometimes this result is "weak" because it comes from a macro expansion,
792+ // and in this case it cannot shadow names from outer scopes, e.g.
793+ // macro_rules! m { ... } // solution in outer scope
795794 // {
796- // define_mac !(); // if this generates another `macro_rules! mac`, then it can't shadow
797- // // the outer `mac` and we have and ambiguity error
798- // mac !();
795+ // define_m !(); // generates another `macro_rules! m` - innermost solution
796+ // // weak, cannot shadow the outer `m`, need to report ambiguity error
797+ // m !();
799798 // }
800- let mut potentially_ambiguous_result: Option < & NameBinding > = None ;
799+ // So we have to save the innermost solution and continue searching in outer scopes
800+ // to detect potential ambiguities.
801+ let mut innermost_result: Option < & NameBinding > = None ;
801802
802803 // Go through all the scopes and try to resolve the name.
803- let mut where_to_resolve = scope ;
804+ let mut where_to_resolve = invocation_legacy_scope ;
804805 loop {
805806 let result = match where_to_resolve. get ( ) {
806- LegacyScope :: Binding ( legacy_binding) => if ident == legacy_binding. ident {
807- Some ( legacy_binding. binding )
808- } else {
809- None
810- }
807+ LegacyScope :: Binding ( legacy_binding) if ident == legacy_binding. ident =>
808+ Some ( legacy_binding. binding ) ,
811809 _ => None ,
812810 } ;
813811
@@ -836,45 +834,33 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
836834 return Some ( result) ;
837835 }
838836
839- // Found a solution that is ambiguous with a previously found solution.
840- // Push an ambiguity error for later reporting and
841- // return something for better recovery.
842- if let Some ( previous_result) = potentially_ambiguous_result {
843- if result. def ( ) != previous_result. def ( ) {
837+ if let Some ( innermost_result) = innermost_result {
838+ // Found another solution, if the first one was "weak", report an error.
839+ if result. def ( ) != innermost_result. def ( ) &&
840+ innermost_result. expansion != Mark :: root ( ) {
844841 self . ambiguity_errors . push ( AmbiguityError {
845842 span : ident. span ,
846843 name : ident. name ,
847- b1 : previous_result ,
844+ b1 : innermost_result ,
848845 b2 : result,
849846 } ) ;
850- return Some ( previous_result ) ;
847+ return Some ( innermost_result ) ;
851848 }
849+ } else {
850+ // Found the first solution.
851+ innermost_result = Some ( result) ;
852852 }
853853
854- // Found a solution that's not an ambiguity yet, but is "suspicious" and
855- // can participate in ambiguities later on.
856- // Remember it and go search for other solutions in outer scopes.
857- if result. expansion != Mark :: root ( ) {
858- potentially_ambiguous_result = Some ( result) ;
859-
860- continue_search ! ( ) ;
861- }
862-
863- // Found a solution that can't be ambiguous.
864- return Some ( result) ;
854+ continue_search ! ( ) ;
865855 }
866856 None => {
867857 continue_search ! ( ) ;
868858 }
869859 }
870860 }
871861
872- // Previously found potentially ambiguous result turned out to not be ambiguous after all.
873- if let Some ( previous_result) = potentially_ambiguous_result {
874- return Some ( previous_result) ;
875- }
876-
877- None
862+ // The first found solution was the only one (or there was no solution at all), return it.
863+ innermost_result
878864 }
879865
880866 pub fn finalize_current_module_macro_resolutions ( & mut self ) {
0 commit comments