@@ -18,12 +18,25 @@ use crate::formatting::{
18
18
19
19
mod visitor;
20
20
21
- type FileModMap < ' ast > = BTreeMap < FileName , Cow < ' ast , ast :: Mod > > ;
21
+ type FileModMap < ' ast > = BTreeMap < FileName , Module < ' ast > > ;
22
22
23
23
lazy_static ! {
24
24
static ref CFG_IF : Symbol = Symbol :: intern( "cfg_if" ) ;
25
25
}
26
26
27
+ /// Represents module with its inner attributes.
28
+ #[ derive( Debug , Clone ) ]
29
+ pub ( crate ) struct Module < ' a > {
30
+ ast_mod : Cow < ' a , ast:: Mod > ,
31
+ inner_attr : Vec < ast:: Attribute > ,
32
+ }
33
+
34
+ impl < ' a > AsRef < ast:: Mod > for Module < ' a > {
35
+ fn as_ref ( & self ) -> & ast:: Mod {
36
+ & self . ast_mod
37
+ }
38
+ }
39
+
27
40
/// Maps each module to the corresponding file.
28
41
pub ( crate ) struct ModResolver < ' ast , ' sess > {
29
42
parse_sess : & ' sess ParseSess ,
@@ -53,9 +66,9 @@ pub(crate) enum ModuleResolutionErrorKind {
53
66
#[ derive( Clone ) ]
54
67
enum SubModKind < ' a , ' ast > {
55
68
/// `mod foo;`
56
- External ( PathBuf , DirectoryOwnership , Cow < ' ast , ast :: Mod > ) ,
69
+ External ( PathBuf , DirectoryOwnership , Module < ' ast > ) ,
57
70
/// `mod foo;` with multiple sources.
58
- MultiExternal ( Vec < ( PathBuf , DirectoryOwnership , Cow < ' ast , ast :: Mod > ) > ) ,
71
+ MultiExternal ( Vec < ( PathBuf , DirectoryOwnership , Module < ' ast > ) > ) ,
59
72
/// `mod foo {}`
60
73
Internal ( & ' a ast:: Item ) ,
61
74
}
@@ -94,8 +107,13 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
94
107
self . visit_mod_from_ast ( & krate. module ) ?;
95
108
}
96
109
97
- self . file_map
98
- . insert ( root_filename, Cow :: Borrowed ( & krate. module ) ) ;
110
+ self . file_map . insert (
111
+ root_filename,
112
+ Module {
113
+ ast_mod : Cow :: Borrowed ( & krate. module ) ,
114
+ inner_attr : krate. attrs . clone ( ) ,
115
+ } ,
116
+ ) ;
99
117
Ok ( self . file_map )
100
118
}
101
119
@@ -105,7 +123,13 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
105
123
visitor. visit_item ( & item) ;
106
124
for module_item in visitor. mods ( ) {
107
125
if let ast:: ItemKind :: Mod ( ref sub_mod) = module_item. item . kind {
108
- self . visit_sub_mod ( & module_item. item , Cow :: Owned ( sub_mod. clone ( ) ) ) ?;
126
+ self . visit_sub_mod (
127
+ & module_item. item ,
128
+ Module {
129
+ ast_mod : Cow :: Owned ( sub_mod. clone ( ) ) ,
130
+ inner_attr : module_item. item . attrs . clone ( ) ,
131
+ } ,
132
+ ) ?;
109
133
}
110
134
}
111
135
Ok ( ( ) )
@@ -120,7 +144,13 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
120
144
}
121
145
122
146
if let ast:: ItemKind :: Mod ( ref sub_mod) = item. kind {
123
- self . visit_sub_mod ( & item, Cow :: Owned ( sub_mod. clone ( ) ) ) ?;
147
+ self . visit_sub_mod (
148
+ & item,
149
+ Module {
150
+ ast_mod : Cow :: Owned ( sub_mod. clone ( ) ) ,
151
+ inner_attr : item. attrs . clone ( ) ,
152
+ } ,
153
+ ) ?;
124
154
}
125
155
}
126
156
Ok ( ( ) )
@@ -134,7 +164,13 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
134
164
}
135
165
136
166
if let ast:: ItemKind :: Mod ( ref sub_mod) = item. kind {
137
- self . visit_sub_mod ( item, Cow :: Borrowed ( sub_mod) ) ?;
167
+ self . visit_sub_mod (
168
+ item,
169
+ Module {
170
+ ast_mod : Cow :: Borrowed ( sub_mod) ,
171
+ inner_attr : item. attrs . clone ( ) ,
172
+ } ,
173
+ ) ?;
138
174
}
139
175
}
140
176
Ok ( ( ) )
@@ -143,12 +179,12 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
143
179
fn visit_sub_mod (
144
180
& mut self ,
145
181
item : & ' c ast:: Item ,
146
- sub_mod : Cow < ' ast , ast :: Mod > ,
182
+ sub_mod : Module < ' ast > ,
147
183
) -> Result < ( ) , ModuleResolutionError > {
148
184
let old_directory = self . directory . clone ( ) ;
149
185
let sub_mod_kind = self . peek_sub_mod ( item, & sub_mod) ?;
150
186
if let Some ( sub_mod_kind) = sub_mod_kind {
151
- self . insert_sub_mod ( sub_mod_kind. clone ( ) , sub_mod . clone ( ) ) ?;
187
+ self . insert_sub_mod ( sub_mod_kind. clone ( ) ) ?;
152
188
self . visit_sub_mod_inner ( sub_mod, sub_mod_kind) ?;
153
189
}
154
190
self . directory = old_directory;
@@ -159,7 +195,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
159
195
fn peek_sub_mod (
160
196
& self ,
161
197
item : & ' c ast:: Item ,
162
- sub_mod : & Cow < ' ast , ast :: Mod > ,
198
+ sub_mod : & Module < ' ast > ,
163
199
) -> Result < Option < SubModKind < ' c , ' ast > > , ModuleResolutionError > {
164
200
if contains_skip ( & item. attrs ) {
165
201
return Ok ( None ) ;
@@ -178,7 +214,6 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
178
214
fn insert_sub_mod (
179
215
& mut self ,
180
216
sub_mod_kind : SubModKind < ' c , ' ast > ,
181
- _sub_mod : Cow < ' ast , ast:: Mod > ,
182
217
) -> Result < ( ) , ModuleResolutionError > {
183
218
match sub_mod_kind {
184
219
SubModKind :: External ( mod_path, _, sub_mod) => {
@@ -200,7 +235,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
200
235
201
236
fn visit_sub_mod_inner (
202
237
& mut self ,
203
- sub_mod : Cow < ' ast , ast :: Mod > ,
238
+ sub_mod : Module < ' ast > ,
204
239
sub_mod_kind : SubModKind < ' c , ' ast > ,
205
240
) -> Result < ( ) , ModuleResolutionError > {
206
241
match sub_mod_kind {
@@ -230,13 +265,13 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
230
265
231
266
fn visit_sub_mod_after_directory_update (
232
267
& mut self ,
233
- sub_mod : Cow < ' ast , ast :: Mod > ,
268
+ sub_mod : Module < ' ast > ,
234
269
directory : Option < Directory > ,
235
270
) -> Result < ( ) , ModuleResolutionError > {
236
271
if let Some ( directory) = directory {
237
272
self . directory = directory;
238
273
}
239
- match sub_mod {
274
+ match sub_mod. ast_mod {
240
275
Cow :: Borrowed ( sub_mod) => self . visit_mod_from_ast ( sub_mod) ,
241
276
Cow :: Owned ( sub_mod) => self . visit_mod_outside_ast ( sub_mod) ,
242
277
}
@@ -247,7 +282,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
247
282
& self ,
248
283
mod_name : symbol:: Ident ,
249
284
attrs : & [ ast:: Attribute ] ,
250
- sub_mod : & Cow < ' ast , ast :: Mod > ,
285
+ sub_mod : & Module < ' ast > ,
251
286
) -> Result < Option < SubModKind < ' c , ' ast > > , ModuleResolutionError > {
252
287
let relative = match self . directory . ownership {
253
288
DirectoryOwnership :: Owned { relative } => relative,
@@ -257,11 +292,15 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
257
292
if self . parse_sess . is_file_parsed ( & path) {
258
293
return Ok ( None ) ;
259
294
}
260
- return match Parser :: parse_file_as_module ( self . parse_sess , & path, sub_mod. inner ) {
295
+ return match Parser :: parse_file_as_module ( self . parse_sess , & path, sub_mod. ast_mod . inner )
296
+ {
261
297
Ok ( m) => Ok ( Some ( SubModKind :: External (
262
298
path,
263
299
DirectoryOwnership :: Owned { relative : None } ,
264
- Cow :: Owned ( m. 0 ) ,
300
+ Module {
301
+ ast_mod : Cow :: Owned ( m. 0 ) ,
302
+ inner_attr : m. 1 ,
303
+ } ,
265
304
) ) ) ,
266
305
Err ( ParserError :: ParseError ) => Err ( ModuleResolutionError {
267
306
module : mod_name. to_string ( ) ,
@@ -299,12 +338,24 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
299
338
return Ok ( Some ( SubModKind :: MultiExternal ( mods_outside_ast) ) ) ;
300
339
}
301
340
}
302
- match Parser :: parse_file_as_module ( self . parse_sess , & path, sub_mod. inner ) {
303
- Ok ( m) if outside_mods_empty => {
304
- Ok ( Some ( SubModKind :: External ( path, ownership, Cow :: Owned ( m. 0 ) ) ) )
305
- }
341
+ match Parser :: parse_file_as_module ( self . parse_sess , & path, sub_mod. ast_mod . inner ) {
342
+ Ok ( m) if outside_mods_empty => Ok ( Some ( SubModKind :: External (
343
+ path,
344
+ ownership,
345
+ Module {
346
+ ast_mod : Cow :: Owned ( m. 0 ) ,
347
+ inner_attr : m. 1 ,
348
+ } ,
349
+ ) ) ) ,
306
350
Ok ( m) => {
307
- mods_outside_ast. push ( ( path. clone ( ) , ownership, Cow :: Owned ( m. 0 ) ) ) ;
351
+ mods_outside_ast. push ( (
352
+ path. clone ( ) ,
353
+ ownership,
354
+ Module {
355
+ ast_mod : Cow :: Owned ( m. 0 ) ,
356
+ inner_attr : m. 1 ,
357
+ } ,
358
+ ) ) ;
308
359
if should_insert {
309
360
mods_outside_ast. push ( ( path, ownership, sub_mod. clone ( ) ) ) ;
310
361
}
@@ -366,8 +417,8 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
366
417
fn find_mods_outside_of_ast (
367
418
& self ,
368
419
attrs : & [ ast:: Attribute ] ,
369
- sub_mod : & Cow < ' ast , ast :: Mod > ,
370
- ) -> Vec < ( PathBuf , DirectoryOwnership , Cow < ' ast , ast :: Mod > ) > {
420
+ sub_mod : & Module < ' ast > ,
421
+ ) -> Vec < ( PathBuf , DirectoryOwnership , Module < ' ast > ) > {
371
422
// Filter nested path, like `#[cfg_attr(feature = "foo", path = "bar.rs")]`.
372
423
let mut path_visitor = visitor:: PathVisitor :: default ( ) ;
373
424
for attr in attrs. iter ( ) {
@@ -394,16 +445,22 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
394
445
continue ;
395
446
}
396
447
397
- let m = match Parser :: parse_file_as_module ( self . parse_sess , & actual_path, sub_mod. inner )
398
- {
448
+ let m = match Parser :: parse_file_as_module (
449
+ self . parse_sess ,
450
+ & actual_path,
451
+ sub_mod. ast_mod . inner ,
452
+ ) {
399
453
Ok ( m) => m,
400
454
Err ( ..) => continue ,
401
455
} ;
402
456
403
457
result. push ( (
404
458
actual_path,
405
459
DirectoryOwnership :: Owned { relative : None } ,
406
- Cow :: Owned ( m. 0 ) ,
460
+ Module {
461
+ ast_mod : Cow :: Owned ( m. 0 ) ,
462
+ inner_attr : m. 1 ,
463
+ } ,
407
464
) )
408
465
}
409
466
result
0 commit comments