@@ -50,15 +50,16 @@ crate struct FromPrelude(bool);
50
50
51
51
#[ derive( Clone ) ]
52
52
pub struct InvocationData < ' a > {
53
- crate module : Cell < Module < ' a > > ,
54
53
def_index : DefIndex ,
55
- // Legacy scope in which the macro was invoked.
56
- // The invocation path is resolved in this scope.
54
+ /// Module in which the macro was invoked.
55
+ crate module : Cell < Module < ' a > > ,
56
+ /// Legacy scope in which the macro was invoked.
57
+ /// The invocation path is resolved in this scope.
57
58
crate parent_legacy_scope : Cell < LegacyScope < ' a > > ,
58
- // Legacy scope *produced* by expanding this macro invocation,
59
- // includes all the macro_rules items, other invocations, etc generated by it.
60
- // `Empty` is used if for invocations that has not been expanded yet.
61
- output_legacy_scope : Cell < LegacyScope < ' a > > ,
59
+ /// Legacy scope *produced* by expanding this macro invocation,
60
+ /// includes all the macro_rules items, other invocations, etc generated by it.
61
+ /// Set to the parent scope if the macro is not expanded yet (as if the macro produced nothing) .
62
+ crate output_legacy_scope : Cell < LegacyScope < ' a > > ,
62
63
}
63
64
64
65
impl < ' a > InvocationData < ' a > {
@@ -72,21 +73,32 @@ impl<'a> InvocationData<'a> {
72
73
}
73
74
}
74
75
75
- // Binding produced by a `macro_rules` item.
76
- // Not modularized, can shadow previous legacy bindings, etc.
76
+ /// Binding produced by a `macro_rules` item.
77
+ /// Not modularized, can shadow previous legacy bindings, etc.
77
78
pub struct LegacyBinding < ' a > {
78
79
binding : & ' a NameBinding < ' a > ,
79
- // Legacy scope into which the `macro_rules` item was planted.
80
- parent_legacy_scope : Cell < LegacyScope < ' a > > ,
80
+ /// Legacy scope into which the `macro_rules` item was planted.
81
+ parent_legacy_scope : LegacyScope < ' a > ,
81
82
ident : Ident ,
82
83
}
83
84
85
+ /// Scope introduced by a `macro_rules!` macro.
86
+ /// Starts at the macro's definition and ends at the end of the macro's parent module
87
+ /// (named or unnamed), or even further if it escapes with `#[macro_use]`.
88
+ /// Some macro invocations need to introduce legacy scopes too because they
89
+ /// potentially can expand into macro definitions.
84
90
#[ derive( Copy , Clone ) ]
85
91
pub enum LegacyScope < ' a > {
92
+ /// Created when invocation data is allocated in the arena,
93
+ /// must be replaced with a proper scope later.
94
+ Uninitialized ,
95
+ /// Empty "root" scope at the crate start containing no names.
86
96
Empty ,
87
- Invocation ( & ' a InvocationData < ' a > ) , // The scope of the invocation, not including its expansion
88
- Expansion ( & ' a InvocationData < ' a > ) , // The scope of the invocation, including its expansion
97
+ /// Scope introduced by a `macro_rules!` macro definition.
89
98
Binding ( & ' a LegacyBinding < ' a > ) ,
99
+ /// Scope introduced by a macro invocation that can potentially
100
+ /// create a `macro_rules!` macro definition.
101
+ Invocation ( & ' a InvocationData < ' a > ) ,
90
102
}
91
103
92
104
pub struct ProcMacError {
@@ -181,7 +193,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
181
193
}
182
194
let mut visitor = BuildReducedGraphVisitor {
183
195
resolver : self ,
184
- current_legacy_scope : LegacyScope :: Invocation ( invocation) ,
196
+ current_legacy_scope : invocation. parent_legacy_scope . get ( ) ,
185
197
expansion : mark,
186
198
} ;
187
199
fragment. visit_with ( & mut visitor) ;
@@ -483,8 +495,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
483
495
}
484
496
}
485
497
486
- let legacy_resolution =
487
- self . resolve_legacy_scope ( path[ 0 ] , invoc_id, & invocation. parent_legacy_scope , false ) ;
498
+ let legacy_resolution = self . resolve_legacy_scope (
499
+ path[ 0 ] , invoc_id, invocation. parent_legacy_scope . get ( ) , false
500
+ ) ;
488
501
let result = if let Some ( legacy_binding) = legacy_resolution {
489
502
Ok ( legacy_binding. def ( ) )
490
503
} else {
@@ -788,7 +801,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
788
801
fn resolve_legacy_scope ( & mut self ,
789
802
ident : Ident ,
790
803
invoc_id : Mark ,
791
- invoc_parent_legacy_scope : & ' a Cell < LegacyScope < ' a > > ,
804
+ invoc_parent_legacy_scope : LegacyScope < ' a > ,
792
805
record_used : bool )
793
806
-> Option < & ' a NameBinding < ' a > > {
794
807
let ident = ident. modern ( ) ;
@@ -809,28 +822,18 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
809
822
// Go through all the scopes and try to resolve the name.
810
823
let mut where_to_resolve = invoc_parent_legacy_scope;
811
824
loop {
812
- let result = match where_to_resolve. get ( ) {
825
+ let result = match where_to_resolve {
813
826
LegacyScope :: Binding ( legacy_binding) if ident == legacy_binding. ident =>
814
827
Some ( legacy_binding. binding ) ,
815
828
_ => None ,
816
829
} ;
817
830
818
831
macro_rules! continue_search { ( ) => {
819
- where_to_resolve = match where_to_resolve. get ( ) {
832
+ where_to_resolve = match where_to_resolve {
820
833
LegacyScope :: Empty => break , // nowhere else to search
821
- LegacyScope :: Binding ( binding) => & binding. parent_legacy_scope,
822
- LegacyScope :: Invocation ( invocation) => & invocation. parent_legacy_scope,
823
- LegacyScope :: Expansion ( invocation) => {
824
- match invocation. output_legacy_scope. get( ) {
825
- LegacyScope :: Empty => & invocation. parent_legacy_scope,
826
- LegacyScope :: Binding ( ..) |
827
- LegacyScope :: Expansion ( ..) => & invocation. output_legacy_scope,
828
- LegacyScope :: Invocation ( ..) => {
829
- where_to_resolve. set( invocation. parent_legacy_scope. get( ) ) ;
830
- where_to_resolve
831
- }
832
- }
833
- }
834
+ LegacyScope :: Binding ( binding) => binding. parent_legacy_scope,
835
+ LegacyScope :: Invocation ( invocation) => invocation. output_legacy_scope. get( ) ,
836
+ LegacyScope :: Uninitialized => unreachable!( ) ,
834
837
} ;
835
838
836
839
continue ;
@@ -885,9 +888,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
885
888
886
889
for & ( invoc_id, ident, kind, def) in module. legacy_macro_resolutions . borrow ( ) . iter ( ) {
887
890
let span = ident. span ;
888
- let invoc_parent_legacy_scope = & self . invocations [ & invoc_id] . parent_legacy_scope ;
889
- let legacy_resolution =
890
- self . resolve_legacy_scope ( ident, invoc_id, invoc_parent_legacy_scope, true ) ;
891
+ let invocation = self . invocations [ & invoc_id] ;
892
+ let legacy_resolution = self . resolve_legacy_scope (
893
+ ident, invoc_id, invocation. parent_legacy_scope . get ( ) , true
894
+ ) ;
891
895
let resolution = self . resolve_lexical_macro_path_segment (
892
896
ident, MacroNS , invoc_id, true , true , kind == MacroKind :: Attr , span
893
897
) ;
@@ -1013,8 +1017,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
1013
1017
arenas. alloc_invocation_data ( InvocationData {
1014
1018
def_index : invoc. def_index ,
1015
1019
module : Cell :: new ( graph_root) ,
1016
- parent_legacy_scope : Cell :: new ( LegacyScope :: Empty ) ,
1017
- output_legacy_scope : Cell :: new ( LegacyScope :: Empty ) ,
1020
+ parent_legacy_scope : Cell :: new ( LegacyScope :: Uninitialized ) ,
1021
+ output_legacy_scope : Cell :: new ( LegacyScope :: Uninitialized ) ,
1018
1022
} )
1019
1023
} ) ;
1020
1024
} ;
@@ -1050,7 +1054,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
1050
1054
let vis = ty:: Visibility :: Invisible ; // Doesn't matter for legacy bindings
1051
1055
let binding = ( def, vis, item. span , expansion) . to_name_binding ( self . arenas ) ;
1052
1056
let legacy_binding = self . arenas . alloc_legacy_binding ( LegacyBinding {
1053
- parent_legacy_scope : Cell :: new ( * current_legacy_scope) , binding, ident
1057
+ parent_legacy_scope : * current_legacy_scope, binding, ident
1054
1058
} ) ;
1055
1059
* current_legacy_scope = LegacyScope :: Binding ( legacy_binding) ;
1056
1060
self . all_macros . insert ( ident. name , def) ;
0 commit comments