rust-lang / rust-lang/rust

Wrong suggestion with macro returning no expression

Open
#124,585 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-diagnostics T-compiler
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the diagnostic from the macro_rules example in src/main.rs using rustc, starting with the let binding and existing semicolon shown in the issue. Trace the compiler diagnostic path that emits the “add ;” help for a macro expansion, then add regression coverage for this case. Done means the misleading semicolon suggestion is suppressed or replaced when the expansion is used as a let initializer.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.