@@ -355,16 +355,17 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
355
355
// FIXME: Avoid visiting the crate as a `Mod` item,
356
356
// make crate a first class expansion target instead.
357
357
pub fn expand_crate ( & mut self , mut krate : ast:: Crate ) -> ast:: Crate {
358
- let mut module = ModuleData {
359
- mod_path : vec ! [ Ident :: from_str( & self . cx. ecfg. crate_name) ] ,
360
- directory : match self . cx . source_map ( ) . span_to_unmapped_path ( krate. span ) {
361
- FileName :: Real ( name) => name. into_local_path ( ) ,
362
- other => PathBuf :: from ( other. to_string ( ) ) ,
363
- } ,
358
+ let file_path = match self . cx . source_map ( ) . span_to_unmapped_path ( krate. span ) {
359
+ FileName :: Real ( name) => name. into_local_path ( ) ,
360
+ other => PathBuf :: from ( other. to_string ( ) ) ,
364
361
} ;
365
- module. directory . pop ( ) ;
366
- self . cx . root_path = module. directory . clone ( ) ;
367
- self . cx . current_expansion . module = Rc :: new ( module) ;
362
+ let dir_path = file_path. parent ( ) . unwrap_or ( & file_path) . to_owned ( ) ;
363
+ self . cx . root_path = dir_path. clone ( ) ;
364
+ self . cx . current_expansion . module = Rc :: new ( ModuleData {
365
+ mod_path : vec ! [ Ident :: from_str( & self . cx. ecfg. crate_name) ] ,
366
+ file_path_stack : vec ! [ file_path] ,
367
+ dir_path,
368
+ } ) ;
368
369
369
370
let krate_item = AstFragment :: Items ( smallvec ! [ P ( ast:: Item {
370
371
attrs: krate. attrs,
@@ -1276,25 +1277,30 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1276
1277
} )
1277
1278
}
1278
1279
ast:: ItemKind :: Mod ( _, ref mut mod_kind) if ident != Ident :: invalid ( ) => {
1279
- let sess = & self . cx . sess . parse_sess ;
1280
- let orig_ownership = self . cx . current_expansion . directory_ownership ;
1281
- let mut module = ( * self . cx . current_expansion . module ) . clone ( ) ;
1282
-
1283
- let pushed = & mut false ; // Record `parse_external_mod` pushing so we can pop.
1284
- let dir = Directory { ownership : orig_ownership, path : module. directory } ;
1285
- let Directory { ownership, path } = match mod_kind {
1280
+ let dir = Directory {
1281
+ ownership : self . cx . current_expansion . directory_ownership ,
1282
+ path : self . cx . current_expansion . module . dir_path . clone ( ) ,
1283
+ } ;
1284
+ let ( file_path, Directory { ownership, path } ) = match mod_kind {
1286
1285
ModKind :: Loaded ( _, Inline :: Yes , _) => {
1287
1286
// Inline `mod foo { ... }`, but we still need to push directories.
1287
+ let dir_path = push_directory ( & self . cx . sess , ident, & attrs, dir) ;
1288
1288
item. attrs = attrs;
1289
- push_directory ( & self . cx . sess , ident , & item . attrs , dir )
1289
+ ( None , dir_path )
1290
1290
}
1291
1291
ModKind :: Loaded ( _, Inline :: No , _) => {
1292
1292
panic ! ( "`mod` item is loaded from a file for the second time" )
1293
1293
}
1294
1294
ModKind :: Unloaded => {
1295
1295
// We have an outline `mod foo;` so we need to parse the file.
1296
- let ( items, inner_span, dir) =
1297
- parse_external_mod ( & self . cx . sess , ident, span, dir, & mut attrs, pushed) ;
1296
+ let ( items, inner_span, file_path, dir_path) = parse_external_mod (
1297
+ & self . cx . sess ,
1298
+ ident,
1299
+ span,
1300
+ & self . cx . current_expansion . module . file_path_stack ,
1301
+ dir,
1302
+ & mut attrs,
1303
+ ) ;
1298
1304
1299
1305
let krate =
1300
1306
ast:: Crate { attrs, items, span : inner_span, proc_macros : vec ! [ ] } ;
@@ -1305,34 +1311,29 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
1305
1311
* mod_kind = ModKind :: Loaded ( krate. items , Inline :: No , inner_span) ;
1306
1312
item. attrs = krate. attrs ;
1307
1313
// File can have inline attributes, e.g., `#![cfg(...)]` & co. => Reconfigure.
1308
- item = match self . configure ( item) {
1309
- Some ( node) => node,
1310
- None => {
1311
- if * pushed {
1312
- sess. included_mod_stack . borrow_mut ( ) . pop ( ) ;
1313
- }
1314
- return Default :: default ( ) ;
1315
- }
1316
- } ;
1317
- dir
1314
+ item = configure ! ( self , item) ;
1315
+ ( Some ( file_path) , dir_path)
1318
1316
}
1319
1317
} ;
1320
1318
1321
1319
// Set the module info before we flat map.
1322
- self . cx . current_expansion . directory_ownership = ownership;
1323
- module. directory = path;
1320
+ let mut module = self . cx . current_expansion . module . with_dir_path ( path) ;
1324
1321
module. mod_path . push ( ident) ;
1322
+ if let Some ( file_path) = file_path {
1323
+ module. file_path_stack . push ( file_path) ;
1324
+ }
1325
+
1325
1326
let orig_module =
1326
1327
mem:: replace ( & mut self . cx . current_expansion . module , Rc :: new ( module) ) ;
1328
+ let orig_dir_ownership =
1329
+ mem:: replace ( & mut self . cx . current_expansion . directory_ownership , ownership) ;
1327
1330
1328
1331
let result = noop_flat_map_item ( item, self ) ;
1329
1332
1330
1333
// Restore the module info.
1334
+ self . cx . current_expansion . directory_ownership = orig_dir_ownership;
1331
1335
self . cx . current_expansion . module = orig_module;
1332
- self . cx . current_expansion . directory_ownership = orig_ownership;
1333
- if * pushed {
1334
- sess. included_mod_stack . borrow_mut ( ) . pop ( ) ;
1335
- }
1336
+
1336
1337
result
1337
1338
}
1338
1339
_ => {
0 commit comments