Skip to content

Diagnostic improvement of macros #97108

Open
@frank-king

Description

@frank-king

Given the following code:

macro_rules! m {
    () => {};
    ( $name:ident; ($tt:tt)* ) => {
        m!{ @ $name }
        m!{ $($tt)* }
    };
    (@ $name:ident) => { struct $name; };
}

m! {
    A;
    B;
}

m! { C; }

Playground.

The current output is:

error: no rules expected the token `B`
  --> src/lib.rs:12:5
   |
1  | macro_rules! m {
   | -------------- when calling this macro
...
12 |     B;
   |     ^ no rules expected this token in macro call

error: unexpected end of macro invocation
  --> src/lib.rs:15:8
   |
1  | macro_rules! m {
   | -------------- when calling this macro
...
15 | m! { C; }
   |        ^ missing tokens in macro arguments

error: could not compile `playground` due to 2 previous errors

Ideally the output should look like:

error: no rules expected the token `B`
  --> src/lib.rs:12:5
   |
1  | macro_rules! m {
   | -------------- when calling this macro
...
12 |     B;
   |     ^ no rules expected this token in macro call

note: expected `(` but found `B`.
  --> src/lib.rs:3:20
   |
3  |    ( $name:ident; ($tt:tt)* ) => {
   |                   ^ expected token `(`.
...
12 |     B;
   |     ^ But found `B`.
help: do you mean this?
  --> src/lib.rs:3:20
   |
3  |    ( $name:ident; ($tt:tt)* ) => {
   +                   $($tt:tt)* ) => {
   |                   ^ Add `$` here.


error: unexpected end of macro invocation
  --> src/lib.rs:15:8
   |
1  | macro_rules! m {
   | -------------- when calling this macro
...
15 | m! { C; }
   |        ^ missing tokens in macro arguments

note: missing `(` but found nothing.
  --> src/lib.rs:3:20
   |
3  |    ( $name:ident; ($tt:tt)* ) => {
   |                   ^ expected token `(`.
...
15 | m! { C; }
   |        ^ missing tokens in macro arguments

help: do you mean this?
  --> src/lib.rs:3:20
   |
3  |    ( $name:ident; ($tt:tt)* ) => {
   +                   $($tt:tt)* ) => {
   |                   ^ Add `$` here.
error: could not compile `playground` due to 2 previous errors

The expect error message is written by hand.

The original problem comes from here. It has wasted me a couple of hours to find out the error (a missing $ in the macro rules), so I hope the diagnostic message can be improved, to avoid another one being stuck by this.

If the compiler can not report that I missed a $, I hope at least it can report that the next expected token ( doesn't match the actual arguments.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsT-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