@@ -6,6 +6,7 @@ use rustc_ast::ast;
6
6
use rustc_ast:: attr:: HasAttrs ;
7
7
use rustc_ast:: visit:: Visitor ;
8
8
use rustc_span:: symbol:: { self , sym, Symbol } ;
9
+ use rustc_span:: Span ;
9
10
use thiserror:: Error ;
10
11
11
12
use crate :: attr:: MetaVisitor ;
@@ -24,20 +25,31 @@ type FileModMap<'ast> = BTreeMap<FileName, Module<'ast>>;
24
25
/// Represents module with its inner attributes.
25
26
#[ derive( Debug , Clone ) ]
26
27
pub ( crate ) struct Module < ' a > {
27
- ast_mod : Cow < ' a , ast:: Mod > ,
28
+ ast_mod_kind : Option < Cow < ' a , ast:: ModKind > > ,
29
+ pub ( crate ) items : Cow < ' a , Vec < rustc_ast:: ptr:: P < ast:: Item > > > ,
30
+ attrs : Cow < ' a , Vec < ast:: Attribute > > ,
28
31
inner_attr : Vec < ast:: Attribute > ,
32
+ pub ( crate ) span : Span ,
29
33
}
30
34
31
35
impl < ' a > Module < ' a > {
32
- pub ( crate ) fn new ( ast_mod : Cow < ' a , ast:: Mod > , attrs : & [ ast:: Attribute ] ) -> Self {
33
- let inner_attr = attrs
36
+ pub ( crate ) fn new (
37
+ mod_span : Span ,
38
+ ast_mod_kind : Option < Cow < ' a , ast:: ModKind > > ,
39
+ mod_items : Cow < ' a , Vec < rustc_ast:: ptr:: P < ast:: Item > > > ,
40
+ mod_attrs : Cow < ' a , Vec < ast:: Attribute > > ,
41
+ ) -> Self {
42
+ let inner_attr = mod_attrs
34
43
. iter ( )
35
44
. filter ( |attr| attr. style == ast:: AttrStyle :: Inner )
36
45
. cloned ( )
37
46
. collect ( ) ;
38
47
Module {
39
- ast_mod,
48
+ items : mod_items,
49
+ attrs : mod_attrs,
40
50
inner_attr,
51
+ span : mod_span,
52
+ ast_mod_kind,
41
53
}
42
54
}
43
55
}
@@ -51,12 +63,6 @@ impl<'a> HasAttrs for Module<'a> {
51
63
}
52
64
}
53
65
54
- impl < ' a > AsRef < ast:: Mod > for Module < ' a > {
55
- fn as_ref ( & self ) -> & ast:: Mod {
56
- & self . ast_mod
57
- }
58
- }
59
-
60
66
/// Maps each module to the corresponding file.
61
67
pub ( crate ) struct ModResolver < ' ast , ' sess > {
62
68
parse_sess : & ' sess ParseSess ,
@@ -124,12 +130,17 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
124
130
125
131
// Skip visiting sub modules when the input is from stdin.
126
132
if self . recursive {
127
- self . visit_mod_from_ast ( & krate. module ) ?;
133
+ self . visit_mod_from_ast ( & krate. items ) ?;
128
134
}
129
135
130
136
self . file_map . insert (
131
137
root_filename,
132
- Module :: new ( Cow :: Borrowed ( & krate. module ) , & krate. attrs ) ,
138
+ Module :: new (
139
+ krate. span ,
140
+ None ,
141
+ Cow :: Borrowed ( & krate. items ) ,
142
+ Cow :: Borrowed ( & krate. attrs ) ,
143
+ ) ,
133
144
) ;
134
145
Ok ( self . file_map )
135
146
}
@@ -139,40 +150,69 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
139
150
let mut visitor = visitor:: CfgIfVisitor :: new ( self . parse_sess ) ;
140
151
visitor. visit_item ( & item) ;
141
152
for module_item in visitor. mods ( ) {
142
- if let ast:: ItemKind :: Mod ( ref sub_mod ) = module_item. item . kind {
153
+ if let ast:: ItemKind :: Mod ( _ , ref sub_mod_kind ) = module_item. item . kind {
143
154
self . visit_sub_mod (
144
155
& module_item. item ,
145
- Module :: new ( Cow :: Owned ( sub_mod. clone ( ) ) , & module_item. item . attrs ) ,
156
+ Module :: new (
157
+ module_item. item . span ,
158
+ Some ( Cow :: Owned ( sub_mod_kind. clone ( ) ) ) ,
159
+ Cow :: Owned ( vec ! [ ] ) ,
160
+ Cow :: Owned ( vec ! [ ] ) ,
161
+ ) ,
146
162
) ?;
147
163
}
148
164
}
149
165
Ok ( ( ) )
150
166
}
151
167
152
168
/// Visit modules defined inside macro calls.
153
- fn visit_mod_outside_ast ( & mut self , module : ast:: Mod ) -> Result < ( ) , ModuleResolutionError > {
154
- for item in module. items {
169
+ fn visit_mod_outside_ast (
170
+ & mut self ,
171
+ items : Vec < rustc_ast:: ptr:: P < ast:: Item > > ,
172
+ ) -> Result < ( ) , ModuleResolutionError > {
173
+ for item in items {
155
174
if is_cfg_if ( & item) {
156
175
self . visit_cfg_if ( Cow :: Owned ( item. into_inner ( ) ) ) ?;
157
176
continue ;
158
177
}
159
178
160
- if let ast:: ItemKind :: Mod ( ref sub_mod) = item. kind {
161
- self . visit_sub_mod ( & item, Module :: new ( Cow :: Owned ( sub_mod. clone ( ) ) , & item. attrs ) ) ?;
179
+ if let ast:: ItemKind :: Mod ( _, ref sub_mod_kind) = item. kind {
180
+ let span = item. span ;
181
+ self . visit_sub_mod (
182
+ & item,
183
+ Module :: new (
184
+ span,
185
+ Some ( Cow :: Owned ( sub_mod_kind. clone ( ) ) ) ,
186
+ Cow :: Owned ( vec ! [ ] ) ,
187
+ Cow :: Owned ( vec ! [ ] ) ,
188
+ ) ,
189
+ ) ?;
162
190
}
163
191
}
164
192
Ok ( ( ) )
165
193
}
166
194
167
195
/// Visit modules from AST.
168
- fn visit_mod_from_ast ( & mut self , module : & ' ast ast:: Mod ) -> Result < ( ) , ModuleResolutionError > {
169
- for item in & module. items {
196
+ fn visit_mod_from_ast (
197
+ & mut self ,
198
+ items : & ' ast Vec < rustc_ast:: ptr:: P < ast:: Item > > ,
199
+ ) -> Result < ( ) , ModuleResolutionError > {
200
+ for item in items {
170
201
if is_cfg_if ( item) {
171
202
self . visit_cfg_if ( Cow :: Borrowed ( item) ) ?;
172
203
}
173
204
174
- if let ast:: ItemKind :: Mod ( ref sub_mod) = item. kind {
175
- self . visit_sub_mod ( item, Module :: new ( Cow :: Borrowed ( sub_mod) , & item. attrs ) ) ?;
205
+ if let ast:: ItemKind :: Mod ( _, ref sub_mod_kind) = item. kind {
206
+ let span = item. span ;
207
+ self . visit_sub_mod (
208
+ item,
209
+ Module :: new (
210
+ span,
211
+ Some ( Cow :: Borrowed ( sub_mod_kind) ) ,
212
+ Cow :: Owned ( vec ! [ ] ) ,
213
+ Cow :: Borrowed ( & item. attrs ) ,
214
+ ) ,
215
+ ) ?;
176
216
}
177
217
}
178
218
Ok ( ( ) )
@@ -273,9 +313,12 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
273
313
if let Some ( directory) = directory {
274
314
self . directory = directory;
275
315
}
276
- match sub_mod. ast_mod {
277
- Cow :: Borrowed ( sub_mod) => self . visit_mod_from_ast ( sub_mod) ,
278
- Cow :: Owned ( sub_mod) => self . visit_mod_outside_ast ( sub_mod) ,
316
+ match ( sub_mod. ast_mod_kind , sub_mod. items ) {
317
+ ( Some ( Cow :: Borrowed ( ast:: ModKind :: Loaded ( items, ast:: Inline :: No , _) ) ) , _) => {
318
+ self . visit_mod_from_ast ( & items)
319
+ }
320
+ ( Some ( Cow :: Owned ( ..) ) , Cow :: Owned ( items) ) => self . visit_mod_outside_ast ( items) ,
321
+ ( _, _) => Ok ( ( ) ) ,
279
322
}
280
323
}
281
324
@@ -294,13 +337,17 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
294
337
if self . parse_sess . is_file_parsed ( & path) {
295
338
return Ok ( None ) ;
296
339
}
297
- return match Parser :: parse_file_as_module ( self . parse_sess , & path, sub_mod. ast_mod . inner )
298
- {
299
- Ok ( ( _, ref attrs) ) if contains_skip ( attrs) => Ok ( None ) ,
300
- Ok ( m) => Ok ( Some ( SubModKind :: External (
340
+ return match Parser :: parse_file_as_module ( self . parse_sess , & path, sub_mod. span ) {
341
+ Ok ( ( ref attrs, _, _) ) if contains_skip ( attrs) => Ok ( None ) ,
342
+ Ok ( ( attrs, items, span) ) => Ok ( Some ( SubModKind :: External (
301
343
path,
302
344
DirectoryOwnership :: Owned { relative : None } ,
303
- Module :: new ( Cow :: Owned ( m. 0 ) , & m. 1 ) ,
345
+ Module :: new (
346
+ span,
347
+ Some ( Cow :: Owned ( ast:: ModKind :: Unloaded ) ) ,
348
+ Cow :: Owned ( items) ,
349
+ Cow :: Owned ( attrs) ,
350
+ ) ,
304
351
) ) ) ,
305
352
Err ( ParserError :: ParseError ) => Err ( ModuleResolutionError {
306
353
module : mod_name. to_string ( ) ,
@@ -338,18 +385,30 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
338
385
return Ok ( Some ( SubModKind :: MultiExternal ( mods_outside_ast) ) ) ;
339
386
}
340
387
}
341
- match Parser :: parse_file_as_module ( self . parse_sess , & path, sub_mod. ast_mod . inner ) {
342
- Ok ( ( _, ref attrs) ) if contains_skip ( attrs) => Ok ( None ) ,
343
- Ok ( m) if outside_mods_empty => Ok ( Some ( SubModKind :: External (
344
- path,
345
- ownership,
346
- Module :: new ( Cow :: Owned ( m. 0 ) , & m. 1 ) ,
347
- ) ) ) ,
348
- Ok ( m) => {
388
+ match Parser :: parse_file_as_module ( self . parse_sess , & path, sub_mod. span ) {
389
+ Ok ( ( ref attrs, _, _) ) if contains_skip ( attrs) => Ok ( None ) ,
390
+ Ok ( ( attrs, items, span) ) if outside_mods_empty => {
391
+ Ok ( Some ( SubModKind :: External (
392
+ path,
393
+ ownership,
394
+ Module :: new (
395
+ span,
396
+ Some ( Cow :: Owned ( ast:: ModKind :: Unloaded ) ) ,
397
+ Cow :: Owned ( items) ,
398
+ Cow :: Owned ( attrs) ,
399
+ ) ,
400
+ ) ) )
401
+ }
402
+ Ok ( ( attrs, items, span) ) => {
349
403
mods_outside_ast. push ( (
350
404
path. clone ( ) ,
351
405
ownership,
352
- Module :: new ( Cow :: Owned ( m. 0 ) , & m. 1 ) ,
406
+ Module :: new (
407
+ span,
408
+ Some ( Cow :: Owned ( ast:: ModKind :: Unloaded ) ) ,
409
+ Cow :: Owned ( items) ,
410
+ Cow :: Owned ( attrs) ,
411
+ ) ,
353
412
) ) ;
354
413
if should_insert {
355
414
mods_outside_ast. push ( ( path, ownership, sub_mod. clone ( ) ) ) ;
@@ -437,20 +496,22 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
437
496
) ) ;
438
497
continue ;
439
498
}
440
- let m = match Parser :: parse_file_as_module (
441
- self . parse_sess ,
442
- & actual_path,
443
- sub_mod. ast_mod . inner ,
444
- ) {
445
- Ok ( ( _, ref attrs) ) if contains_skip ( attrs) => continue ,
446
- Ok ( m) => m,
447
- Err ( ..) => continue ,
448
- } ;
499
+ let ( attrs, items, span) =
500
+ match Parser :: parse_file_as_module ( self . parse_sess , & actual_path, sub_mod. span ) {
501
+ Ok ( ( ref attrs, _, _) ) if contains_skip ( attrs) => continue ,
502
+ Ok ( m) => m,
503
+ Err ( ..) => continue ,
504
+ } ;
449
505
450
506
result. push ( (
451
507
actual_path,
452
508
DirectoryOwnership :: Owned { relative : None } ,
453
- Module :: new ( Cow :: Owned ( m. 0 ) , & m. 1 ) ,
509
+ Module :: new (
510
+ span,
511
+ Some ( Cow :: Owned ( ast:: ModKind :: Unloaded ) ) ,
512
+ Cow :: Owned ( items) ,
513
+ Cow :: Owned ( attrs) ,
514
+ ) ,
454
515
) )
455
516
}
456
517
result
0 commit comments