@@ -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 ( ) ,
@@ -6456,8 +6456,12 @@ impl<'a> Parser<'a> {
64566456 }
64576457 } else {
64586458 let old_directory = self . directory . clone ( ) ;
6459- self . push_directory ( id, & outer_attrs) ;
6460-
6459+ // Push inline `mod x { ... }`'s `x` onto the `relative` offset of the module
6460+ // from the current directory's location. This ensures that `mod x { mod y; }`
6461+ // corresponds to `x/y.rs`, not `y.rs`
6462+ if let DirectoryOwnership :: Owned { relative } = & mut self . directory . ownership {
6463+ relative. push ( id) ;
6464+ }
64616465 self . expect ( & token:: OpenDelim ( token:: Brace ) ) ?;
64626466 let mod_inner_lo = self . span ;
64636467 let attrs = self . parse_inner_attributes ( ) ?;
@@ -6468,26 +6472,6 @@ impl<'a> Parser<'a> {
64686472 }
64696473 }
64706474
6471- fn push_directory ( & mut self , id : Ident , attrs : & [ Attribute ] ) {
6472- if let Some ( path) = attr:: first_attr_value_str_by_name ( attrs, "path" ) {
6473- self . directory . path . to_mut ( ) . push ( & path. as_str ( ) ) ;
6474- self . directory . ownership = DirectoryOwnership :: Owned { relative : None } ;
6475- } else {
6476- // We have to push on the current module name in the case of relative
6477- // paths in order to ensure that any additional module paths from inline
6478- // `mod x { ... }` come after the relative extension.
6479- //
6480- // For example, a `mod z { ... }` inside `x/y.rs` should set the current
6481- // directory path to `/x/y/z`, not `/x/z` with a relative offset of `y`.
6482- if let DirectoryOwnership :: Owned { relative } = & mut self . directory . ownership {
6483- if let Some ( ident) = relative. take ( ) { // remove the relative offset
6484- self . directory . path . to_mut ( ) . push ( ident. as_str ( ) ) ;
6485- }
6486- }
6487- self . directory . path . to_mut ( ) . push ( & id. as_str ( ) ) ;
6488- }
6489- }
6490-
64916475 pub fn submod_path_from_attr ( attrs : & [ Attribute ] , dir_path : & Path ) -> Option < PathBuf > {
64926476 if let Some ( s) = attr:: first_attr_value_str_by_name ( attrs, "path" ) {
64936477 let s = s. as_str ( ) ;
@@ -6507,21 +6491,20 @@ impl<'a> Parser<'a> {
65076491 /// Returns either a path to a module, or .
65086492 pub fn default_submod_path (
65096493 id : ast:: Ident ,
6510- relative : Option < ast:: Ident > ,
6494+ relative : & [ ast:: Ident ] ,
65116495 dir_path : & Path ,
65126496 source_map : & SourceMap ) -> ModulePath
65136497 {
6514- // If we're in a foo.rs file instead of a mod.rs file,
6515- // we need to look for submodules in
6516- // `./foo/<id>.rs` and `./foo/<id>/mod.rs` rather than
6517- // `./<id>.rs` and `./<id>/mod.rs`.
6518- let relative_prefix_string;
6519- let relative_prefix = if let Some ( ident) = relative {
6520- relative_prefix_string = format ! ( "{}{}" , ident. as_str( ) , path:: MAIN_SEPARATOR ) ;
6521- & relative_prefix_string
6522- } else {
6523- ""
6524- } ;
6498+ // Offset the current directory first by the name of
6499+ // the file if not `mod.rs`, then by any nested modules.
6500+ // e.g. `mod y { mod z; }` in `x.rs` should look for
6501+ // `./x/y/z.rs` and `./x/y/z/mod.rs` rather than
6502+ // `./z.rs` and `./z/mod.rs`.
6503+ let mut relative_prefix = String :: new ( ) ;
6504+ for ident in relative {
6505+ relative_prefix. push_str ( & ident. as_str ( ) ) ;
6506+ relative_prefix. push ( path:: MAIN_SEPARATOR ) ;
6507+ }
65256508
65266509 let mod_name = id. to_string ( ) ;
65276510 let default_path_str = format ! ( "{}{}.rs" , relative_prefix, mod_name) ;
@@ -6536,14 +6519,14 @@ impl<'a> Parser<'a> {
65366519 ( true , false ) => Ok ( ModulePathSuccess {
65376520 path : default_path,
65386521 directory_ownership : DirectoryOwnership :: Owned {
6539- relative : Some ( id ) ,
6522+ relative : vec ! [ id ] ,
65406523 } ,
65416524 warn : false ,
65426525 } ) ,
65436526 ( false , true ) => Ok ( ModulePathSuccess {
65446527 path : secondary_path,
65456528 directory_ownership : DirectoryOwnership :: Owned {
6546- relative : None ,
6529+ relative : vec ! [ ] ,
65476530 } ,
65486531 warn : false ,
65496532 } ) ,
@@ -6582,27 +6565,18 @@ impl<'a> Parser<'a> {
65826565 // Note that this will produce weirdness when a file named `foo.rs` is
65836566 // `#[path]` included and contains a `mod foo;` declaration.
65846567 // If you encounter this, it's your own darn fault :P
6585- Some ( _) => DirectoryOwnership :: Owned { relative : None } ,
6568+ Some ( _) => DirectoryOwnership :: Owned { relative : vec ! [ ] } ,
65866569 _ => DirectoryOwnership :: UnownedViaMod ( true ) ,
65876570 } ,
65886571 path,
65896572 warn : false ,
65906573 } ) ;
65916574 }
65926575
6593- let relative = match self . directory . ownership {
6594- DirectoryOwnership :: Owned { relative } => {
6595- // Push the usage onto the list of non-mod.rs mod uses.
6596- // This is used later for feature-gate error reporting.
6597- if let Some ( cur_file_ident) = relative {
6598- self . sess
6599- . non_modrs_mods . borrow_mut ( )
6600- . push ( ( cur_file_ident, id_sp) ) ;
6601- }
6602- relative
6603- } ,
6576+ let relative = match & self . directory . ownership {
6577+ DirectoryOwnership :: Owned { relative } => & * * relative,
66046578 DirectoryOwnership :: UnownedViaBlock |
6605- DirectoryOwnership :: UnownedViaMod ( _) => None ,
6579+ DirectoryOwnership :: UnownedViaMod ( _) => & [ ] ,
66066580 } ;
66076581 let paths = Parser :: default_submod_path (
66086582 id, relative, & self . directory . path , self . sess . source_map ( ) ) ;
0 commit comments