X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=compiler%2Frustc_expand%2Fsrc%2Fmodule.rs;h=993522d01d86744bec64592c31f698d58a0e7ae2;hb=461f52071d8065dbb7c57189e181dc1f72e8b10f;hp=2ec656d4895e7f0d960741bdf49cc6c934dc9a51;hpb=ec487bf3cfc9ce386da25169509fae8f2b4d4eec;p=rust.git diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs index 2ec656d4895..993522d01d8 100644 --- a/compiler/rustc_expand/src/module.rs +++ b/compiler/rustc_expand/src/module.rs @@ -1,6 +1,6 @@ use crate::base::ModuleData; use rustc_ast::ptr::P; -use rustc_ast::{token, Attribute, Item}; +use rustc_ast::{token, Attribute, Inline, Item}; use rustc_errors::{struct_span_err, DiagnosticBuilder}; use rustc_parse::new_parser_from_file; use rustc_session::parse::ParseSess; @@ -37,7 +37,7 @@ pub enum ModError<'a> { CircularInclusion(Vec), ModInBlock(Option), FileNotFound(Ident, PathBuf), - MultipleCandidates(Ident, String, String), + MultipleCandidates(Ident, PathBuf, PathBuf), ParserError(DiagnosticBuilder<'a>), } @@ -83,29 +83,49 @@ pub enum ModError<'a> { attrs: &[Attribute], module: &ModuleData, mut dir_ownership: DirOwnership, + inline: Inline, ) -> (PathBuf, DirOwnership) { - if let Some(file_path) = mod_file_path_from_attr(sess, attrs, &module.dir_path) { - // For inline modules file path from `#[path]` is actually the directory path - // for historical reasons, so we don't pop the last segment here. - return (file_path, DirOwnership::Owned { relative: None }); - } + match inline { + Inline::Yes => { + if let Some(file_path) = mod_file_path_from_attr(sess, attrs, &module.dir_path) { + // For inline modules file path from `#[path]` is actually the directory path + // for historical reasons, so we don't pop the last segment here. + return (file_path, DirOwnership::Owned { relative: None }); + } - // We have to push on the current module name in the case of relative - // paths in order to ensure that any additional module paths from inline - // `mod x { ... }` come after the relative extension. - // - // For example, a `mod z { ... }` inside `x/y.rs` should set the current - // directory path to `/x/y/z`, not `/x/z` with a relative offset of `y`. - let mut dir_path = module.dir_path.clone(); - if let DirOwnership::Owned { relative } = &mut dir_ownership { - if let Some(ident) = relative.take() { - // Remove the relative offset. + // We have to push on the current module name in the case of relative + // paths in order to ensure that any additional module paths from inline + // `mod x { ... }` come after the relative extension. + // + // For example, a `mod z { ... }` inside `x/y.rs` should set the current + // directory path to `/x/y/z`, not `/x/z` with a relative offset of `y`. + let mut dir_path = module.dir_path.clone(); + if let DirOwnership::Owned { relative } = &mut dir_ownership { + if let Some(ident) = relative.take() { + // Remove the relative offset. + dir_path.push(&*ident.as_str()); + } + } dir_path.push(&*ident.as_str()); + + (dir_path, dir_ownership) } - } - dir_path.push(&*ident.as_str()); + Inline::No => { + // FIXME: This is a subset of `parse_external_mod` without actual parsing, + // check whether the logic for unloaded, loaded and inline modules can be unified. + let file_path = mod_file_path(sess, ident, &attrs, &module.dir_path, dir_ownership) + .map(|mp| { + dir_ownership = mp.dir_ownership; + mp.file_path + }) + .unwrap_or_default(); - (dir_path, dir_ownership) + // Extract the directory path for submodules of the module. + let dir_path = file_path.parent().unwrap_or(&file_path).to_owned(); + + (dir_path, dir_ownership) + } + } } fn mod_file_path<'a>( @@ -200,9 +220,7 @@ pub fn default_submod_path<'a>( dir_ownership: DirOwnership::Owned { relative: None }, }), (false, false) => Err(ModError::FileNotFound(ident, default_path)), - (true, true) => { - Err(ModError::MultipleCandidates(ident, default_path_str, secondary_path_str)) - } + (true, true) => Err(ModError::MultipleCandidates(ident, default_path, secondary_path)), } } @@ -244,15 +262,15 @@ fn report(self, sess: &Session, span: Span) { )); err } - ModError::MultipleCandidates(ident, default_path_short, secondary_path_short) => { + ModError::MultipleCandidates(ident, default_path, secondary_path) => { let mut err = struct_span_err!( diag, span, E0761, - "file for module `{}` found at both {} and {}", + "file for module `{}` found at both \"{}\" and \"{}\"", ident, - default_path_short, - secondary_path_short, + default_path.display(), + secondary_path.display(), ); err.help("delete or rename one of them to remove the ambiguity"); err