@@ -50,15 +50,16 @@ crate struct FromPrelude(bool);
5050
5151#[ derive( Clone ) ]
5252pub struct InvocationData < ' a > {
53- crate module : Cell < Module < ' a > > ,
5453 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.
5758 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 > > ,
6263}
6364
6465impl < ' a > InvocationData < ' a > {
@@ -72,21 +73,32 @@ impl<'a> InvocationData<'a> {
7273 }
7374}
7475
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.
7778pub struct LegacyBinding < ' a > {
7879 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 > ,
8182 ident : Ident ,
8283}
8384
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.
8490#[ derive( Copy , Clone ) ]
8591pub 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.
8696 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.
8998 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 > ) ,
90102}
91103
92104pub struct ProcMacError {
@@ -181,7 +193,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
181193 }
182194 let mut visitor = BuildReducedGraphVisitor {
183195 resolver : self ,
184- current_legacy_scope : LegacyScope :: Invocation ( invocation) ,
196+ current_legacy_scope : invocation. parent_legacy_scope . get ( ) ,
185197 expansion : mark,
186198 } ;
187199 fragment. visit_with ( & mut visitor) ;
@@ -483,8 +495,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
483495 }
484496 }
485497
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+ ) ;
488501 let result = if let Some ( legacy_binding) = legacy_resolution {
489502 Ok ( legacy_binding. def ( ) )
490503 } else {
@@ -788,7 +801,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
788801 fn resolve_legacy_scope ( & mut self ,
789802 ident : Ident ,
790803 invoc_id : Mark ,
791- invoc_parent_legacy_scope : & ' a Cell < LegacyScope < ' a > > ,
804+ invoc_parent_legacy_scope : LegacyScope < ' a > ,
792805 record_used : bool )
793806 -> Option < & ' a NameBinding < ' a > > {
794807 let ident = ident. modern ( ) ;
@@ -809,28 +822,18 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
809822 // Go through all the scopes and try to resolve the name.
810823 let mut where_to_resolve = invoc_parent_legacy_scope;
811824 loop {
812- let result = match where_to_resolve. get ( ) {
825+ let result = match where_to_resolve {
813826 LegacyScope :: Binding ( legacy_binding) if ident == legacy_binding. ident =>
814827 Some ( legacy_binding. binding ) ,
815828 _ => None ,
816829 } ;
817830
818831 macro_rules! continue_search { ( ) => {
819- where_to_resolve = match where_to_resolve. get ( ) {
832+ where_to_resolve = match where_to_resolve {
820833 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!( ) ,
834837 } ;
835838
836839 continue ;
@@ -885,9 +888,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
885888
886889 for & ( invoc_id, ident, kind, def) in module. legacy_macro_resolutions . borrow ( ) . iter ( ) {
887890 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+ ) ;
891895 let resolution = self . resolve_lexical_macro_path_segment (
892896 ident, MacroNS , invoc_id, true , true , kind == MacroKind :: Attr , span
893897 ) ;
@@ -1013,8 +1017,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
10131017 arenas. alloc_invocation_data ( InvocationData {
10141018 def_index : invoc. def_index ,
10151019 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 ) ,
10181022 } )
10191023 } ) ;
10201024 } ;
@@ -1050,7 +1054,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
10501054 let vis = ty:: Visibility :: Invisible ; // Doesn't matter for legacy bindings
10511055 let binding = ( def, vis, item. span , expansion) . to_name_binding ( self . arenas ) ;
10521056 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
10541058 } ) ;
10551059 * current_legacy_scope = LegacyScope :: Binding ( legacy_binding) ;
10561060 self . all_macros . insert ( ident. name , def) ;
0 commit comments