@@ -81,9 +81,9 @@ pub enum LegacyScope<'a> {
81
81
// Binding produced by a `macro_rules` item.
82
82
// Not modularized, can shadow previous legacy bindings, etc.
83
83
pub struct LegacyBinding < ' a > {
84
- pub binding : & ' a NameBinding < ' a > ,
85
- pub parent : Cell < LegacyScope < ' a > > ,
86
- pub ident : Ident ,
84
+ binding : & ' a NameBinding < ' a > ,
85
+ parent : Cell < LegacyScope < ' a > > ,
86
+ ident : Ident ,
87
87
}
88
88
89
89
pub struct ProcMacError {
@@ -784,42 +784,101 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
784
784
}
785
785
}
786
786
787
- crate fn resolve_legacy_scope ( & mut self ,
788
- mut scope : & ' a Cell < LegacyScope < ' a > > ,
789
- ident : Ident ,
790
- record_used : bool )
791
- -> Option < ( & ' a NameBinding < ' a > , FromExpansion ) > {
787
+ fn resolve_legacy_scope ( & mut self ,
788
+ scope : & ' a Cell < LegacyScope < ' a > > ,
789
+ ident : Ident ,
790
+ record_used : bool )
791
+ -> Option < ( & ' a NameBinding < ' a > , FromExpansion ) > {
792
792
let ident = ident. modern ( ) ;
793
- let mut relative_depth: u32 = 0 ;
793
+
794
+ // Names from inner scope that can't shadow names from outer scopes, e.g.
795
+ // macro_rules! mac { ... }
796
+ // {
797
+ // define_mac!(); // if this generates another `macro_rules! mac`, then it can't shadow
798
+ // // the outer `mac` and we have and ambiguity error
799
+ // mac!();
800
+ // }
801
+ let mut potentially_ambiguous_result: Option < ( & NameBinding , FromExpansion ) > = None ;
802
+
803
+ // Go through all the scopes and try to resolve the name.
804
+ let mut where_to_resolve = scope;
805
+ let mut relative_depth = 0u32 ;
794
806
loop {
795
- match scope. get ( ) {
796
- LegacyScope :: Empty => break ,
797
- LegacyScope :: Expansion ( invocation) => {
798
- match invocation. expansion . get ( ) {
799
- LegacyScope :: Invocation ( _) => scope. set ( invocation. legacy_scope . get ( ) ) ,
800
- LegacyScope :: Empty => {
801
- scope = & invocation. legacy_scope ;
802
- }
803
- _ => {
807
+ let result = match where_to_resolve. get ( ) {
808
+ LegacyScope :: Binding ( legacy_binding) => if ident == legacy_binding. ident {
809
+ Some ( ( legacy_binding. binding , FromExpansion ( relative_depth > 0 ) ) )
810
+ } else {
811
+ None
812
+ }
813
+ _ => None ,
814
+ } ;
815
+
816
+ macro_rules! continue_search { ( ) => {
817
+ where_to_resolve = match where_to_resolve. get( ) {
818
+ LegacyScope :: Binding ( binding) => & binding. parent,
819
+ LegacyScope :: Invocation ( invocation) => {
820
+ relative_depth = relative_depth. saturating_sub( 1 ) ;
821
+ & invocation. legacy_scope
822
+ }
823
+ LegacyScope :: Expansion ( invocation) => match invocation. expansion. get( ) {
824
+ LegacyScope :: Empty => & invocation. legacy_scope,
825
+ LegacyScope :: Binding ( ..) | LegacyScope :: Expansion ( ..) => {
804
826
relative_depth += 1 ;
805
- scope = & invocation. expansion ;
827
+ & invocation. expansion
828
+ }
829
+ LegacyScope :: Invocation ( ..) => {
830
+ where_to_resolve. set( invocation. legacy_scope. get( ) ) ;
831
+ where_to_resolve
806
832
}
807
833
}
808
- }
809
- LegacyScope :: Invocation ( invocation) => {
810
- relative_depth = relative_depth. saturating_sub ( 1 ) ;
811
- scope = & invocation. legacy_scope ;
812
- }
813
- LegacyScope :: Binding ( potential_binding) => {
814
- if potential_binding. ident == ident {
815
- if record_used && relative_depth > 0 {
816
- self . disallowed_shadowing . push ( potential_binding) ;
834
+ LegacyScope :: Empty => break , // nowhere else to search
835
+ } ;
836
+
837
+ continue ;
838
+ } }
839
+
840
+ match result {
841
+ Some ( result) => {
842
+ if !record_used {
843
+ return Some ( result) ;
844
+ }
845
+
846
+ // Found a solution that is ambiguous with a previously found solution.
847
+ // Push an ambiguity error for later reporting and
848
+ // return something for better recovery.
849
+ if let Some ( previous_result) = potentially_ambiguous_result {
850
+ if result. 0 . def ( ) != previous_result. 0 . def ( ) {
851
+ self . ambiguity_errors . push ( AmbiguityError {
852
+ span : ident. span ,
853
+ name : ident. name ,
854
+ b1 : previous_result. 0 ,
855
+ b2 : result. 0 ,
856
+ } ) ;
857
+ return Some ( previous_result) ;
817
858
}
818
- return Some ( ( potential_binding. binding , FromExpansion ( relative_depth > 0 ) ) ) ;
819
859
}
820
- scope = & potential_binding. parent ;
860
+
861
+ // Found a solution that's not an ambiguity yet, but is "suspicious" and
862
+ // can participate in ambiguities later on.
863
+ // Remember it and go search for other solutions in outer scopes.
864
+ if ( result. 1 ) . 0 {
865
+ potentially_ambiguous_result = Some ( result) ;
866
+
867
+ continue_search ! ( ) ;
868
+ }
869
+
870
+ // Found a solution that can't be ambiguous.
871
+ return Some ( result) ;
821
872
}
822
- } ;
873
+ None => {
874
+ continue_search ! ( ) ;
875
+ }
876
+ }
877
+ }
878
+
879
+ // Previously found potentially ambiguous result turned out to not be ambiguous after all.
880
+ if let Some ( previous_result) = potentially_ambiguous_result {
881
+ return Some ( previous_result) ;
823
882
}
824
883
825
884
None
@@ -846,8 +905,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
846
905
847
906
let check_consistency = |this : & Self , new_def : Def | {
848
907
if let Some ( def) = def {
849
- if this. ambiguity_errors . is_empty ( ) && this. disallowed_shadowing . is_empty ( ) &&
850
- new_def != def && new_def != Def :: Err {
908
+ if this. ambiguity_errors . is_empty ( ) && new_def != def && new_def != Def :: Err {
851
909
// Make sure compilation does not succeed if preferred macro resolution
852
910
// has changed after the macro had been expanded. In theory all such
853
911
// situations should be reported as ambiguity errors, so this is span-bug.
0 commit comments