@@ -6,6 +6,7 @@ use rustc_ast::ast;
66use rustc_ast:: attr:: HasAttrs ;
77use rustc_ast:: visit:: Visitor ;
88use rustc_span:: symbol:: { self , sym, Symbol } ;
9+ use rustc_span:: Span ;
910use thiserror:: Error ;
1011
1112use crate :: attr:: MetaVisitor ;
@@ -24,20 +25,31 @@ type FileModMap<'ast> = BTreeMap<FileName, Module<'ast>>;
2425/// Represents module with its inner attributes.
2526#[ derive( Debug , Clone ) ]
2627pub ( 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 > > ,
2831 inner_attr : Vec < ast:: Attribute > ,
32+ pub ( crate ) span : Span ,
2933}
3034
3135impl < ' 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
3443 . iter ( )
3544 . filter ( |attr| attr. style == ast:: AttrStyle :: Inner )
3645 . cloned ( )
3746 . collect ( ) ;
3847 Module {
39- ast_mod,
48+ items : mod_items,
49+ attrs : mod_attrs,
4050 inner_attr,
51+ span : mod_span,
52+ ast_mod_kind,
4153 }
4254 }
4355}
@@ -51,12 +63,6 @@ impl<'a> HasAttrs for Module<'a> {
5163 }
5264}
5365
54- impl < ' a > AsRef < ast:: Mod > for Module < ' a > {
55- fn as_ref ( & self ) -> & ast:: Mod {
56- & self . ast_mod
57- }
58- }
59-
6066/// Maps each module to the corresponding file.
6167pub ( crate ) struct ModResolver < ' ast , ' sess > {
6268 parse_sess : & ' sess ParseSess ,
@@ -124,12 +130,17 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
124130
125131 // Skip visiting sub modules when the input is from stdin.
126132 if self . recursive {
127- self . visit_mod_from_ast ( & krate. module ) ?;
133+ self . visit_mod_from_ast ( & krate. items ) ?;
128134 }
129135
130136 self . file_map . insert (
131137 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+ ) ,
133144 ) ;
134145 Ok ( self . file_map )
135146 }
@@ -139,40 +150,69 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
139150 let mut visitor = visitor:: CfgIfVisitor :: new ( self . parse_sess ) ;
140151 visitor. visit_item ( & item) ;
141152 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 {
143154 self . visit_sub_mod (
144155 & 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+ ) ,
146162 ) ?;
147163 }
148164 }
149165 Ok ( ( ) )
150166 }
151167
152168 /// 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 {
155174 if is_cfg_if ( & item) {
156175 self . visit_cfg_if ( Cow :: Owned ( item. into_inner ( ) ) ) ?;
157176 continue ;
158177 }
159178
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+ ) ?;
162190 }
163191 }
164192 Ok ( ( ) )
165193 }
166194
167195 /// 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 {
170201 if is_cfg_if ( item) {
171202 self . visit_cfg_if ( Cow :: Borrowed ( item) ) ?;
172203 }
173204
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+ ) ?;
176216 }
177217 }
178218 Ok ( ( ) )
@@ -273,9 +313,12 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
273313 if let Some ( directory) = directory {
274314 self . directory = directory;
275315 }
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 ( ( ) ) ,
279322 }
280323 }
281324
@@ -294,13 +337,17 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
294337 if self . parse_sess . is_file_parsed ( & path) {
295338 return Ok ( None ) ;
296339 }
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 (
301343 path,
302344 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+ ) ,
304351 ) ) ) ,
305352 Err ( ParserError :: ParseError ) => Err ( ModuleResolutionError {
306353 module : mod_name. to_string ( ) ,
@@ -338,18 +385,30 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
338385 return Ok ( Some ( SubModKind :: MultiExternal ( mods_outside_ast) ) ) ;
339386 }
340387 }
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) ) => {
349403 mods_outside_ast. push ( (
350404 path. clone ( ) ,
351405 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+ ) ,
353412 ) ) ;
354413 if should_insert {
355414 mods_outside_ast. push ( ( path, ownership, sub_mod. clone ( ) ) ) ;
@@ -437,20 +496,22 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
437496 ) ) ;
438497 continue ;
439498 }
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+ } ;
449505
450506 result. push ( (
451507 actual_path,
452508 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+ ) ,
454515 ) )
455516 }
456517 result
0 commit comments