@@ -3,6 +3,7 @@ use std::collections::BTreeMap;
33use std:: path:: { Path , PathBuf } ;
44
55use rustc_ast:: ast;
6+ use rustc_ast:: attr:: HasAttrs ;
67use rustc_ast:: visit:: Visitor ;
78use rustc_span:: symbol:: { self , sym, Symbol } ;
89use thiserror:: Error ;
@@ -18,12 +19,48 @@ use crate::formatting::{
1819
1920mod visitor;
2021
21- type FileModMap < ' ast > = BTreeMap < FileName , Cow < ' ast , ast :: Mod > > ;
22+ type FileModMap < ' ast > = BTreeMap < FileName , Module < ' ast > > ;
2223
2324lazy_static ! {
2425 static ref CFG_IF : Symbol = Symbol :: intern( "cfg_if" ) ;
2526}
2627
28+ /// Represents module with its inner attributes.
29+ #[ derive( Debug , Clone ) ]
30+ pub ( crate ) struct Module < ' a > {
31+ ast_mod : Cow < ' a , ast:: Mod > ,
32+ inner_attr : Vec < ast:: Attribute > ,
33+ }
34+
35+ impl < ' a > Module < ' a > {
36+ pub ( crate ) fn new ( ast_mod : Cow < ' a , ast:: Mod > , attrs : & [ ast:: Attribute ] ) -> Self {
37+ let inner_attr = attrs
38+ . iter ( )
39+ . filter ( |attr| attr. style == ast:: AttrStyle :: Inner )
40+ . cloned ( )
41+ . collect ( ) ;
42+ Module {
43+ ast_mod,
44+ inner_attr,
45+ }
46+ }
47+ }
48+
49+ impl < ' a > HasAttrs for Module < ' a > {
50+ fn attrs ( & self ) -> & [ ast:: Attribute ] {
51+ & self . inner_attr
52+ }
53+ fn visit_attrs ( & mut self , f : impl FnOnce ( & mut Vec < ast:: Attribute > ) ) {
54+ f ( & mut self . inner_attr )
55+ }
56+ }
57+
58+ impl < ' a > AsRef < ast:: Mod > for Module < ' a > {
59+ fn as_ref ( & self ) -> & ast:: Mod {
60+ & self . ast_mod
61+ }
62+ }
63+
2764/// Maps each module to the corresponding file.
2865pub ( crate ) struct ModResolver < ' ast , ' sess > {
2966 parse_sess : & ' sess ParseSess ,
@@ -53,9 +90,9 @@ pub(crate) enum ModuleResolutionErrorKind {
5390#[ derive( Clone ) ]
5491enum SubModKind < ' a , ' ast > {
5592 /// `mod foo;`
56- External ( PathBuf , DirectoryOwnership , Cow < ' ast , ast :: Mod > ) ,
93+ External ( PathBuf , DirectoryOwnership , Module < ' ast > ) ,
5794 /// `mod foo;` with multiple sources.
58- MultiExternal ( Vec < ( PathBuf , DirectoryOwnership , Cow < ' ast , ast :: Mod > ) > ) ,
95+ MultiExternal ( Vec < ( PathBuf , DirectoryOwnership , Module < ' ast > ) > ) ,
5996 /// `mod foo {}`
6097 Internal ( & ' a ast:: Item ) ,
6198}
@@ -94,8 +131,10 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
94131 self . visit_mod_from_ast ( & krate. module ) ?;
95132 }
96133
97- self . file_map
98- . insert ( root_filename, Cow :: Borrowed ( & krate. module ) ) ;
134+ self . file_map . insert (
135+ root_filename,
136+ Module :: new ( Cow :: Borrowed ( & krate. module ) , & krate. attrs ) ,
137+ ) ;
99138 Ok ( self . file_map )
100139 }
101140
@@ -105,7 +144,10 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
105144 visitor. visit_item ( & item) ;
106145 for module_item in visitor. mods ( ) {
107146 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 ( ) ) ) ?;
147+ self . visit_sub_mod (
148+ & module_item. item ,
149+ Module :: new ( Cow :: Owned ( sub_mod. clone ( ) ) , & module_item. item . attrs ) ,
150+ ) ?;
109151 }
110152 }
111153 Ok ( ( ) )
@@ -120,7 +162,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
120162 }
121163
122164 if let ast:: ItemKind :: Mod ( ref sub_mod) = item. kind {
123- self . visit_sub_mod ( & item, Cow :: Owned ( sub_mod. clone ( ) ) ) ?;
165+ self . visit_sub_mod ( & item, Module :: new ( Cow :: Owned ( sub_mod. clone ( ) ) , & item . attrs ) ) ?;
124166 }
125167 }
126168 Ok ( ( ) )
@@ -134,7 +176,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
134176 }
135177
136178 if let ast:: ItemKind :: Mod ( ref sub_mod) = item. kind {
137- self . visit_sub_mod ( item, Cow :: Borrowed ( sub_mod) ) ?;
179+ self . visit_sub_mod ( item, Module :: new ( Cow :: Borrowed ( sub_mod) , & item . attrs ) ) ?;
138180 }
139181 }
140182 Ok ( ( ) )
@@ -143,12 +185,12 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
143185 fn visit_sub_mod (
144186 & mut self ,
145187 item : & ' c ast:: Item ,
146- sub_mod : Cow < ' ast , ast :: Mod > ,
188+ sub_mod : Module < ' ast > ,
147189 ) -> Result < ( ) , ModuleResolutionError > {
148190 let old_directory = self . directory . clone ( ) ;
149191 let sub_mod_kind = self . peek_sub_mod ( item, & sub_mod) ?;
150192 if let Some ( sub_mod_kind) = sub_mod_kind {
151- self . insert_sub_mod ( sub_mod_kind. clone ( ) , sub_mod . clone ( ) ) ?;
193+ self . insert_sub_mod ( sub_mod_kind. clone ( ) ) ?;
152194 self . visit_sub_mod_inner ( sub_mod, sub_mod_kind) ?;
153195 }
154196 self . directory = old_directory;
@@ -159,7 +201,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
159201 fn peek_sub_mod (
160202 & self ,
161203 item : & ' c ast:: Item ,
162- sub_mod : & Cow < ' ast , ast :: Mod > ,
204+ sub_mod : & Module < ' ast > ,
163205 ) -> Result < Option < SubModKind < ' c , ' ast > > , ModuleResolutionError > {
164206 if contains_skip ( & item. attrs ) {
165207 return Ok ( None ) ;
@@ -178,7 +220,6 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
178220 fn insert_sub_mod (
179221 & mut self ,
180222 sub_mod_kind : SubModKind < ' c , ' ast > ,
181- _sub_mod : Cow < ' ast , ast:: Mod > ,
182223 ) -> Result < ( ) , ModuleResolutionError > {
183224 match sub_mod_kind {
184225 SubModKind :: External ( mod_path, _, sub_mod) => {
@@ -200,7 +241,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
200241
201242 fn visit_sub_mod_inner (
202243 & mut self ,
203- sub_mod : Cow < ' ast , ast :: Mod > ,
244+ sub_mod : Module < ' ast > ,
204245 sub_mod_kind : SubModKind < ' c , ' ast > ,
205246 ) -> Result < ( ) , ModuleResolutionError > {
206247 match sub_mod_kind {
@@ -230,13 +271,13 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
230271
231272 fn visit_sub_mod_after_directory_update (
232273 & mut self ,
233- sub_mod : Cow < ' ast , ast :: Mod > ,
274+ sub_mod : Module < ' ast > ,
234275 directory : Option < Directory > ,
235276 ) -> Result < ( ) , ModuleResolutionError > {
236277 if let Some ( directory) = directory {
237278 self . directory = directory;
238279 }
239- match sub_mod {
280+ match sub_mod. ast_mod {
240281 Cow :: Borrowed ( sub_mod) => self . visit_mod_from_ast ( sub_mod) ,
241282 Cow :: Owned ( sub_mod) => self . visit_mod_outside_ast ( sub_mod) ,
242283 }
@@ -247,7 +288,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
247288 & self ,
248289 mod_name : symbol:: Ident ,
249290 attrs : & [ ast:: Attribute ] ,
250- sub_mod : & Cow < ' ast , ast :: Mod > ,
291+ sub_mod : & Module < ' ast > ,
251292 ) -> Result < Option < SubModKind < ' c , ' ast > > , ModuleResolutionError > {
252293 let relative = match self . directory . ownership {
253294 DirectoryOwnership :: Owned { relative } => relative,
@@ -257,11 +298,12 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
257298 if self . parse_sess . is_file_parsed ( & path) {
258299 return Ok ( None ) ;
259300 }
260- return match Parser :: parse_file_as_module ( self . parse_sess , & path, sub_mod. inner ) {
301+ return match Parser :: parse_file_as_module ( self . parse_sess , & path, sub_mod. ast_mod . inner )
302+ {
261303 Ok ( m) => Ok ( Some ( SubModKind :: External (
262304 path,
263305 DirectoryOwnership :: Owned { relative : None } ,
264- Cow :: Owned ( m) ,
306+ Module :: new ( Cow :: Owned ( m. 0 ) , & m . 1 ) ,
265307 ) ) ) ,
266308 Err ( ParserError :: ParseError ) => Err ( ModuleResolutionError {
267309 module : mod_name. to_string ( ) ,
@@ -299,12 +341,18 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
299341 return Ok ( Some ( SubModKind :: MultiExternal ( mods_outside_ast) ) ) ;
300342 }
301343 }
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) ) ) )
305- }
344+ match Parser :: parse_file_as_module ( self . parse_sess , & path, sub_mod. ast_mod . inner ) {
345+ Ok ( m) if outside_mods_empty => Ok ( Some ( SubModKind :: External (
346+ path,
347+ ownership,
348+ Module :: new ( Cow :: Owned ( m. 0 ) , & m. 1 ) ,
349+ ) ) ) ,
306350 Ok ( m) => {
307- mods_outside_ast. push ( ( path. clone ( ) , ownership, Cow :: Owned ( m) ) ) ;
351+ mods_outside_ast. push ( (
352+ path. clone ( ) ,
353+ ownership,
354+ Module :: new ( Cow :: Owned ( m. 0 ) , & m. 1 ) ,
355+ ) ) ;
308356 if should_insert {
309357 mods_outside_ast. push ( ( path, ownership, sub_mod. clone ( ) ) ) ;
310358 }
@@ -366,8 +414,8 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
366414 fn find_mods_outside_of_ast (
367415 & self ,
368416 attrs : & [ ast:: Attribute ] ,
369- sub_mod : & Cow < ' ast , ast :: Mod > ,
370- ) -> Vec < ( PathBuf , DirectoryOwnership , Cow < ' ast , ast :: Mod > ) > {
417+ sub_mod : & Module < ' ast > ,
418+ ) -> Vec < ( PathBuf , DirectoryOwnership , Module < ' ast > ) > {
371419 // Filter nested path, like `#[cfg_attr(feature = "foo", path = "bar.rs")]`.
372420 let mut path_visitor = visitor:: PathVisitor :: default ( ) ;
373421 for attr in attrs. iter ( ) {
@@ -394,16 +442,19 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
394442 continue ;
395443 }
396444
397- let m = match Parser :: parse_file_as_module ( self . parse_sess , & actual_path, sub_mod. inner )
398- {
445+ let m = match Parser :: parse_file_as_module (
446+ self . parse_sess ,
447+ & actual_path,
448+ sub_mod. ast_mod . inner ,
449+ ) {
399450 Ok ( m) => m,
400451 Err ( ..) => continue ,
401452 } ;
402453
403454 result. push ( (
404455 actual_path,
405456 DirectoryOwnership :: Owned { relative : None } ,
406- Cow :: Owned ( m) ,
457+ Module :: new ( Cow :: Owned ( m. 0 ) , & m . 1 ) ,
407458 ) )
408459 }
409460 result
0 commit comments