rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.61k stars 12.74k forks source link

bad diagnostic when macro tries to use stmt as expr #30597

Open durka opened 8 years ago

durka commented 8 years ago

Given this macro:

macro_rules! foo {
    ($s:stmt) => { $s }
}

When called in expression context, for example println!("{}", foo!(42)), the error message refers to "unexpected token 42;", thereby conjuring a semicolon out of the ether. We aren't JS so we shouldn't conjure semicolons out of the ether :)

GuillaumeGomez commented 8 years ago

So if we follow the trace; https://github.com/rust-lang/rust/blob/master/src/libsyntax/parse/parser.rs#L398 https://github.com/rust-lang/rust/blob/master/src/libsyntax/parse/parser.rs#L387 https://github.com/rust-lang/rust/blob/master/src/libsyntax/print/pprust.rs#L249

I think the "error" comes from these lines.

durka commented 8 years ago

@GuillaumeGomez Hmm, I guess it must be that the "statement" 42 ends up as essentially Literal(Integer(42), Some(intern(";")))?

Mark-Simulacrum commented 7 years ago

So we still produce a semicolon, but the error is much better (though still far from ideal):

error: expected expression, found `42;`
 --> test.rs:2:20
  |
2 |     ($s:stmt) => { $s }
  |                    ^^ expected expression
...
6 |     println!("{}", foo!(42));
  |                    -------- in this macro invocation
estebank commented 2 years ago

The current output provides an incorrect suggestion:

error: expected expression, found `42;`
 --> src/main.rs:2:20
  |
2 |     ($s:stmt) => { $s }
  |                    ^^ expected expression
...
6 |     println!("{}", foo!(42));
  |                    -------- in this macro invocation
  |
  = note: the macro call doesn't expand to an expression, but it can expand to a statement
  = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `;` to interpret the expansion as a statement
  |
6 |     println!("{}", foo!(42););
  |                            +
estebank commented 1 year ago

Triage: no change.