@@ -556,7 +556,7 @@ impl<'a> Parser<'a> {
556556 recurse_into_file_modules,
557557 directory : Directory {
558558 path : Cow :: from ( PathBuf :: new ( ) ) ,
559- ownership : DirectoryOwnership :: Owned { relative : None }
559+ ownership : DirectoryOwnership :: Owned { relative : vec ! [ ] }
560560 } ,
561561 root_module_name : None ,
562562 expected_tokens : Vec :: new ( ) ,
@@ -6409,8 +6409,12 @@ impl<'a> Parser<'a> {
64096409 }
64106410 } else {
64116411 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+ }
64146418 self . expect ( & token:: OpenDelim ( token:: Brace ) ) ?;
64156419 let mod_inner_lo = self . span ;
64166420 let attrs = self . parse_inner_attributes ( ) ?;
@@ -6421,26 +6425,6 @@ impl<'a> Parser<'a> {
64216425 }
64226426 }
64236427
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-
64446428 pub fn submod_path_from_attr ( attrs : & [ Attribute ] , dir_path : & Path ) -> Option < PathBuf > {
64456429 if let Some ( s) = attr:: first_attr_value_str_by_name ( attrs, "path" ) {
64466430 let s = s. as_str ( ) ;
@@ -6460,21 +6444,20 @@ impl<'a> Parser<'a> {
64606444 /// Returns either a path to a module, or .
64616445 pub fn default_submod_path (
64626446 id : ast:: Ident ,
6463- relative : Option < ast:: Ident > ,
6447+ relative : & [ ast:: Ident ] ,
64646448 dir_path : & Path ,
64656449 source_map : & SourceMap ) -> ModulePath
64666450 {
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+ }
64786461
64796462 let mod_name = id. to_string ( ) ;
64806463 let default_path_str = format ! ( "{}{}.rs" , relative_prefix, mod_name) ;
@@ -6489,14 +6472,14 @@ impl<'a> Parser<'a> {
64896472 ( true , false ) => Ok ( ModulePathSuccess {
64906473 path : default_path,
64916474 directory_ownership : DirectoryOwnership :: Owned {
6492- relative : Some ( id ) ,
6475+ relative : vec ! [ id ] ,
64936476 } ,
64946477 warn : false ,
64956478 } ) ,
64966479 ( false , true ) => Ok ( ModulePathSuccess {
64976480 path : secondary_path,
64986481 directory_ownership : DirectoryOwnership :: Owned {
6499- relative : None ,
6482+ relative : vec ! [ ] ,
65006483 } ,
65016484 warn : false ,
65026485 } ) ,
@@ -6535,27 +6518,18 @@ impl<'a> Parser<'a> {
65356518 // Note that this will produce weirdness when a file named `foo.rs` is
65366519 // `#[path]` included and contains a `mod foo;` declaration.
65376520 // If you encounter this, it's your own darn fault :P
6538- Some ( _) => DirectoryOwnership :: Owned { relative : None } ,
6521+ Some ( _) => DirectoryOwnership :: Owned { relative : vec ! [ ] } ,
65396522 _ => DirectoryOwnership :: UnownedViaMod ( true ) ,
65406523 } ,
65416524 path,
65426525 warn : false ,
65436526 } ) ;
65446527 }
65456528
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,
65576531 DirectoryOwnership :: UnownedViaBlock |
6558- DirectoryOwnership :: UnownedViaMod ( _) => None ,
6532+ DirectoryOwnership :: UnownedViaMod ( _) => & [ ] ,
65596533 } ;
65606534 let paths = Parser :: default_submod_path (
65616535 id, relative, & self . directory . path , self . sess . source_map ( ) ) ;
0 commit comments