Skip to content

Wrong suggestion with macro returning no expression #124585

Open
@jfrimmel

Description

@jfrimmel

Code

// https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=aa236bae17b94446cb3d4cfd5fa13c5b

macro_rules! m {
    () => {};
}

fn main() {
    let _ = m![];
}

Current output

error: macro expansion ends with an incomplete expression: expected expression
 --> src/main.rs:6:13
  |
2 |     () => {};
  |           -- in this macro arm
...
6 |     let _ = m![];
  |             ^^^^ expected expression
  |
  = note: the macro call doesn't expand to an expression, but it can expand to a statement
help: add `;` to interpret the expansion as a statement
  |
6 |     let _ = m![];;
  |                 +

Desired output

error: macro expansion ends with an incomplete expression: expected expression
 --> src/main.rs:6:13
  |
2 |     () => {};
  |           -- in this macro arm
...
6 |     let _ = m![];
  |             ^^^^ expected expression
  |
  = note: the macro call doesn't expand to an expression, but it can expand to a statement
help: return an expression from the macro expansion
  |
2 |     () => { /* expression */ };
  |           ~++++++++++++++++++~

Rationale and extra context

The current suggestion adds a semicolon before the existing semicolon, which should at least be detected and, in that case, the current help:-line should be suppressed. One could add a specialized help-suggestion as in the desired output above, but that's not really that relevant. So:
if there is a macro assigned to a let, I would alter the existing suggestion as mentioned above.

Other cases

Suggestion if there is a missing semicolon Interestingly, the suggestion is kind of correct, if the code is invalid (missing semicolon):
macro_rules! m {
    () => {};
}

fn main() {
    let _ = m![]
}

But even then, the actual suggestion is not that helpful:

error: expected `;`, found `}`
 --> src/main.rs:6:17
  |
6 |     let _ = m![]
  |                 ^ help: add `;` here
7 | }
  | - unexpected token

error: macro expansion ends with an incomplete expression: expected expression
 --> src/main.rs:6:13
  |
2 |     () => {};
  |           -- in this macro arm
...
6 |     let _ = m![]
  |             ^^^^ expected expression
  |
  = note: the macro call doesn't expand to an expression, but it can expand to a statement
help: add `;` to interpret the expansion as a statement
  |
6 |     let _ = m![];
  |                 +

Rust Version

$ rustc --version --verbose
rustc 1.77.2 (25ef9e3d8 2024-04-09)
binary: rustc
commit-hash: 25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04
commit-date: 2024-04-09
host: x86_64-unknown-linux-gnu
release: 1.77.2
LLVM version: 17.0.6

Anything else?

No response

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