1
Fork 0

de-fatalize outline module parsing

This commit is contained in:
Mazdak Farrokhzad 2020-03-08 12:19:27 +01:00
parent b9e1b26611
commit 8bab88f2d9
8 changed files with 52 additions and 27 deletions

View file

@ -2153,7 +2153,7 @@ impl FnRetTy {
/// Module declaration. /// Module declaration.
/// ///
/// E.g., `mod foo;` or `mod foo { .. }`. /// E.g., `mod foo;` or `mod foo { .. }`.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Default)]
pub struct Mod { pub struct Mod {
/// A span from the first token past `{` to the last token until `}`. /// A span from the first token past `{` to the last token until `}`.
/// For `mod foo;`, the inner span ranges from the first token /// For `mod foo;`, the inner span ranges from the first token

View file

@ -8,7 +8,7 @@ use rustc_ast::attr;
use rustc_ast::token::{self, TokenKind}; use rustc_ast::token::{self, TokenKind};
use rustc_errors::{struct_span_err, PResult}; use rustc_errors::{struct_span_err, PResult};
use rustc_session::parse::ParseSess; use rustc_session::parse::ParseSess;
use rustc_span::source_map::{FileName, Span, DUMMY_SP}; use rustc_span::source_map::{FileName, Span};
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use std::path::{self, Path, PathBuf}; use std::path::{self, Path, PathBuf};
@ -24,7 +24,7 @@ pub struct ModulePath<'a> {
// Public for rustfmt usage. // Public for rustfmt usage.
pub struct ModulePathSuccess { pub struct ModulePathSuccess {
pub path: PathBuf, pub path: PathBuf,
pub directory_ownership: DirectoryOwnership, pub ownership: DirectoryOwnership,
} }
impl<'a> Parser<'a> { impl<'a> Parser<'a> {
@ -45,16 +45,13 @@ impl<'a> Parser<'a> {
let (module, mut inner_attrs) = if self.eat(&token::Semi) { let (module, mut inner_attrs) = if self.eat(&token::Semi) {
if in_cfg && self.recurse_into_file_modules { if in_cfg && self.recurse_into_file_modules {
// This mod is in an external file. Let's go get it! // This mod is in an external file. Let's go get it!
let ModulePathSuccess { path, directory_ownership } = submod_path( let dir = &self.directory;
self.sess, submod_path(self.sess, id, &attrs, dir.ownership, &dir.path)
id, .and_then(|r| eval_src_mod(self.sess, self.cfg_mods, r.path, r.ownership, id))
&attrs, .map_err(|mut err| err.emit())
self.directory.ownership, .unwrap_or_default()
&self.directory.path,
)?;
eval_src_mod(self.sess, self.cfg_mods, path, directory_ownership, id)?
} else { } else {
(ast::Mod { inner: DUMMY_SP, items: Vec::new(), inline: false }, Vec::new()) Default::default()
} }
} else { } else {
let old_directory = self.directory.clone(); let old_directory = self.directory.clone();
@ -162,12 +159,12 @@ pub fn push_directory(
fn submod_path<'a>( fn submod_path<'a>(
sess: &'a ParseSess, sess: &'a ParseSess,
id: ast::Ident, id: ast::Ident,
outer_attrs: &[Attribute], attrs: &[Attribute],
directory_ownership: DirectoryOwnership, ownership: DirectoryOwnership,
dir_path: &Path, dir_path: &Path,
) -> PResult<'a, ModulePathSuccess> { ) -> PResult<'a, ModulePathSuccess> {
if let Some(path) = submod_path_from_attr(outer_attrs, dir_path) { if let Some(path) = submod_path_from_attr(attrs, dir_path) {
let directory_ownership = match path.file_name().and_then(|s| s.to_str()) { let ownership = match path.file_name().and_then(|s| s.to_str()) {
// All `#[path]` files are treated as though they are a `mod.rs` file. // All `#[path]` files are treated as though they are a `mod.rs` file.
// This means that `mod foo;` declarations inside `#[path]`-included // This means that `mod foo;` declarations inside `#[path]`-included
// files are siblings, // files are siblings,
@ -178,16 +175,16 @@ fn submod_path<'a>(
Some(_) => DirectoryOwnership::Owned { relative: None }, Some(_) => DirectoryOwnership::Owned { relative: None },
_ => DirectoryOwnership::UnownedViaMod, _ => DirectoryOwnership::UnownedViaMod,
}; };
return Ok(ModulePathSuccess { directory_ownership, path }); return Ok(ModulePathSuccess { ownership, path });
} }
let relative = match directory_ownership { let relative = match ownership {
DirectoryOwnership::Owned { relative } => relative, DirectoryOwnership::Owned { relative } => relative,
DirectoryOwnership::UnownedViaBlock | DirectoryOwnership::UnownedViaMod => None, DirectoryOwnership::UnownedViaBlock | DirectoryOwnership::UnownedViaMod => None,
}; };
let ModulePath { path_exists, name, result } = let ModulePath { path_exists, name, result } =
default_submod_path(sess, id, relative, dir_path); default_submod_path(sess, id, relative, dir_path);
match directory_ownership { match ownership {
DirectoryOwnership::Owned { .. } => Ok(result?), DirectoryOwnership::Owned { .. } => Ok(result?),
DirectoryOwnership::UnownedViaBlock => { DirectoryOwnership::UnownedViaBlock => {
let _ = result.map_err(|mut err| err.cancel()); let _ = result.map_err(|mut err| err.cancel());
@ -300,11 +297,11 @@ pub fn default_submod_path<'a>(
let result = match (default_exists, secondary_exists) { let result = match (default_exists, secondary_exists) {
(true, false) => Ok(ModulePathSuccess { (true, false) => Ok(ModulePathSuccess {
path: default_path, path: default_path,
directory_ownership: DirectoryOwnership::Owned { relative: Some(id) }, ownership: DirectoryOwnership::Owned { relative: Some(id) },
}), }),
(false, true) => Ok(ModulePathSuccess { (false, true) => Ok(ModulePathSuccess {
path: secondary_path, path: secondary_path,
directory_ownership: DirectoryOwnership::Owned { relative: None }, ownership: DirectoryOwnership::Owned { relative: None },
}), }),
(false, false) => { (false, false) => {
let mut err = struct_span_err!( let mut err = struct_span_err!(

View file

@ -2,4 +2,5 @@ mod mod_file_disambig_aux; //~ ERROR file for module `mod_file_disambig_aux` fou
fn main() { fn main() {
assert_eq!(mod_file_aux::bar(), 10); assert_eq!(mod_file_aux::bar(), 10);
//~^ ERROR failed to resolve: use of undeclared type or module `mod_file_aux`
} }

View file

@ -6,6 +6,13 @@ LL | mod mod_file_disambig_aux;
| |
= help: delete or rename one of them to remove the ambiguity = help: delete or rename one of them to remove the ambiguity
error: aborting due to previous error error[E0433]: failed to resolve: use of undeclared type or module `mod_file_aux`
--> $DIR/mod_file_disambig.rs:4:16
|
LL | assert_eq!(mod_file_aux::bar(), 10);
| ^^^^^^^^^^^^ use of undeclared type or module `mod_file_aux`
For more information about this error, try `rustc --explain E0584`. error: aborting due to 2 previous errors
Some errors have detailed explanations: E0433, E0584.
For more information about an error, try `rustc --explain E0433`.

View file

@ -6,5 +6,5 @@ pub fn hi_str() -> String {
} }
fn main() { fn main() {
circular_modules_hello::say_hello(); circular_modules_hello::say_hello(); //~ ERROR cannot find function `say_hello` in module
} }

View file

@ -4,5 +4,17 @@ error: circular modules: $DIR/circular_modules_hello.rs -> $DIR/circular_modules
LL | mod circular_modules_hello; LL | mod circular_modules_hello;
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error error[E0425]: cannot find function `say_hello` in module `circular_modules_hello`
--> $DIR/circular_modules_main.rs:9:29
|
LL | circular_modules_hello::say_hello();
| ^^^^^^^^^ not found in `circular_modules_hello`
|
help: possible candidate is found in another module, you can import it into scope
|
LL | use circular_modules_hello::say_hello;
|
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0425`.

View file

@ -5,4 +5,5 @@ mod not_a_real_file; //~ ERROR file not found for module `not_a_real_file`
fn main() { fn main() {
assert_eq!(mod_file_aux::bar(), 10); assert_eq!(mod_file_aux::bar(), 10);
//~^ ERROR failed to resolve: use of undeclared type or module `mod_file_aux`
} }

View file

@ -6,6 +6,13 @@ LL | mod not_a_real_file;
| |
= help: to create the module `not_a_real_file`, create file "$DIR/not_a_real_file.rs" = help: to create the module `not_a_real_file`, create file "$DIR/not_a_real_file.rs"
error: aborting due to previous error error[E0433]: failed to resolve: use of undeclared type or module `mod_file_aux`
--> $DIR/mod_file_not_exist.rs:7:16
|
LL | assert_eq!(mod_file_aux::bar(), 10);
| ^^^^^^^^^^^^ use of undeclared type or module `mod_file_aux`
For more information about this error, try `rustc --explain E0583`. error: aborting due to 2 previous errors
Some errors have detailed explanations: E0433, E0583.
For more information about an error, try `rustc --explain E0433`.