@@ -45,6 +45,7 @@ use std::mem;
45
45
use rustc_data_structures:: sync:: Lrc ;
46
46
use rustc_data_structures:: small_vec:: ExpectOne ;
47
47
48
+ #[ derive( Clone , Copy ) ]
48
49
crate struct FromPrelude ( bool ) ;
49
50
50
51
#[ derive( Clone ) ]
@@ -555,15 +556,18 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
555
556
assert ! ( force || !record_used) ; // `record_used` implies `force`
556
557
ident = ident. modern ( ) ;
557
558
558
- // Names from inner scope that can't shadow names from outer scopes, e.g.
559
- // mod m { ... }
559
+ // This is *the* result, resolution from the scope closest to the resolved identifier.
560
+ // However, sometimes this result is "weak" because it comes from a glob import or
561
+ // a macro expansion, and in this case it cannot shadow names from outer scopes, e.g.
562
+ // mod m { ... } // solution in outer scope
560
563
// {
561
- // use prefix::*; // if this imports another `m`, then it can't shadow the outer `m`
562
- // // and we have and ambiguity error
564
+ // use prefix::*; // imports another `m` - innermost solution
565
+ // // weak, cannot shadow the outer `m`, need to report ambiguity error
563
566
// m::mac!();
564
567
// }
565
- // This includes names from globs and from macro expansions.
566
- let mut potentially_ambiguous_result: Option < ( & NameBinding , FromPrelude ) > = None ;
568
+ // So we have to save the innermost solution and continue searching in outer scopes
569
+ // to detect potential ambiguities.
570
+ let mut innermost_result: Option < ( & NameBinding , FromPrelude ) > = None ;
567
571
568
572
enum WhereToResolve < ' a > {
569
573
Module ( Module < ' a > ) ,
@@ -706,32 +710,25 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
706
710
return Ok ( result) ;
707
711
}
708
712
709
- // Found a solution that is ambiguous with a previously found solution.
710
- // Push an ambiguity error for later reporting and
711
- // return something for better recovery.
712
- if let Some ( previous_result ) = potentially_ambiguous_result {
713
- if result . 0 . def ( ) != previous_result . 0 . def ( ) {
713
+ if let Some ( innermost_result ) = innermost_result {
714
+ // Found another solution, if the first one was "weak", report an error.
715
+ if result . 0 . def ( ) != innermost_result . 0 . def ( ) &&
716
+ ( innermost_result . 0 . is_glob_import ( ) ||
717
+ innermost_result . 0 . expansion != Mark :: root ( ) ) {
714
718
self . ambiguity_errors . push ( AmbiguityError {
715
719
span : path_span,
716
720
name : ident. name ,
717
- b1 : previous_result . 0 ,
721
+ b1 : innermost_result . 0 ,
718
722
b2 : result. 0 ,
719
723
} ) ;
720
- return Ok ( previous_result ) ;
724
+ return Ok ( innermost_result ) ;
721
725
}
726
+ } else {
727
+ // Found the first solution.
728
+ innermost_result = Some ( result) ;
722
729
}
723
730
724
- // Found a solution that's not an ambiguity yet, but is "suspicious" and
725
- // can participate in ambiguities later on.
726
- // Remember it and go search for other solutions in outer scopes.
727
- if result. 0 . is_glob_import ( ) || result. 0 . expansion != Mark :: root ( ) {
728
- potentially_ambiguous_result = Some ( result) ;
729
-
730
- continue_search ! ( ) ;
731
- }
732
-
733
- // Found a solution that can't be ambiguous, great success.
734
- return Ok ( result) ;
731
+ continue_search ! ( ) ;
735
732
} ,
736
733
Err ( Determinacy :: Determined ) => {
737
734
continue_search ! ( ) ;
@@ -740,9 +737,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
740
737
}
741
738
}
742
739
743
- // Previously found potentially ambiguous result turned out to not be ambiguous after all .
744
- if let Some ( previous_result ) = potentially_ambiguous_result {
745
- return Ok ( previous_result ) ;
740
+ // The first found solution was the only one, return it .
741
+ if let Some ( innermost_result ) = innermost_result {
742
+ return Ok ( innermost_result ) ;
746
743
}
747
744
748
745
let determinacy = Determinacy :: determined ( force) ;
@@ -761,30 +758,31 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
761
758
}
762
759
763
760
fn resolve_legacy_scope ( & mut self ,
764
- scope : & ' a Cell < LegacyScope < ' a > > ,
761
+ invocation_legacy_scope : & ' a Cell < LegacyScope < ' a > > ,
765
762
ident : Ident ,
766
763
record_used : bool )
767
764
-> Option < & ' a NameBinding < ' a > > {
768
765
let ident = ident. modern ( ) ;
769
766
770
- // Names from inner scope that can't shadow names from outer scopes, e.g.
771
- // macro_rules! mac { ... }
767
+ // This is *the* result, resolution from the scope closest to the resolved identifier.
768
+ // However, sometimes this result is "weak" because it comes from a macro expansion,
769
+ // and in this case it cannot shadow names from outer scopes, e.g.
770
+ // macro_rules! m { ... } // solution in outer scope
772
771
// {
773
- // define_mac !(); // if this generates another `macro_rules! mac`, then it can't shadow
774
- // // the outer `mac` and we have and ambiguity error
775
- // mac !();
772
+ // define_m !(); // generates another `macro_rules! m` - innermost solution
773
+ // // weak, cannot shadow the outer `m`, need to report ambiguity error
774
+ // m !();
776
775
// }
777
- let mut potentially_ambiguous_result: Option < & NameBinding > = None ;
776
+ // So we have to save the innermost solution and continue searching in outer scopes
777
+ // to detect potential ambiguities.
778
+ let mut innermost_result: Option < & NameBinding > = None ;
778
779
779
780
// Go through all the scopes and try to resolve the name.
780
- let mut where_to_resolve = scope ;
781
+ let mut where_to_resolve = invocation_legacy_scope ;
781
782
loop {
782
783
let result = match where_to_resolve. get ( ) {
783
- LegacyScope :: Binding ( legacy_binding) => if ident == legacy_binding. ident {
784
- Some ( legacy_binding. binding )
785
- } else {
786
- None
787
- }
784
+ LegacyScope :: Binding ( legacy_binding) if ident == legacy_binding. ident =>
785
+ Some ( legacy_binding. binding ) ,
788
786
_ => None ,
789
787
} ;
790
788
@@ -813,45 +811,33 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
813
811
return Some ( result) ;
814
812
}
815
813
816
- // Found a solution that is ambiguous with a previously found solution.
817
- // Push an ambiguity error for later reporting and
818
- // return something for better recovery.
819
- if let Some ( previous_result) = potentially_ambiguous_result {
820
- if result. def ( ) != previous_result. def ( ) {
814
+ if let Some ( innermost_result) = innermost_result {
815
+ // Found another solution, if the first one was "weak", report an error.
816
+ if result. def ( ) != innermost_result. def ( ) &&
817
+ innermost_result. expansion != Mark :: root ( ) {
821
818
self . ambiguity_errors . push ( AmbiguityError {
822
819
span : ident. span ,
823
820
name : ident. name ,
824
- b1 : previous_result ,
821
+ b1 : innermost_result ,
825
822
b2 : result,
826
823
} ) ;
827
- return Some ( previous_result ) ;
824
+ return Some ( innermost_result ) ;
828
825
}
826
+ } else {
827
+ // Found the first solution.
828
+ innermost_result = Some ( result) ;
829
829
}
830
830
831
- // Found a solution that's not an ambiguity yet, but is "suspicious" and
832
- // can participate in ambiguities later on.
833
- // Remember it and go search for other solutions in outer scopes.
834
- if result. expansion != Mark :: root ( ) {
835
- potentially_ambiguous_result = Some ( result) ;
836
-
837
- continue_search ! ( ) ;
838
- }
839
-
840
- // Found a solution that can't be ambiguous.
841
- return Some ( result) ;
831
+ continue_search ! ( ) ;
842
832
}
843
833
None => {
844
834
continue_search ! ( ) ;
845
835
}
846
836
}
847
837
}
848
838
849
- // Previously found potentially ambiguous result turned out to not be ambiguous after all.
850
- if let Some ( previous_result) = potentially_ambiguous_result {
851
- return Some ( previous_result) ;
852
- }
853
-
854
- None
839
+ // The first found solution was the only one (or there was no solution at all), return it.
840
+ innermost_result
855
841
}
856
842
857
843
pub fn finalize_current_module_macro_resolutions ( & mut self ) {
0 commit comments