@@ -12,6 +12,7 @@ use {Module, Resolver};
12
12
use build_reduced_graph:: BuildReducedGraphVisitor ;
13
13
use rustc:: hir:: def_id:: { CRATE_DEF_INDEX , DefIndex } ;
14
14
use rustc:: hir:: map:: { self , DefCollector } ;
15
+ use std:: cell:: Cell ;
15
16
use std:: rc:: Rc ;
16
17
use syntax:: ast;
17
18
use syntax:: errors:: DiagnosticBuilder ;
@@ -35,7 +36,7 @@ pub struct NameBinding {
35
36
#[ derive( Clone ) ]
36
37
pub struct ExpansionData < ' a > {
37
38
backtrace : SyntaxContext ,
38
- pub module : Module < ' a > ,
39
+ pub module : Cell < Module < ' a > > ,
39
40
def_index : DefIndex ,
40
41
// True if this expansion is in a `const_integer` position, for example `[u32; m!()]`.
41
42
// c.f. `DefCollector::visit_ast_const_integer`.
@@ -46,7 +47,7 @@ impl<'a> ExpansionData<'a> {
46
47
pub fn root ( graph_root : Module < ' a > ) -> Self {
47
48
ExpansionData {
48
49
backtrace : SyntaxContext :: empty ( ) ,
49
- module : graph_root,
50
+ module : Cell :: new ( graph_root) ,
50
51
def_index : CRATE_DEF_INDEX ,
51
52
const_integer : false ,
52
53
}
@@ -61,18 +62,18 @@ impl<'a> base::Resolver for Resolver<'a> {
61
62
fn get_module_scope ( & mut self , id : ast:: NodeId ) -> Mark {
62
63
let mark = Mark :: fresh ( ) ;
63
64
let module = self . module_map [ & id] ;
64
- self . expansion_data . insert ( mark, ExpansionData {
65
+ self . expansion_data . insert ( mark, self . arenas . alloc_expansion_data ( ExpansionData {
65
66
backtrace : SyntaxContext :: empty ( ) ,
66
- module : module,
67
+ module : Cell :: new ( module) ,
67
68
def_index : module. def_id ( ) . unwrap ( ) . index ,
68
69
const_integer : false ,
69
- } ) ;
70
+ } ) ) ;
70
71
mark
71
72
}
72
73
73
74
fn visit_expansion ( & mut self , mark : Mark , expansion : & Expansion ) {
74
75
self . collect_def_ids ( mark, expansion) ;
75
- self . current_module = self . expansion_data [ & mark] . module ;
76
+ self . current_module = self . expansion_data [ & mark] . module . get ( ) ;
76
77
expansion. visit_with ( & mut BuildReducedGraphVisitor { resolver : self , expansion : mark } ) ;
77
78
}
78
79
@@ -81,13 +82,14 @@ impl<'a> base::Resolver for Resolver<'a> {
81
82
self . session . span_err ( def. span , "user-defined macros may not be named `macro_rules`" ) ;
82
83
}
83
84
if def. use_locally {
84
- let ExpansionData { mut module, backtrace, .. } = self . expansion_data [ & scope] ;
85
+ let expansion_data = self . expansion_data [ & scope] ;
86
+ let mut module = expansion_data. module . get ( ) ;
85
87
while module. macros_escape {
86
88
module = module. parent . unwrap ( ) ;
87
89
}
88
90
let binding = NameBinding {
89
91
ext : Rc :: new ( macro_rules:: compile ( & self . session . parse_sess , & def) ) ,
90
- expansion : backtrace. data ( ) . prev_ctxt . data ( ) . outer_mark ,
92
+ expansion : expansion_data . backtrace . data ( ) . prev_ctxt . data ( ) . outer_mark ,
91
93
shadowing : self . resolve_macro_name ( scope, def. ident . name , false ) . is_some ( ) ,
92
94
span : def. span ,
93
95
} ;
@@ -119,7 +121,7 @@ impl<'a> base::Resolver for Resolver<'a> {
119
121
fn find_attr_invoc ( & mut self , attrs : & mut Vec < ast:: Attribute > ) -> Option < ast:: Attribute > {
120
122
for i in 0 ..attrs. len ( ) {
121
123
let name = intern ( & attrs[ i] . name ( ) ) ;
122
- match self . expansion_data [ & Mark :: root ( ) ] . module . macros . borrow ( ) . get ( & name) {
124
+ match self . expansion_data [ & Mark :: root ( ) ] . module . get ( ) . macros . borrow ( ) . get ( & name) {
123
125
Some ( binding) => match * binding. ext {
124
126
MultiModifier ( ..) | MultiDecorator ( ..) | SyntaxExtension :: AttrProcMacro ( ..) => {
125
127
return Some ( attrs. remove ( i) )
@@ -164,10 +166,11 @@ impl<'a> base::Resolver for Resolver<'a> {
164
166
impl < ' a > Resolver < ' a > {
165
167
pub fn resolve_macro_name ( & mut self , scope : Mark , name : ast:: Name , record_used : bool )
166
168
-> Option < Rc < SyntaxExtension > > {
167
- let ExpansionData { mut module, backtrace, .. } = self . expansion_data [ & scope] ;
169
+ let expansion_data = self . expansion_data [ & scope] ;
170
+ let mut module = expansion_data. module . get ( ) ;
168
171
loop {
169
172
if let Some ( binding) = module. macros . borrow ( ) . get ( & name) {
170
- let mut backtrace = backtrace. data ( ) ;
173
+ let mut backtrace = expansion_data . backtrace . data ( ) ;
171
174
while binding. expansion != backtrace. outer_mark {
172
175
if backtrace. outer_mark != Mark :: root ( ) {
173
176
backtrace = backtrace. prev_ctxt . data ( ) ;
@@ -205,14 +208,18 @@ impl<'a> Resolver<'a> {
205
208
}
206
209
207
210
fn collect_def_ids ( & mut self , mark : Mark , expansion : & Expansion ) {
208
- let expansion_data = & mut self . expansion_data ;
209
- let ExpansionData { backtrace, def_index, const_integer, module } = expansion_data[ & mark] ;
211
+ let Resolver { ref mut expansion_data, arenas, graph_root, .. } = * self ;
212
+ let ExpansionData { def_index, const_integer, backtrace, .. } =
213
+ expansion_data[ & mark] . clone ( ) ;
214
+
210
215
let visit_macro_invoc = & mut |invoc : map:: MacroInvocationData | {
211
- expansion_data. entry ( invoc. mark ) . or_insert ( ExpansionData {
212
- backtrace : backtrace. apply_mark ( invoc. mark ) ,
213
- def_index : invoc. def_index ,
214
- const_integer : invoc. const_integer ,
215
- module : module,
216
+ expansion_data. entry ( invoc. mark ) . or_insert_with ( || {
217
+ arenas. alloc_expansion_data ( ExpansionData {
218
+ backtrace : backtrace. apply_mark ( invoc. mark ) ,
219
+ def_index : invoc. def_index ,
220
+ const_integer : invoc. const_integer ,
221
+ module : Cell :: new ( graph_root) ,
222
+ } )
216
223
} ) ;
217
224
} ;
218
225
0 commit comments