Skip to content

Incorrect trace for Item-level syntax errors in modules included by macro-generated code #66071

@SOF3

Description

@SOF3

Using Rust nightly 2019-11-04.

Consider a macro that generates a mod statement:

#[proc_macro]
pub fn generate(_: proc_macro::TokenStream) -> proc_macro::TokenStream {
    quote::quote!(mod foo;).into()
}

Call this in the src/main.rs in another crate:

codegen::generate!();

fn main() {
    foo::bar();
}

In src/foo.rs, we have the following code:

#{inline}
pub fn bar() {
    println!("Hello world");
}

Note the intentional syntax error #{inline} instead of #[inline] in src/foo.rs.

Compiling this setup (reproducible example in
upload.tar.gz)
with cargo check,
we have the following error message:

error: expected `[`, found `{`
 --> src\main.rs:1:1
  |
1 | codegen::generate!();
  | ^^^^^^^^^^^^^^^^^^^^^

error[E0433]: failed to resolve: use of undeclared type or module `foo`
 --> src\main.rs:4:5
  |
4 |     foo::bar();
  |     ^^^ use of undeclared type or module `foo`

The second error is an indirect consequence of the first error.
But where did the "found {" error message come from?

Obviously, there is nothing wrong with the codegen::generate!() macro
(we can verify this by fixing the intentional syntax error in src/foo.rs).

So let's try manually expanding the macro call, i.e. we now replace src/main.rs:1 with

mod foo;

And we have the following correct error message:

error: expected `[`, found `{`
 --> src\foo.rs:1:2
  |
1 | #{inline}
  |  ^ expected `[`

error: aborting due to previous error

So this error is caused by incorrect error span detection.

I am unable to locate the exact set of syntax errors affected,
because this does not happen with every syntax error.

For example, if I replace src/foo.rs with

#[inline] // correct syntax here
pub fn bar() {
    let a = 1 // missing semicolon here
    println!("Hello world");
}

The resultant error message is correct:

error: expected `;`, found ``println``
 --> src\foo.rs:3:14
  |
3 |     let a = 1
  |              ^ help: add `;` here
4 |     println!("Hello world");
  |     ------- unexpected token

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)C-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions