@@ -556,7 +556,7 @@ impl<'a> Parser<'a> {
556
556
recurse_into_file_modules,
557
557
directory : Directory {
558
558
path : Cow :: from ( PathBuf :: new ( ) ) ,
559
- ownership : DirectoryOwnership :: Owned { relative : None }
559
+ ownership : DirectoryOwnership :: Owned { relative : vec ! [ ] }
560
560
} ,
561
561
root_module_name : None ,
562
562
expected_tokens : Vec :: new ( ) ,
@@ -6409,8 +6409,12 @@ impl<'a> Parser<'a> {
6409
6409
}
6410
6410
} else {
6411
6411
let old_directory = self . directory . clone ( ) ;
6412
- self . push_directory ( id, & outer_attrs) ;
6413
-
6412
+ // Push inline `mod x { ... }`'s `x` onto the `relative` offset of the module
6413
+ // from the current directory's location. This ensures that `mod x { mod y; }`
6414
+ // corresponds to `x/y.rs`, not `y.rs`
6415
+ if let DirectoryOwnership :: Owned { relative } = & mut self . directory . ownership {
6416
+ relative. push ( id) ;
6417
+ }
6414
6418
self . expect ( & token:: OpenDelim ( token:: Brace ) ) ?;
6415
6419
let mod_inner_lo = self . span ;
6416
6420
let attrs = self . parse_inner_attributes ( ) ?;
@@ -6421,26 +6425,6 @@ impl<'a> Parser<'a> {
6421
6425
}
6422
6426
}
6423
6427
6424
- fn push_directory ( & mut self , id : Ident , attrs : & [ Attribute ] ) {
6425
- if let Some ( path) = attr:: first_attr_value_str_by_name ( attrs, "path" ) {
6426
- self . directory . path . to_mut ( ) . push ( & path. as_str ( ) ) ;
6427
- self . directory . ownership = DirectoryOwnership :: Owned { relative : None } ;
6428
- } else {
6429
- // We have to push on the current module name in the case of relative
6430
- // paths in order to ensure that any additional module paths from inline
6431
- // `mod x { ... }` come after the relative extension.
6432
- //
6433
- // For example, a `mod z { ... }` inside `x/y.rs` should set the current
6434
- // directory path to `/x/y/z`, not `/x/z` with a relative offset of `y`.
6435
- if let DirectoryOwnership :: Owned { relative } = & mut self . directory . ownership {
6436
- if let Some ( ident) = relative. take ( ) { // remove the relative offset
6437
- self . directory . path . to_mut ( ) . push ( ident. as_str ( ) ) ;
6438
- }
6439
- }
6440
- self . directory . path . to_mut ( ) . push ( & id. as_str ( ) ) ;
6441
- }
6442
- }
6443
-
6444
6428
pub fn submod_path_from_attr ( attrs : & [ Attribute ] , dir_path : & Path ) -> Option < PathBuf > {
6445
6429
if let Some ( s) = attr:: first_attr_value_str_by_name ( attrs, "path" ) {
6446
6430
let s = s. as_str ( ) ;
@@ -6460,21 +6444,20 @@ impl<'a> Parser<'a> {
6460
6444
/// Returns either a path to a module, or .
6461
6445
pub fn default_submod_path (
6462
6446
id : ast:: Ident ,
6463
- relative : Option < ast:: Ident > ,
6447
+ relative : & [ ast:: Ident ] ,
6464
6448
dir_path : & Path ,
6465
6449
source_map : & SourceMap ) -> ModulePath
6466
6450
{
6467
- // If we're in a foo.rs file instead of a mod.rs file,
6468
- // we need to look for submodules in
6469
- // `./foo/<id>.rs` and `./foo/<id>/mod.rs` rather than
6470
- // `./<id>.rs` and `./<id>/mod.rs`.
6471
- let relative_prefix_string;
6472
- let relative_prefix = if let Some ( ident) = relative {
6473
- relative_prefix_string = format ! ( "{}{}" , ident. as_str( ) , path:: MAIN_SEPARATOR ) ;
6474
- & relative_prefix_string
6475
- } else {
6476
- ""
6477
- } ;
6451
+ // Offset the current directory first by the name of
6452
+ // the file if not `mod.rs`, then by any nested modules.
6453
+ // e.g. `mod y { mod z; }` in `x.rs` should look for
6454
+ // `./x/y/z.rs` and `./x/y/z/mod.rs` rather than
6455
+ // `./z.rs` and `./z/mod.rs`.
6456
+ let mut relative_prefix = String :: new ( ) ;
6457
+ for ident in relative {
6458
+ relative_prefix. push_str ( & ident. as_str ( ) ) ;
6459
+ relative_prefix. push ( path:: MAIN_SEPARATOR ) ;
6460
+ }
6478
6461
6479
6462
let mod_name = id. to_string ( ) ;
6480
6463
let default_path_str = format ! ( "{}{}.rs" , relative_prefix, mod_name) ;
@@ -6489,14 +6472,14 @@ impl<'a> Parser<'a> {
6489
6472
( true , false ) => Ok ( ModulePathSuccess {
6490
6473
path : default_path,
6491
6474
directory_ownership : DirectoryOwnership :: Owned {
6492
- relative : Some ( id ) ,
6475
+ relative : vec ! [ id ] ,
6493
6476
} ,
6494
6477
warn : false ,
6495
6478
} ) ,
6496
6479
( false , true ) => Ok ( ModulePathSuccess {
6497
6480
path : secondary_path,
6498
6481
directory_ownership : DirectoryOwnership :: Owned {
6499
- relative : None ,
6482
+ relative : vec ! [ ] ,
6500
6483
} ,
6501
6484
warn : false ,
6502
6485
} ) ,
@@ -6535,27 +6518,18 @@ impl<'a> Parser<'a> {
6535
6518
// Note that this will produce weirdness when a file named `foo.rs` is
6536
6519
// `#[path]` included and contains a `mod foo;` declaration.
6537
6520
// If you encounter this, it's your own darn fault :P
6538
- Some ( _) => DirectoryOwnership :: Owned { relative : None } ,
6521
+ Some ( _) => DirectoryOwnership :: Owned { relative : vec ! [ ] } ,
6539
6522
_ => DirectoryOwnership :: UnownedViaMod ( true ) ,
6540
6523
} ,
6541
6524
path,
6542
6525
warn : false ,
6543
6526
} ) ;
6544
6527
}
6545
6528
6546
- let relative = match self . directory . ownership {
6547
- DirectoryOwnership :: Owned { relative } => {
6548
- // Push the usage onto the list of non-mod.rs mod uses.
6549
- // This is used later for feature-gate error reporting.
6550
- if let Some ( cur_file_ident) = relative {
6551
- self . sess
6552
- . non_modrs_mods . borrow_mut ( )
6553
- . push ( ( cur_file_ident, id_sp) ) ;
6554
- }
6555
- relative
6556
- } ,
6529
+ let relative = match & self . directory . ownership {
6530
+ DirectoryOwnership :: Owned { relative } => & * * relative,
6557
6531
DirectoryOwnership :: UnownedViaBlock |
6558
- DirectoryOwnership :: UnownedViaMod ( _) => None ,
6532
+ DirectoryOwnership :: UnownedViaMod ( _) => & [ ] ,
6559
6533
} ;
6560
6534
let paths = Parser :: default_submod_path (
6561
6535
id, relative, & self . directory . path , self . sess . source_map ( ) ) ;
0 commit comments