@@ -355,16 +355,17 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
355355 // FIXME: Avoid visiting the crate as a `Mod` item,
356356 // make crate a first class expansion target instead.
357357 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 ( ) ) ,
364361 } ;
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+ } ) ;
368369
369370 let krate_item = AstFragment :: Items ( smallvec ! [ P ( ast:: Item {
370371 attrs: krate. attrs,
@@ -1276,25 +1277,30 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
12761277 } )
12771278 }
12781279 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 {
12861285 ModKind :: Loaded ( _, Inline :: Yes , _) => {
12871286 // Inline `mod foo { ... }`, but we still need to push directories.
1287+ let dir_path = push_directory ( & self . cx . sess , ident, & attrs, dir) ;
12881288 item. attrs = attrs;
1289- push_directory ( & self . cx . sess , ident , & item . attrs , dir )
1289+ ( None , dir_path )
12901290 }
12911291 ModKind :: Loaded ( _, Inline :: No , _) => {
12921292 panic ! ( "`mod` item is loaded from a file for the second time" )
12931293 }
12941294 ModKind :: Unloaded => {
12951295 // 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+ ) ;
12981304
12991305 let krate =
13001306 ast:: Crate { attrs, items, span : inner_span, proc_macros : vec ! [ ] } ;
@@ -1305,34 +1311,29 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
13051311 * mod_kind = ModKind :: Loaded ( krate. items , Inline :: No , inner_span) ;
13061312 item. attrs = krate. attrs ;
13071313 // 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)
13181316 }
13191317 } ;
13201318
13211319 // 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) ;
13241321 module. mod_path . push ( ident) ;
1322+ if let Some ( file_path) = file_path {
1323+ module. file_path_stack . push ( file_path) ;
1324+ }
1325+
13251326 let orig_module =
13261327 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) ;
13271330
13281331 let result = noop_flat_map_item ( item, self ) ;
13291332
13301333 // Restore the module info.
1334+ self . cx . current_expansion . directory_ownership = orig_dir_ownership;
13311335 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+
13361337 result
13371338 }
13381339 _ => {
0 commit comments