1
1
use crate :: { AmbiguityError , AmbiguityKind , AmbiguityErrorMisc , Determinacy } ;
2
2
use crate :: { CrateLint , Resolver , ResolutionError , Scope , ScopeSet , ParentScope , Weak } ;
3
- use crate :: { Module , ModuleKind , NameBinding , PathResult , Segment , ToNameBinding } ;
3
+ use crate :: { ModuleKind , NameBinding , PathResult , Segment , ToNameBinding } ;
4
4
use crate :: { ModuleOrUniformRoot , KNOWN_TOOLS } ;
5
5
use crate :: Namespace :: * ;
6
6
use crate :: build_reduced_graph:: BuildReducedGraphVisitor ;
@@ -22,36 +22,11 @@ use syntax::feature_gate::GateIssue;
22
22
use syntax:: symbol:: { Symbol , kw, sym} ;
23
23
use syntax_pos:: { Span , DUMMY_SP } ;
24
24
25
- use std:: cell:: Cell ;
26
25
use std:: { mem, ptr} ;
27
26
use rustc_data_structures:: sync:: Lrc ;
28
27
29
28
type Res = def:: Res < ast:: NodeId > ;
30
29
31
- // FIXME: Merge this with `ParentScope`.
32
- #[ derive( Clone , Debug ) ]
33
- pub struct InvocationData < ' a > {
34
- /// The module in which the macro was invoked.
35
- crate module : Module < ' a > ,
36
- /// The legacy scope in which the macro was invoked.
37
- /// The invocation path is resolved in this scope.
38
- crate parent_legacy_scope : LegacyScope < ' a > ,
39
- /// The legacy scope *produced* by expanding this macro invocation,
40
- /// includes all the macro_rules items, other invocations, etc generated by it.
41
- /// `None` if the macro is not expanded yet.
42
- crate output_legacy_scope : Cell < Option < LegacyScope < ' a > > > ,
43
- }
44
-
45
- impl < ' a > InvocationData < ' a > {
46
- pub fn default ( module : Module < ' a > ) -> Self {
47
- InvocationData {
48
- module,
49
- parent_legacy_scope : LegacyScope :: Empty ,
50
- output_legacy_scope : Cell :: new ( None ) ,
51
- }
52
- }
53
- }
54
-
55
30
/// Binding produced by a `macro_rules` item.
56
31
/// Not modularized, can shadow previous legacy bindings, etc.
57
32
#[ derive( Debug ) ]
@@ -75,7 +50,7 @@ pub enum LegacyScope<'a> {
75
50
Binding ( & ' a LegacyBinding < ' a > ) ,
76
51
/// The scope introduced by a macro invocation that can potentially
77
52
/// create a `macro_rules!` macro definition.
78
- Invocation ( & ' a InvocationData < ' a > ) ,
53
+ Invocation ( ExpnId ) ,
79
54
}
80
55
81
56
// Macro namespace is separated into two sub-namespaces, one for bang macros and
@@ -124,9 +99,8 @@ impl<'a> base::Resolver for Resolver<'a> {
124
99
ExpnKind :: Macro ( MacroKind :: Attr , sym:: test_case) , DUMMY_SP , self . session . edition ( )
125
100
) ) ) ;
126
101
let module = self . module_map [ & self . definitions . local_def_id ( id) ] ;
127
- let invocation_data = self . arenas . alloc_invocation_data ( InvocationData :: default ( module) ) ;
102
+ self . invocation_parent_scopes . insert ( expn_id , ParentScope :: default ( module) ) ;
128
103
self . definitions . set_invocation_parent ( expn_id, module. def_id ( ) . unwrap ( ) . index ) ;
129
- self . invocations . insert ( expn_id, invocation_data) ;
130
104
expn_id
131
105
}
132
106
@@ -140,29 +114,29 @@ impl<'a> base::Resolver for Resolver<'a> {
140
114
} ) ;
141
115
}
142
116
143
- fn visit_ast_fragment_with_placeholders ( & mut self , expn_id : ExpnId , fragment : & AstFragment ,
144
- derives : & [ ExpnId ] ) {
145
- fragment. visit_with ( & mut DefCollector :: new ( & mut self . definitions , expn_id) ) ;
146
-
147
- let invocation = self . invocations [ & expn_id] ;
148
- invocation. module . unresolved_invocations . borrow_mut ( ) . remove ( & expn_id) ;
149
- invocation. module . unresolved_invocations . borrow_mut ( ) . extend ( derives) ;
150
- let parent_def = self . definitions . invocation_parent ( expn_id) ;
117
+ fn visit_ast_fragment_with_placeholders (
118
+ & mut self , expansion : ExpnId , fragment : & AstFragment , derives : & [ ExpnId ]
119
+ ) {
120
+ // Fill in some data for derives if the fragment is from a derive container.
121
+ let parent_scope = self . invocation_parent_scopes [ & expansion] . clone ( ) ;
122
+ let parent_def = self . definitions . invocation_parent ( expansion) ;
123
+ self . invocation_parent_scopes . extend (
124
+ derives. iter ( ) . map ( |& derive| ( derive, parent_scope. clone ( ) ) )
125
+ ) ;
151
126
for & derive_invoc_id in derives {
152
127
self . definitions . set_invocation_parent ( derive_invoc_id, parent_def) ;
153
128
}
154
- self . invocations . extend ( derives. iter ( ) . map ( |& derive| ( derive, invocation) ) ) ;
155
- let mut visitor = BuildReducedGraphVisitor {
156
- r : self ,
157
- parent_scope : ParentScope {
158
- module : invocation. module ,
159
- expansion : expn_id,
160
- legacy : invocation. parent_legacy_scope ,
161
- derives : Vec :: new ( ) ,
162
- } ,
163
- } ;
129
+ parent_scope. module . unresolved_invocations . borrow_mut ( ) . remove ( & expansion) ;
130
+ parent_scope. module . unresolved_invocations . borrow_mut ( ) . extend ( derives) ;
131
+
132
+ // Integrate the new AST fragment into all the definition and module structures.
133
+ // We are inside the `expansion` new, but other parent scope components are still the same.
134
+ fragment. visit_with ( & mut DefCollector :: new ( & mut self . definitions , expansion) ) ;
135
+ let parent_scope = ParentScope { expansion, ..parent_scope } ;
136
+ let mut visitor = BuildReducedGraphVisitor { r : self , parent_scope } ;
164
137
fragment. visit_with ( & mut visitor) ;
165
- invocation. output_legacy_scope . set ( Some ( visitor. parent_scope . legacy ) ) ;
138
+ let output_legacy_scope = visitor. parent_scope . legacy ;
139
+ self . output_legacy_scopes . insert ( expansion, output_legacy_scope) ;
166
140
}
167
141
168
142
fn register_builtin_macro ( & mut self , ident : ast:: Ident , ext : SyntaxExtension ) {
@@ -178,7 +152,8 @@ impl<'a> base::Resolver for Resolver<'a> {
178
152
179
153
fn resolve_macro_invocation ( & mut self , invoc : & Invocation , invoc_id : ExpnId , force : bool )
180
154
-> Result < Option < Lrc < SyntaxExtension > > , Indeterminate > {
181
- let ( path, kind, derives_in_scope, after_derive) = match invoc. kind {
155
+ let parent_scope = & self . invocation_parent_scopes [ & invoc_id] . clone ( ) ;
156
+ let ( path, kind, derives, after_derive) = match invoc. kind {
182
157
InvocationKind :: Attr { ref attr, ref derives, after_derive, .. } =>
183
158
( & attr. path , MacroKind :: Attr , derives. clone ( ) , after_derive) ,
184
159
InvocationKind :: Bang { ref mac, .. } =>
@@ -192,7 +167,6 @@ impl<'a> base::Resolver for Resolver<'a> {
192
167
// will automatically knows about itself.
193
168
let mut result = Ok ( None ) ;
194
169
if derives. len ( ) > 1 {
195
- let parent_scope = & self . invoc_parent_scope ( invoc_id, Vec :: new ( ) ) ;
196
170
for path in derives {
197
171
match self . resolve_macro_path ( path, Some ( MacroKind :: Derive ) ,
198
172
parent_scope, true , force) {
@@ -209,7 +183,8 @@ impl<'a> base::Resolver for Resolver<'a> {
209
183
}
210
184
} ;
211
185
212
- let parent_scope = & self . invoc_parent_scope ( invoc_id, derives_in_scope) ;
186
+ // Derives are not included when `invocations` are collected, so we have to add them here.
187
+ let parent_scope = & ParentScope { derives, ..parent_scope. clone ( ) } ;
213
188
let ( ext, res) = self . smart_resolve_macro_path ( path, kind, parent_scope, force) ?;
214
189
215
190
let span = invoc. span ( ) ;
@@ -247,16 +222,6 @@ impl<'a> base::Resolver for Resolver<'a> {
247
222
}
248
223
249
224
impl < ' a > Resolver < ' a > {
250
- fn invoc_parent_scope ( & self , invoc_id : ExpnId , derives : Vec < ast:: Path > ) -> ParentScope < ' a > {
251
- let invoc = self . invocations [ & invoc_id] ;
252
- ParentScope {
253
- module : invoc. module ,
254
- expansion : invoc_id. parent ( ) ,
255
- legacy : invoc. parent_legacy_scope ,
256
- derives,
257
- }
258
- }
259
-
260
225
/// Resolve macro path with error reporting and recovery.
261
226
fn smart_resolve_macro_path (
262
227
& mut self ,
@@ -466,8 +431,9 @@ impl<'a> Resolver<'a> {
466
431
Scope :: MacroRules ( legacy_scope) => match legacy_scope {
467
432
LegacyScope :: Binding ( legacy_binding) if ident == legacy_binding. ident =>
468
433
Ok ( ( legacy_binding. binding , Flags :: MACRO_RULES ) ) ,
469
- LegacyScope :: Invocation ( invoc) if invoc. output_legacy_scope . get ( ) . is_none ( ) =>
470
- Err ( Determinacy :: Undetermined ) ,
434
+ LegacyScope :: Invocation ( invoc_id)
435
+ if !this. output_legacy_scopes . contains_key ( & invoc_id) =>
436
+ Err ( Determinacy :: Undetermined ) ,
471
437
_ => Err ( Determinacy :: Determined ) ,
472
438
}
473
439
Scope :: CrateRoot => {
0 commit comments