tweak outline module parsing spans

This commit is contained in:
Mazdak Farrokhzad 2020-03-09 11:16:00 +01:00
parent 7d0e5bbb67
commit fe71342091
15 changed files with 55 additions and 49 deletions

View File

@ -1429,6 +1429,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
let mut attrs = mem::take(&mut item.attrs); // We do this to please borrowck.
let ident = item.ident;
let span = item.span;
match item.kind {
ast::ItemKind::MacCall(..) => {
@ -1436,10 +1437,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
self.check_attributes(&item.attrs);
item.and_then(|item| match item.kind {
ItemKind::MacCall(mac) => self
.collect(
AstFragmentKind::Items,
InvocationKind::Bang { mac, span: item.span },
)
.collect(AstFragmentKind::Items, InvocationKind::Bang { mac, span })
.make_items(),
_ => unreachable!(),
})
@ -1457,7 +1455,8 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
push_directory(ident, &item.attrs, dir)
} else {
// We have an outline `mod foo;` so we need to parse the file.
let (new_mod, dir) = parse_external_mod(sess, ident, dir, &mut attrs, pushed);
let (new_mod, dir) =
parse_external_mod(sess, ident, span, dir, &mut attrs, pushed);
*old_mod = new_mod;
item.attrs = attrs;
// File can have inline attributes, e.g., `#![cfg(...)]` & co. => Reconfigure.

View File

@ -41,6 +41,7 @@ pub struct ModulePathSuccess {
crate fn parse_external_mod(
sess: &ParseSess,
id: ast::Ident,
span: Span, // The span to blame on errors.
Directory { mut ownership, path }: Directory,
attrs: &mut Vec<Attribute>,
pop_mod_stack: &mut bool,
@ -48,18 +49,18 @@ crate fn parse_external_mod(
// We bail on the first error, but that error does not cause a fatal error... (1)
let result: PResult<'_, _> = try {
// Extract the file path and the new ownership.
let mp = submod_path(sess, id, &attrs, ownership, &path)?;
let mp = submod_path(sess, id, span, &attrs, ownership, &path)?;
ownership = mp.ownership;
// Ensure file paths are acyclic.
let mut included_mod_stack = sess.included_mod_stack.borrow_mut();
error_on_circular_module(sess, id.span, &mp.path, &included_mod_stack)?;
error_on_circular_module(sess, span, &mp.path, &included_mod_stack)?;
included_mod_stack.push(mp.path.clone());
*pop_mod_stack = true; // We have pushed, so notify caller.
drop(included_mod_stack);
// Actually parse the external file as amodule.
let mut p0 = new_sub_parser_from_file(sess, &mp.path, Some(id.to_string()), id.span);
let mut p0 = new_sub_parser_from_file(sess, &mp.path, Some(id.to_string()), span);
let mut module = p0.parse_mod(&token::Eof)?;
module.0.inline = false;
module
@ -126,6 +127,7 @@ crate fn push_directory(
fn submod_path<'a>(
sess: &'a ParseSess,
id: ast::Ident,
span: Span,
attrs: &[Attribute],
ownership: DirectoryOwnership,
dir_path: &Path,
@ -150,54 +152,53 @@ fn submod_path<'a>(
DirectoryOwnership::UnownedViaBlock | DirectoryOwnership::UnownedViaMod => None,
};
let ModulePath { path_exists, name, result } =
default_submod_path(sess, id, relative, dir_path);
default_submod_path(sess, id, span, relative, dir_path);
match ownership {
DirectoryOwnership::Owned { .. } => Ok(result?),
DirectoryOwnership::UnownedViaBlock => {
let _ = result.map_err(|mut err| err.cancel());
error_decl_mod_in_block(sess, id.span, path_exists, &name)
error_decl_mod_in_block(sess, span, path_exists, &name)
}
DirectoryOwnership::UnownedViaMod => {
let _ = result.map_err(|mut err| err.cancel());
error_cannot_declare_mod_here(sess, id.span, path_exists, &name)
error_cannot_declare_mod_here(sess, span, path_exists, &name)
}
}
}
fn error_decl_mod_in_block<'a, T>(
sess: &'a ParseSess,
id_sp: Span,
span: Span,
path_exists: bool,
name: &str,
) -> PResult<'a, T> {
let msg = "Cannot declare a non-inline module inside a block unless it has a path attribute";
let mut err = sess.span_diagnostic.struct_span_err(id_sp, msg);
let mut err = sess.span_diagnostic.struct_span_err(span, msg);
if path_exists {
let msg = format!("Maybe `use` the module `{}` instead of redeclaring it", name);
err.span_note(id_sp, &msg);
err.span_note(span, &msg);
}
Err(err)
}
fn error_cannot_declare_mod_here<'a, T>(
sess: &'a ParseSess,
id_sp: Span,
span: Span,
path_exists: bool,
name: &str,
) -> PResult<'a, T> {
let mut err =
sess.span_diagnostic.struct_span_err(id_sp, "cannot declare a new module at this location");
if !id_sp.is_dummy() {
if let FileName::Real(src_path) = sess.source_map().span_to_filename(id_sp) {
sess.span_diagnostic.struct_span_err(span, "cannot declare a new module at this location");
if !span.is_dummy() {
if let FileName::Real(src_path) = sess.source_map().span_to_filename(span) {
if let Some(stem) = src_path.file_stem() {
let mut dest_path = src_path.clone();
dest_path.set_file_name(stem);
dest_path.push("mod.rs");
err.span_note(
id_sp,
span,
&format!(
"maybe move this module `{}` to its own \
directory via `{}`",
"maybe move this module `{}` to its own directory via `{}`",
src_path.display(),
dest_path.display()
),
@ -207,7 +208,7 @@ fn error_cannot_declare_mod_here<'a, T>(
}
if path_exists {
err.span_note(
id_sp,
span,
&format!("... or maybe `use` the module `{}` instead of possibly redeclaring it", name),
);
}
@ -237,6 +238,7 @@ pub fn submod_path_from_attr(attrs: &[Attribute], dir_path: &Path) -> Option<Pat
pub fn default_submod_path<'a>(
sess: &'a ParseSess,
id: ast::Ident,
span: Span,
relative: Option<ast::Ident>,
dir_path: &Path,
) -> ModulePath<'a> {
@ -273,7 +275,7 @@ pub fn default_submod_path<'a>(
(false, false) => {
let mut err = struct_span_err!(
sess.span_diagnostic,
id.span,
span,
E0583,
"file not found for module `{}`",
mod_name,
@ -288,7 +290,7 @@ pub fn default_submod_path<'a>(
(true, true) => {
let mut err = struct_span_err!(
sess.span_diagnostic,
id.span,
span,
E0584,
"file for module `{}` found at both {} and {}",
mod_name,

View File

@ -38,7 +38,7 @@ impl<'a> Parser<'a> {
}
/// Parses a `mod <foo> { ... }` or `mod <foo>;` item.
pub(super) fn parse_item_mod(&mut self, attrs: &mut Vec<Attribute>) -> PResult<'a, ItemInfo> {
fn parse_item_mod(&mut self, attrs: &mut Vec<Attribute>) -> PResult<'a, ItemInfo> {
let id = self.parse_ident()?;
let (module, mut inner_attrs) = if self.eat(&token::Semi) {
Default::default()

View File

@ -2,7 +2,7 @@
macro_rules! mod_decl {
($i:ident) => {
mod $i;
mod $i; //~ ERROR Cannot declare a non-inline module inside a block
};
}
@ -11,5 +11,5 @@ mod macro_expanded_mod_helper {
}
fn main() {
mod_decl!(foo); //~ ERROR Cannot declare a non-inline module inside a block
mod_decl!(foo);
}

View File

@ -1,8 +1,13 @@
error: Cannot declare a non-inline module inside a block unless it has a path attribute
--> $DIR/macro-expanded-mod.rs:14:15
--> $DIR/macro-expanded-mod.rs:5:9
|
LL | mod $i;
| ^^^^^^^
...
LL | mod_decl!(foo);
| ^^^
| --------------- in this macro invocation
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error

View File

@ -1,8 +1,8 @@
error: Cannot declare a non-inline module inside a block unless it has a path attribute
--> $DIR/non-inline-mod-restriction.rs:4:9
--> $DIR/non-inline-mod-restriction.rs:4:5
|
LL | mod foo;
| ^^^
| ^^^^^^^^
error: aborting due to previous error

View File

@ -1,8 +1,8 @@
error[E0583]: file not found for module `module_that_doesnt_exist`
--> $DIR/E0583.rs:1:5
--> $DIR/E0583.rs:1:1
|
LL | mod module_that_doesnt_exist;
| ^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: to create the module `module_that_doesnt_exist`, create file "$DIR/module_that_doesnt_exist.rs"

View File

@ -1,8 +1,8 @@
error[E0583]: file not found for module `baz`
--> $DIR/auxiliary/foo/bar.rs:1:9
--> $DIR/auxiliary/foo/bar.rs:1:1
|
LL | pub mod baz;
| ^^^
| ^^^^^^^^^^^^
|
= help: to create the module `baz`, create file "$DIR/auxiliary/foo/bar/baz.rs"

View File

@ -1,8 +1,8 @@
error[E0583]: file not found for module `missing`
--> $DIR/foo.rs:4:5
--> $DIR/foo.rs:4:1
|
LL | mod missing;
| ^^^^^^^
| ^^^^^^^^^^^^
|
= help: to create the module `missing`, create file "$DIR/foo/missing.rs"

View File

@ -1,8 +1,8 @@
error[E0583]: file not found for module `missing`
--> $DIR/foo_inline.rs:4:9
--> $DIR/foo_inline.rs:4:5
|
LL | mod missing;
| ^^^^^^^
| ^^^^^^^^^^^^
|
= help: to create the module `missing`, create file "$DIR/foo_inline/inline/missing.rs"

View File

@ -1,8 +1,8 @@
error[E0584]: file for module `mod_file_disambig_aux` found at both mod_file_disambig_aux.rs and mod_file_disambig_aux/mod.rs
--> $DIR/mod_file_disambig.rs:1:5
--> $DIR/mod_file_disambig.rs:1:1
|
LL | mod mod_file_disambig_aux;
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: delete or rename one of them to remove the ambiguity

View File

@ -1,8 +1,8 @@
error: circular modules: $DIR/circular_modules_hello.rs -> $DIR/circular_modules_main.rs -> $DIR/circular_modules_hello.rs
--> $DIR/circular_modules_main.rs:2:5
--> $DIR/circular_modules_main.rs:2:1
|
LL | mod circular_modules_hello;
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0425]: cannot find function `say_hello` in module `circular_modules_hello`
--> $DIR/circular_modules_main.rs:9:29

View File

@ -1,8 +1,8 @@
error: couldn't read $DIR/../parser: $ACCESS_DENIED_MSG (os error $ACCESS_DENIED_CODE)
--> $DIR/issue-5806.rs:5:5
--> $DIR/issue-5806.rs:5:1
|
LL | mod foo;
| ^^^
| ^^^^^^^^
error: aborting due to previous error

View File

@ -1,8 +1,8 @@
error[E0583]: file not found for module `not_a_real_file`
--> $DIR/mod_file_not_exist.rs:3:5
--> $DIR/mod_file_not_exist.rs:3:1
|
LL | mod not_a_real_file;
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^
|
= help: to create the module `not_a_real_file`, create file "$DIR/not_a_real_file.rs"

View File

@ -1,8 +1,8 @@
error: couldn't read $DIR/not_a_real_file.rs: $FILE_NOT_FOUND_MSG (os error 2)
--> $DIR/mod_file_with_path_attr.rs:4:5
--> $DIR/mod_file_with_path_attr.rs:4:1
|
LL | mod m;
| ^
| ^^^^^^
error: aborting due to previous error