@@ -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 :: config:: FileName ;
@@ -39,9 +40,12 @@ pub(crate) fn get_mod_inner_attrs<'a>(
39
40
/// Represents module with its inner attributes.
40
41
#[ derive( Debug , Clone ) ]
41
42
pub ( crate ) struct Module < ' a > {
42
- ast_mod : Cow < ' a , ast:: Mod > ,
43
+ ast_mod_kind : Option < Cow < ' a , ast:: ModKind > > ,
44
+ pub ( crate ) items : Cow < ' a , Vec < rustc_ast:: ptr:: P < ast:: Item > > > ,
45
+ attrs : Cow < ' a , Vec < ast:: Attribute > > ,
43
46
ast_item : Option < Cow < ' a , ast:: Item > > ,
44
47
inner_attr : Vec < ast:: Attribute > ,
48
+ pub ( crate ) span : Span ,
45
49
}
46
50
47
51
impl < ' a > Module < ' a > {
@@ -67,21 +71,30 @@ impl<'a> Module<'a> {
67
71
}
68
72
69
73
pub ( crate ) fn new (
70
- ast_mod : Cow < ' a , ast:: Mod > ,
74
+ mod_span : Span ,
75
+ ast_mod_kind : Option < Cow < ' a , ast:: ModKind > > ,
71
76
ast_item : Option < Cow < ' a , ast:: Item > > ,
72
- attrs : & [ ast:: Attribute ] ,
77
+ mod_items : Cow < ' a , Vec < rustc_ast:: ptr:: P < ast:: Item > > > ,
78
+ mod_attrs : Cow < ' a , Vec < ast:: Attribute > > ,
73
79
) -> Self {
74
- let inner_attr = attrs
80
+ let inner_attr = mod_attrs
75
81
. iter ( )
76
82
. filter ( |attr| attr. style == ast:: AttrStyle :: Inner )
77
83
. cloned ( )
78
84
. collect ( ) ;
79
85
Module {
86
+ ast_mod_kind,
80
87
ast_item,
81
- ast_mod,
88
+ items : mod_items,
89
+ attrs : mod_attrs,
82
90
inner_attr,
91
+ span : mod_span,
83
92
}
84
93
}
94
+
95
+ pub ( crate ) fn outside_ast_mod_span ( & self ) -> Option < Span > {
96
+ self . ast_item . as_ref ( ) . map ( |item| item. span )
97
+ }
85
98
}
86
99
87
100
impl < ' a > HasAttrs for Module < ' a > {
@@ -93,12 +106,6 @@ impl<'a> HasAttrs for Module<'a> {
93
106
}
94
107
}
95
108
96
- impl < ' a > AsRef < ast:: Mod > for Module < ' a > {
97
- fn as_ref ( & self ) -> & ast:: Mod {
98
- & self . ast_mod
99
- }
100
- }
101
-
102
109
/// Maps each module to the corresponding file.
103
110
pub ( crate ) struct ModResolver < ' ast , ' sess > {
104
111
parse_sess : & ' sess ParseSess ,
@@ -164,11 +171,17 @@ impl<'ast, 'sess> ModResolver<'ast, 'sess> {
164
171
_ => PathBuf :: new ( ) ,
165
172
} ;
166
173
167
- self . visit_mod_from_ast ( & krate. module ) ?;
174
+ self . visit_mod_from_ast ( & krate. items ) ?;
168
175
169
176
self . file_map . insert (
170
177
root_filename,
171
- Module :: new ( Cow :: Borrowed ( & krate. module ) , None , & krate. attrs ) ,
178
+ Module :: new (
179
+ krate. span ,
180
+ None ,
181
+ None ,
182
+ Cow :: Borrowed ( & krate. items ) ,
183
+ Cow :: Borrowed ( & krate. attrs ) ,
184
+ ) ,
172
185
) ;
173
186
Ok ( self . file_map )
174
187
}
@@ -178,51 +191,63 @@ impl<'ast, 'sess> ModResolver<'ast, 'sess> {
178
191
let mut visitor = visitor:: CfgIfVisitor :: new ( self . parse_sess ) ;
179
192
visitor. visit_item ( & item) ;
180
193
for module_item in visitor. mods ( ) {
181
- if let ast:: ItemKind :: Mod ( ref sub_mod ) = module_item. item . kind {
194
+ if let ast:: ItemKind :: Mod ( _ , ref sub_mod_kind ) = module_item. item . kind {
182
195
self . visit_sub_mod ( Module :: new (
183
- Cow :: Owned ( sub_mod. clone ( ) ) ,
196
+ module_item. item . span ,
197
+ Some ( Cow :: Owned ( sub_mod_kind. clone ( ) ) ) ,
184
198
Some ( Cow :: Owned ( module_item. item ) ) ,
185
- & [ ] ,
199
+ Cow :: Owned ( vec ! [ ] ) ,
200
+ Cow :: Owned ( vec ! [ ] ) ,
186
201
) ) ?;
187
202
}
188
203
}
189
204
Ok ( ( ) )
190
205
}
191
206
192
207
/// Visit modules defined inside macro calls.
193
- fn visit_mod_outside_ast ( & mut self , module : ast:: Mod ) -> Result < ( ) , ModuleResolutionError > {
194
- for item in module. items {
208
+ fn visit_mod_outside_ast (
209
+ & mut self ,
210
+ items : Vec < rustc_ast:: ptr:: P < ast:: Item > > ,
211
+ ) -> Result < ( ) , ModuleResolutionError > {
212
+ for item in items {
195
213
if is_cfg_if ( & item) {
196
214
self . visit_cfg_if ( Cow :: Owned ( item. into_inner ( ) ) ) ?;
197
215
continue ;
198
216
}
199
217
200
- if let ast:: ItemKind :: Mod ( ref sub_mod ) = item. kind {
218
+ if let ast:: ItemKind :: Mod ( _ , ref sub_mod_kind ) = item. kind {
201
219
self . visit_sub_mod ( Module :: new (
202
- Cow :: Owned ( sub_mod. clone ( ) ) ,
220
+ item. span ,
221
+ Some ( Cow :: Owned ( sub_mod_kind. clone ( ) ) ) ,
203
222
Some ( Cow :: Owned ( item. into_inner ( ) ) ) ,
204
- & [ ] ,
223
+ Cow :: Owned ( vec ! [ ] ) ,
224
+ Cow :: Owned ( vec ! [ ] ) ,
205
225
) ) ?;
206
226
}
207
227
}
208
228
Ok ( ( ) )
209
229
}
210
230
211
231
/// Visit modules from AST.
212
- fn visit_mod_from_ast ( & mut self , module : & ' ast ast:: Mod ) -> Result < ( ) , ModuleResolutionError > {
213
- for item in & module. items {
232
+ fn visit_mod_from_ast (
233
+ & mut self ,
234
+ items : & ' ast Vec < rustc_ast:: ptr:: P < ast:: Item > > ,
235
+ ) -> Result < ( ) , ModuleResolutionError > {
236
+ for item in items {
214
237
if is_cfg_if ( item) {
215
238
let result = self . visit_cfg_if ( Cow :: Borrowed ( item) ) ;
216
239
if result. is_err ( ) && self . recursive {
217
240
return result;
218
241
}
219
242
}
220
243
221
- if let ast:: ItemKind :: Mod ( ref sub_mod ) = item. kind {
244
+ if let ast:: ItemKind :: Mod ( _ , ref sub_mod_kind ) = item. kind {
222
245
let result = self . visit_sub_mod ( Module :: new (
223
- Cow :: Borrowed ( sub_mod) ,
246
+ item. span ,
247
+ Some ( Cow :: Borrowed ( sub_mod_kind) ) ,
224
248
Some ( Cow :: Borrowed ( item) ) ,
225
- & item. attrs ,
249
+ Cow :: Owned ( vec ! [ ] ) ,
250
+ Cow :: Borrowed ( & item. attrs ) ,
226
251
) ) ;
227
252
if result. is_err ( ) && self . recursive {
228
253
return result;
@@ -330,9 +355,12 @@ impl<'ast, 'sess> ModResolver<'ast, 'sess> {
330
355
if let Some ( directory) = directory {
331
356
self . directory = directory;
332
357
}
333
- match sub_mod. ast_mod {
334
- Cow :: Borrowed ( sub_mod) => self . visit_mod_from_ast ( sub_mod) ,
335
- Cow :: Owned ( sub_mod) => self . visit_mod_outside_ast ( sub_mod) ,
358
+ match ( sub_mod. ast_mod_kind , sub_mod. items ) {
359
+ ( Some ( Cow :: Borrowed ( ast:: ModKind :: Loaded ( items, ast:: Inline :: No , _) ) ) , _) => {
360
+ self . visit_mod_from_ast ( & items)
361
+ }
362
+ ( Some ( Cow :: Owned ( ..) ) , Cow :: Owned ( items) ) => self . visit_mod_outside_ast ( items) ,
363
+ ( _, _) => Ok ( ( ) ) ,
336
364
}
337
365
}
338
366
@@ -351,12 +379,21 @@ impl<'ast, 'sess> ModResolver<'ast, 'sess> {
351
379
if self . parse_sess . is_file_parsed ( & path) {
352
380
return Ok ( None ) ;
353
381
}
354
- return match Parser :: parse_file_as_module ( self . parse_sess , & path, sub_mod. ast_mod . inner )
355
- {
356
- Ok ( m) => Ok ( Some ( SubModKind :: External (
382
+ return match Parser :: parse_file_as_module (
383
+ self . parse_sess ,
384
+ & path,
385
+ sub_mod. outside_ast_mod_span ( ) ,
386
+ ) {
387
+ Ok ( ( attrs, items, span) ) => Ok ( Some ( SubModKind :: External (
357
388
path,
358
389
DirectoryOwnership :: Owned { relative : None } ,
359
- Module :: new ( Cow :: Owned ( m. 0 ) , sub_mod. ast_item . clone ( ) , & m. 1 ) ,
390
+ Module :: new (
391
+ span,
392
+ Some ( Cow :: Owned ( ast:: ModKind :: Unloaded ) ) ,
393
+ sub_mod. ast_item . clone ( ) ,
394
+ Cow :: Owned ( items) ,
395
+ Cow :: Owned ( attrs) ,
396
+ ) ,
360
397
) ) ) ,
361
398
Err ( ParserError :: ParseError ) => Err ( ModuleResolutionError {
362
399
module : sub_mod. name ( ) ,
@@ -394,17 +431,35 @@ impl<'ast, 'sess> ModResolver<'ast, 'sess> {
394
431
return Ok ( Some ( SubModKind :: MultiExternal ( mods_outside_ast) ) ) ;
395
432
}
396
433
}
397
- match Parser :: parse_file_as_module ( self . parse_sess , & path, sub_mod. ast_mod . inner ) {
398
- Ok ( m) if outside_mods_empty => Ok ( Some ( SubModKind :: External (
399
- path,
400
- ownership,
401
- Module :: new ( Cow :: Owned ( m. 0 ) , sub_mod. ast_item . clone ( ) , & m. 1 ) ,
402
- ) ) ) ,
403
- Ok ( m) => {
434
+ match Parser :: parse_file_as_module (
435
+ self . parse_sess ,
436
+ & path,
437
+ sub_mod. outside_ast_mod_span ( ) ,
438
+ ) {
439
+ Ok ( ( attrs, items, span) ) if outside_mods_empty => {
440
+ Ok ( Some ( SubModKind :: External (
441
+ path,
442
+ ownership,
443
+ Module :: new (
444
+ span,
445
+ Some ( Cow :: Owned ( ast:: ModKind :: Unloaded ) ) ,
446
+ sub_mod. ast_item . clone ( ) ,
447
+ Cow :: Owned ( items) ,
448
+ Cow :: Owned ( attrs) ,
449
+ ) ,
450
+ ) ) )
451
+ }
452
+ Ok ( ( attrs, items, span) ) => {
404
453
mods_outside_ast. push ( (
405
454
path. clone ( ) ,
406
455
ownership,
407
- Module :: new ( Cow :: Owned ( m. 0 ) , sub_mod. ast_item . clone ( ) , & m. 1 ) ,
456
+ Module :: new (
457
+ span,
458
+ Some ( Cow :: Owned ( ast:: ModKind :: Unloaded ) ) ,
459
+ sub_mod. ast_item . clone ( ) ,
460
+ Cow :: Owned ( items) ,
461
+ Cow :: Owned ( attrs) ,
462
+ ) ,
408
463
) ) ;
409
464
if should_insert {
410
465
mods_outside_ast. push ( ( path, ownership, sub_mod. clone ( ) ) ) ;
@@ -494,10 +549,10 @@ impl<'ast, 'sess> ModResolver<'ast, 'sess> {
494
549
continue ;
495
550
}
496
551
497
- let m = match Parser :: parse_file_as_module (
552
+ let ( attrs , items , span ) = match Parser :: parse_file_as_module (
498
553
self . parse_sess ,
499
554
& actual_path,
500
- sub_mod. ast_mod . inner ,
555
+ sub_mod. outside_ast_mod_span ( ) ,
501
556
) {
502
557
Ok ( m) => m,
503
558
Err ( ..) => continue ,
@@ -506,7 +561,13 @@ impl<'ast, 'sess> ModResolver<'ast, 'sess> {
506
561
result. push ( (
507
562
actual_path,
508
563
DirectoryOwnership :: Owned { relative : None } ,
509
- Module :: new ( Cow :: Owned ( m. 0 ) , sub_mod. ast_item . clone ( ) , & m. 1 ) ,
564
+ Module :: new (
565
+ span,
566
+ Some ( Cow :: Owned ( ast:: ModKind :: Unloaded ) ) ,
567
+ sub_mod. ast_item . clone ( ) ,
568
+ Cow :: Owned ( items) ,
569
+ Cow :: Owned ( attrs) ,
570
+ ) ,
510
571
) )
511
572
}
512
573
result
0 commit comments