@@ -18,12 +18,25 @@ use crate::formatting::{
1818
1919mod visitor;
2020
21- type FileModMap < ' ast > = BTreeMap < FileName , Cow < ' ast , ast :: Mod > > ;
21+ type FileModMap < ' ast > = BTreeMap < FileName , Module < ' ast > > ;
2222
2323lazy_static ! {
2424 static ref CFG_IF : Symbol = Symbol :: intern( "cfg_if" ) ;
2525}
2626
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+
2740/// Maps each module to the corresponding file.
2841pub ( crate ) struct ModResolver < ' ast , ' sess > {
2942 parse_sess : & ' sess ParseSess ,
@@ -53,9 +66,9 @@ pub(crate) enum ModuleResolutionErrorKind {
5366#[ derive( Clone ) ]
5467enum SubModKind < ' a , ' ast > {
5568 /// `mod foo;`
56- External ( PathBuf , DirectoryOwnership , Cow < ' ast , ast :: Mod > ) ,
69+ External ( PathBuf , DirectoryOwnership , Module < ' ast > ) ,
5770 /// `mod foo;` with multiple sources.
58- MultiExternal ( Vec < ( PathBuf , DirectoryOwnership , Cow < ' ast , ast :: Mod > ) > ) ,
71+ MultiExternal ( Vec < ( PathBuf , DirectoryOwnership , Module < ' ast > ) > ) ,
5972 /// `mod foo {}`
6073 Internal ( & ' a ast:: Item ) ,
6174}
@@ -94,8 +107,13 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
94107 self . visit_mod_from_ast ( & krate. module ) ?;
95108 }
96109
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+ ) ;
99117 Ok ( self . file_map )
100118 }
101119
@@ -105,7 +123,13 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
105123 visitor. visit_item ( & item) ;
106124 for module_item in visitor. mods ( ) {
107125 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+ ) ?;
109133 }
110134 }
111135 Ok ( ( ) )
@@ -120,7 +144,13 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
120144 }
121145
122146 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+ ) ?;
124154 }
125155 }
126156 Ok ( ( ) )
@@ -134,7 +164,13 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
134164 }
135165
136166 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+ ) ?;
138174 }
139175 }
140176 Ok ( ( ) )
@@ -143,12 +179,12 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
143179 fn visit_sub_mod (
144180 & mut self ,
145181 item : & ' c ast:: Item ,
146- sub_mod : Cow < ' ast , ast :: Mod > ,
182+ sub_mod : Module < ' ast > ,
147183 ) -> Result < ( ) , ModuleResolutionError > {
148184 let old_directory = self . directory . clone ( ) ;
149185 let sub_mod_kind = self . peek_sub_mod ( item, & sub_mod) ?;
150186 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 ( ) ) ?;
152188 self . visit_sub_mod_inner ( sub_mod, sub_mod_kind) ?;
153189 }
154190 self . directory = old_directory;
@@ -159,7 +195,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
159195 fn peek_sub_mod (
160196 & self ,
161197 item : & ' c ast:: Item ,
162- sub_mod : & Cow < ' ast , ast :: Mod > ,
198+ sub_mod : & Module < ' ast > ,
163199 ) -> Result < Option < SubModKind < ' c , ' ast > > , ModuleResolutionError > {
164200 if contains_skip ( & item. attrs ) {
165201 return Ok ( None ) ;
@@ -178,7 +214,6 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
178214 fn insert_sub_mod (
179215 & mut self ,
180216 sub_mod_kind : SubModKind < ' c , ' ast > ,
181- _sub_mod : Cow < ' ast , ast:: Mod > ,
182217 ) -> Result < ( ) , ModuleResolutionError > {
183218 match sub_mod_kind {
184219 SubModKind :: External ( mod_path, _, sub_mod) => {
@@ -200,7 +235,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
200235
201236 fn visit_sub_mod_inner (
202237 & mut self ,
203- sub_mod : Cow < ' ast , ast :: Mod > ,
238+ sub_mod : Module < ' ast > ,
204239 sub_mod_kind : SubModKind < ' c , ' ast > ,
205240 ) -> Result < ( ) , ModuleResolutionError > {
206241 match sub_mod_kind {
@@ -230,13 +265,13 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
230265
231266 fn visit_sub_mod_after_directory_update (
232267 & mut self ,
233- sub_mod : Cow < ' ast , ast :: Mod > ,
268+ sub_mod : Module < ' ast > ,
234269 directory : Option < Directory > ,
235270 ) -> Result < ( ) , ModuleResolutionError > {
236271 if let Some ( directory) = directory {
237272 self . directory = directory;
238273 }
239- match sub_mod {
274+ match sub_mod. ast_mod {
240275 Cow :: Borrowed ( sub_mod) => self . visit_mod_from_ast ( sub_mod) ,
241276 Cow :: Owned ( sub_mod) => self . visit_mod_outside_ast ( sub_mod) ,
242277 }
@@ -247,7 +282,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
247282 & self ,
248283 mod_name : symbol:: Ident ,
249284 attrs : & [ ast:: Attribute ] ,
250- sub_mod : & Cow < ' ast , ast :: Mod > ,
285+ sub_mod : & Module < ' ast > ,
251286 ) -> Result < Option < SubModKind < ' c , ' ast > > , ModuleResolutionError > {
252287 let relative = match self . directory . ownership {
253288 DirectoryOwnership :: Owned { relative } => relative,
@@ -257,11 +292,15 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
257292 if self . parse_sess . is_file_parsed ( & path) {
258293 return Ok ( None ) ;
259294 }
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+ {
261297 Ok ( m) => Ok ( Some ( SubModKind :: External (
262298 path,
263299 DirectoryOwnership :: Owned { relative : None } ,
264- Cow :: Owned ( m. 0 ) ,
300+ Module {
301+ ast_mod : Cow :: Owned ( m. 0 ) ,
302+ inner_attr : m. 1 ,
303+ } ,
265304 ) ) ) ,
266305 Err ( ParserError :: ParseError ) => Err ( ModuleResolutionError {
267306 module : mod_name. to_string ( ) ,
@@ -299,12 +338,24 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
299338 return Ok ( Some ( SubModKind :: MultiExternal ( mods_outside_ast) ) ) ;
300339 }
301340 }
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+ ) ) ) ,
306350 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+ ) ) ;
308359 if should_insert {
309360 mods_outside_ast. push ( ( path, ownership, sub_mod. clone ( ) ) ) ;
310361 }
@@ -366,8 +417,8 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
366417 fn find_mods_outside_of_ast (
367418 & self ,
368419 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 > ) > {
371422 // Filter nested path, like `#[cfg_attr(feature = "foo", path = "bar.rs")]`.
372423 let mut path_visitor = visitor:: PathVisitor :: default ( ) ;
373424 for attr in attrs. iter ( ) {
@@ -394,16 +445,22 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
394445 continue ;
395446 }
396447
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+ ) {
399453 Ok ( m) => m,
400454 Err ( ..) => continue ,
401455 } ;
402456
403457 result. push ( (
404458 actual_path,
405459 DirectoryOwnership :: Owned { relative : None } ,
406- Cow :: Owned ( m. 0 ) ,
460+ Module {
461+ ast_mod : Cow :: Owned ( m. 0 ) ,
462+ inner_attr : m. 1 ,
463+ } ,
407464 ) )
408465 }
409466 result
0 commit comments