11use crate :: { AmbiguityError , AmbiguityKind , AmbiguityErrorMisc , Determinacy } ;
22use 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 } ;
44use crate :: { ModuleOrUniformRoot , KNOWN_TOOLS } ;
55use crate :: Namespace :: * ;
66use crate :: build_reduced_graph:: BuildReducedGraphVisitor ;
@@ -22,36 +22,11 @@ use syntax::feature_gate::GateIssue;
2222use syntax:: symbol:: { Symbol , kw, sym} ;
2323use syntax_pos:: { Span , DUMMY_SP } ;
2424
25- use std:: cell:: Cell ;
2625use std:: { mem, ptr} ;
2726use rustc_data_structures:: sync:: Lrc ;
2827
2928type Res = def:: Res < ast:: NodeId > ;
3029
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-
5530/// Binding produced by a `macro_rules` item.
5631/// Not modularized, can shadow previous legacy bindings, etc.
5732#[ derive( Debug ) ]
@@ -75,7 +50,7 @@ pub enum LegacyScope<'a> {
7550 Binding ( & ' a LegacyBinding < ' a > ) ,
7651 /// The scope introduced by a macro invocation that can potentially
7752 /// create a `macro_rules!` macro definition.
78- Invocation ( & ' a InvocationData < ' a > ) ,
53+ Invocation ( ExpnId ) ,
7954}
8055
8156// Macro namespace is separated into two sub-namespaces, one for bang macros and
@@ -124,9 +99,8 @@ impl<'a> base::Resolver for Resolver<'a> {
12499 ExpnKind :: Macro ( MacroKind :: Attr , sym:: test_case) , DUMMY_SP , self . session . edition ( )
125100 ) ) ) ;
126101 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) ) ;
128103 self . definitions . set_invocation_parent ( expn_id, module. def_id ( ) . unwrap ( ) . index ) ;
129- self . invocations . insert ( expn_id, invocation_data) ;
130104 expn_id
131105 }
132106
@@ -140,29 +114,29 @@ impl<'a> base::Resolver for Resolver<'a> {
140114 } ) ;
141115 }
142116
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+ ) ;
151126 for & derive_invoc_id in derives {
152127 self . definitions . set_invocation_parent ( derive_invoc_id, parent_def) ;
153128 }
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 } ;
164137 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) ;
166140 }
167141
168142 fn register_builtin_macro ( & mut self , ident : ast:: Ident , ext : SyntaxExtension ) {
@@ -178,7 +152,8 @@ impl<'a> base::Resolver for Resolver<'a> {
178152
179153 fn resolve_macro_invocation ( & mut self , invoc : & Invocation , invoc_id : ExpnId , force : bool )
180154 -> 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 {
182157 InvocationKind :: Attr { ref attr, ref derives, after_derive, .. } =>
183158 ( & attr. path , MacroKind :: Attr , derives. clone ( ) , after_derive) ,
184159 InvocationKind :: Bang { ref mac, .. } =>
@@ -192,7 +167,6 @@ impl<'a> base::Resolver for Resolver<'a> {
192167 // will automatically knows about itself.
193168 let mut result = Ok ( None ) ;
194169 if derives. len ( ) > 1 {
195- let parent_scope = & self . invoc_parent_scope ( invoc_id, Vec :: new ( ) ) ;
196170 for path in derives {
197171 match self . resolve_macro_path ( path, Some ( MacroKind :: Derive ) ,
198172 parent_scope, true , force) {
@@ -209,7 +183,8 @@ impl<'a> base::Resolver for Resolver<'a> {
209183 }
210184 } ;
211185
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 ( ) } ;
213188 let ( ext, res) = self . smart_resolve_macro_path ( path, kind, parent_scope, force) ?;
214189
215190 let span = invoc. span ( ) ;
@@ -247,16 +222,6 @@ impl<'a> base::Resolver for Resolver<'a> {
247222}
248223
249224impl < ' 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-
260225 /// Resolve macro path with error reporting and recovery.
261226 fn smart_resolve_macro_path (
262227 & mut self ,
@@ -466,8 +431,9 @@ impl<'a> Resolver<'a> {
466431 Scope :: MacroRules ( legacy_scope) => match legacy_scope {
467432 LegacyScope :: Binding ( legacy_binding) if ident == legacy_binding. ident =>
468433 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 ) ,
471437 _ => Err ( Determinacy :: Determined ) ,
472438 }
473439 Scope :: CrateRoot => {
0 commit comments