@@ -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 ) ]
@@ -578,15 +579,18 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
578
579
assert ! ( force || !record_used) ; // `record_used` implies `force`
579
580
ident = ident. modern ( ) ;
580
581
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
583
586
// {
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
586
589
// m::mac!();
587
590
// }
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 ;
590
594
591
595
enum WhereToResolve < ' a > {
592
596
Module ( Module < ' a > ) ,
@@ -729,32 +733,25 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
729
733
return Ok ( result) ;
730
734
}
731
735
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 ( ) ) {
737
741
self . ambiguity_errors . push ( AmbiguityError {
738
742
span : path_span,
739
743
name : ident. name ,
740
- b1 : previous_result . 0 ,
744
+ b1 : innermost_result . 0 ,
741
745
b2 : result. 0 ,
742
746
} ) ;
743
- return Ok ( previous_result ) ;
747
+ return Ok ( innermost_result ) ;
744
748
}
749
+ } else {
750
+ // Found the first solution.
751
+ innermost_result = Some ( result) ;
745
752
}
746
753
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 ! ( ) ;
758
755
} ,
759
756
Err ( Determinacy :: Determined ) => {
760
757
continue_search ! ( ) ;
@@ -763,9 +760,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
763
760
}
764
761
}
765
762
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 ) ;
769
766
}
770
767
771
768
let determinacy = Determinacy :: determined ( force) ;
@@ -784,30 +781,31 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
784
781
}
785
782
786
783
fn resolve_legacy_scope ( & mut self ,
787
- scope : & ' a Cell < LegacyScope < ' a > > ,
784
+ invocation_legacy_scope : & ' a Cell < LegacyScope < ' a > > ,
788
785
ident : Ident ,
789
786
record_used : bool )
790
787
-> Option < & ' a NameBinding < ' a > > {
791
788
let ident = ident. modern ( ) ;
792
789
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
795
794
// {
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 !();
799
798
// }
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 ;
801
802
802
803
// 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 ;
804
805
loop {
805
806
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 ) ,
811
809
_ => None ,
812
810
} ;
813
811
@@ -836,45 +834,33 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
836
834
return Some ( result) ;
837
835
}
838
836
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 ( ) {
844
841
self . ambiguity_errors . push ( AmbiguityError {
845
842
span : ident. span ,
846
843
name : ident. name ,
847
- b1 : previous_result ,
844
+ b1 : innermost_result ,
848
845
b2 : result,
849
846
} ) ;
850
- return Some ( previous_result ) ;
847
+ return Some ( innermost_result ) ;
851
848
}
849
+ } else {
850
+ // Found the first solution.
851
+ innermost_result = Some ( result) ;
852
852
}
853
853
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 ! ( ) ;
865
855
}
866
856
None => {
867
857
continue_search ! ( ) ;
868
858
}
869
859
}
870
860
}
871
861
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
878
864
}
879
865
880
866
pub fn finalize_current_module_macro_resolutions ( & mut self ) {
0 commit comments