Skip to content

Diagnostic improvement of macros #97108

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
frank-king opened this issue May 17, 2022 · 1 comment
Open

Diagnostic improvement of macros #97108

frank-king opened this issue May 17, 2022 · 1 comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@frank-king
Copy link
Contributor

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.

@frank-king frank-king added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels May 17, 2022
@est31
Copy link
Member

est31 commented May 17, 2022

Right now, macro_rules is a macro itself, and also reuses the same logic for parsing macro declarations that normal macro_rules matchers use. That's probably why the errors are so bad. One could think about turning macro_rules into something "properly" parsed, then it can give better errors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

2 participants