1
- use std:: borrow:: Cow ;
2
1
use std:: collections:: BTreeMap ;
3
2
use std:: path:: { Path , PathBuf } ;
4
3
4
+ use rustc_arena:: TypedArena ;
5
5
use rustc_ast:: ast;
6
+ use rustc_ast:: ptr:: P ;
6
7
use rustc_ast:: visit:: Visitor ;
7
8
use rustc_span:: symbol:: { self , sym, Symbol } ;
8
9
use rustc_span:: Span ;
9
- use thin_vec:: ThinVec ;
10
10
use thiserror:: Error ;
11
11
12
12
use crate :: attr:: MetaVisitor ;
@@ -25,17 +25,17 @@ type FileModMap<'ast> = BTreeMap<FileName, Module<'ast>>;
25
25
/// Represents module with its inner attributes.
26
26
#[ derive( Debug , Clone ) ]
27
27
pub ( crate ) struct Module < ' a > {
28
- ast_mod_kind : Option < Cow < ' a , ast:: ModKind > > ,
29
- pub ( crate ) items : Cow < ' a , ThinVec < rustc_ast:: ptr:: P < ast:: Item > > > ,
28
+ ast_mod_kind : Option < & ' a ast:: ModKind > ,
29
+ pub ( crate ) items : & ' a [ rustc_ast:: ptr:: P < ast:: Item > ] ,
30
30
inner_attr : ast:: AttrVec ,
31
31
pub ( crate ) span : Span ,
32
32
}
33
33
34
34
impl < ' a > Module < ' a > {
35
35
pub ( crate ) fn new (
36
36
mod_span : Span ,
37
- ast_mod_kind : Option < Cow < ' a , ast:: ModKind > > ,
38
- mod_items : Cow < ' a , ThinVec < rustc_ast:: ptr:: P < ast:: Item > > > ,
37
+ ast_mod_kind : Option < & ' a ast:: ModKind > ,
38
+ mod_items : & ' a [ rustc_ast:: ptr:: P < ast:: Item > ] ,
39
39
mod_attrs : & [ ast:: Attribute ] ,
40
40
) -> Self {
41
41
let inner_attr = mod_attrs
@@ -58,6 +58,8 @@ impl<'a> Module<'a> {
58
58
59
59
/// Maps each module to the corresponding file.
60
60
pub ( crate ) struct ModResolver < ' ast , ' sess > {
61
+ item_arena : & ' ast TypedArena < P < ast:: Item > > ,
62
+ mod_kind_arena : & ' ast TypedArena < ast:: ModKind > ,
61
63
parse_sess : & ' sess ParseSess ,
62
64
directory : Directory ,
63
65
file_map : FileModMap < ' ast > ,
@@ -100,11 +102,15 @@ enum SubModKind<'ast> {
100
102
impl < ' ast , ' sess > ModResolver < ' ast , ' sess > {
101
103
/// Creates a new `ModResolver`.
102
104
pub ( crate ) fn new (
105
+ item_arena : & ' ast TypedArena < P < ast:: Item > > ,
106
+ mod_kind_arena : & ' ast TypedArena < ast:: ModKind > ,
103
107
parse_sess : & ' sess ParseSess ,
104
108
directory_ownership : DirectoryOwnership ,
105
109
recursive : bool ,
106
110
) -> Self {
107
111
ModResolver {
112
+ item_arena,
113
+ mod_kind_arena,
108
114
directory : Directory {
109
115
path : PathBuf :: new ( ) ,
110
116
ownership : directory_ownership,
@@ -128,7 +134,7 @@ impl<'ast, 'sess> ModResolver<'ast, 'sess> {
128
134
129
135
// Skip visiting sub modules when the input is from stdin.
130
136
if self . recursive {
131
- self . visit_mod_from_ast ( & krate. items ) ?;
137
+ self . visit_items ( & krate. items ) ?;
132
138
}
133
139
134
140
let snippet_provider = self . parse_sess . snippet_provider ( krate. spans . inner_span ) ;
@@ -138,7 +144,7 @@ impl<'ast, 'sess> ModResolver<'ast, 'sess> {
138
144
Module :: new (
139
145
mk_sp ( snippet_provider. start_pos ( ) , snippet_provider. end_pos ( ) ) ,
140
146
None ,
141
- Cow :: Borrowed ( & krate. items ) ,
147
+ & krate. items ,
142
148
& krate. attrs ,
143
149
) ,
144
150
) ;
@@ -149,66 +155,28 @@ impl<'ast, 'sess> ModResolver<'ast, 'sess> {
149
155
fn visit_cfg_if ( & mut self , item : & ast:: Item ) -> Result < ( ) , ModuleResolutionError > {
150
156
let mut visitor = visitor:: CfgIfVisitor :: new ( self . parse_sess ) ;
151
157
visitor. visit_item ( item) ;
152
- self . visit_mod_outside_ast ( & visitor. items ) ?;
158
+ let items = self . item_arena . alloc_from_iter ( visitor. items ) ;
159
+ self . visit_items ( & * items) ?;
153
160
Ok ( ( ) )
154
161
}
155
162
156
- /// Visit modules defined inside macro calls.
157
- fn visit_mod_outside_ast (
158
- & mut self ,
159
- items : & [ rustc_ast:: ptr:: P < ast:: Item > ] ,
160
- ) -> Result < ( ) , ModuleResolutionError > {
161
- for item in items {
162
- if is_cfg_if ( item) {
163
- self . visit_cfg_if ( item) ?;
164
- continue ;
165
- }
166
-
167
- if let ast:: ItemKind :: Mod ( _, ref sub_mod_kind) = item. kind {
168
- let span = item. span ;
169
- self . visit_sub_mod (
170
- & item,
171
- Module :: new (
172
- span,
173
- Some ( Cow :: Owned ( sub_mod_kind. clone ( ) ) ) ,
174
- Cow :: Owned ( ThinVec :: new ( ) ) ,
175
- & [ ] ,
176
- ) ,
177
- ) ?;
178
- }
179
- }
180
- Ok ( ( ) )
181
- }
182
-
183
- /// Visit modules from AST.
184
- fn visit_mod_from_ast (
163
+ fn visit_items (
185
164
& mut self ,
186
165
items : & ' ast [ rustc_ast:: ptr:: P < ast:: Item > ] ,
187
166
) -> Result < ( ) , ModuleResolutionError > {
188
167
for item in items {
189
168
if is_cfg_if ( item) {
190
169
self . visit_cfg_if ( item) ?;
191
- }
192
-
193
- if let ast:: ItemKind :: Mod ( _, ref sub_mod_kind) = item. kind {
194
- let span = item. span ;
195
- self . visit_sub_mod (
196
- item,
197
- Module :: new (
198
- span,
199
- Some ( Cow :: Borrowed ( sub_mod_kind) ) ,
200
- Cow :: Owned ( ThinVec :: new ( ) ) ,
201
- & [ ] ,
202
- ) ,
203
- ) ?;
170
+ } else if let ast:: ItemKind :: Mod ( _, sub_mod_kind) = & item. kind {
171
+ self . visit_sub_mod ( & item, Module :: new ( item. span , Some ( sub_mod_kind) , & [ ] , & [ ] ) ) ?;
204
172
}
205
173
}
206
174
Ok ( ( ) )
207
175
}
208
176
209
177
fn visit_sub_mod (
210
178
& mut self ,
211
- item : & ast:: Item ,
179
+ item : & ' ast ast:: Item ,
212
180
sub_mod : Module < ' ast > ,
213
181
) -> Result < ( ) , ModuleResolutionError > {
214
182
if contains_skip ( & item. attrs ) {
@@ -286,14 +254,10 @@ impl<'ast, 'sess> ModResolver<'ast, 'sess> {
286
254
& mut self ,
287
255
sub_mod : Module < ' ast > ,
288
256
) -> Result < ( ) , ModuleResolutionError > {
289
- match ( sub_mod. ast_mod_kind , sub_mod. items ) {
290
- ( Some ( Cow :: Borrowed ( ast:: ModKind :: Loaded ( items, _, _) ) ) , _) => {
291
- self . visit_mod_from_ast ( items)
292
- }
293
- ( Some ( Cow :: Owned ( ast:: ModKind :: Loaded ( items, _, _) ) ) , _) | ( _, Cow :: Owned ( items) ) => {
294
- self . visit_mod_outside_ast ( & items)
295
- }
296
- ( _, _) => Ok ( ( ) ) ,
257
+ if let Some ( ast:: ModKind :: Loaded ( items, _, _) ) = sub_mod. ast_mod_kind {
258
+ self . visit_items ( items)
259
+ } else {
260
+ self . visit_items ( & sub_mod. items )
297
261
}
298
262
}
299
263
@@ -319,8 +283,8 @@ impl<'ast, 'sess> ModResolver<'ast, 'sess> {
319
283
DirectoryOwnership :: Owned { relative : None } ,
320
284
Module :: new (
321
285
span,
322
- Some ( Cow :: Owned ( ast:: ModKind :: Unloaded ) ) ,
323
- Cow :: Owned ( items) ,
286
+ Some ( self . mod_kind_arena . alloc ( ast:: ModKind :: Unloaded ) ) ,
287
+ self . item_arena . alloc_from_iter ( items) ,
324
288
& attrs,
325
289
) ,
326
290
) ) ) ,
@@ -369,8 +333,8 @@ impl<'ast, 'sess> ModResolver<'ast, 'sess> {
369
333
dir_ownership,
370
334
Module :: new (
371
335
span,
372
- Some ( Cow :: Owned ( ast:: ModKind :: Unloaded ) ) ,
373
- Cow :: Owned ( items) ,
336
+ Some ( self . mod_kind_arena . alloc ( ast:: ModKind :: Unloaded ) ) ,
337
+ self . item_arena . alloc_from_iter ( items) ,
374
338
& attrs,
375
339
) ,
376
340
) ) )
@@ -381,8 +345,8 @@ impl<'ast, 'sess> ModResolver<'ast, 'sess> {
381
345
dir_ownership,
382
346
Module :: new (
383
347
span,
384
- Some ( Cow :: Owned ( ast:: ModKind :: Unloaded ) ) ,
385
- Cow :: Owned ( items) ,
348
+ Some ( self . mod_kind_arena . alloc ( ast:: ModKind :: Unloaded ) ) ,
349
+ self . item_arena . alloc_from_iter ( items) ,
386
350
& attrs,
387
351
) ,
388
352
) ) ;
@@ -519,8 +483,8 @@ impl<'ast, 'sess> ModResolver<'ast, 'sess> {
519
483
DirectoryOwnership :: Owned { relative : None } ,
520
484
Module :: new (
521
485
span,
522
- Some ( Cow :: Owned ( ast:: ModKind :: Unloaded ) ) ,
523
- Cow :: Owned ( items) ,
486
+ Some ( self . mod_kind_arena . alloc ( ast:: ModKind :: Unloaded ) ) ,
487
+ self . item_arena . alloc_from_iter ( items) ,
524
488
& attrs,
525
489
) ,
526
490
) )
0 commit comments