"Unexpected end of macro invocation" error in nested macro has misleading span, doesn't specify which macro

2ad1054
Opened by Matt Brubeck at 2023-08-03 19:11:41

The following code (based on a test case by @apoelstra):

macro_rules! check_enum {
    ($e:ident, $($var:ident),*) => ({
        $(assert_eq!(0 == $e::$var);)*
    })
}

fn main() {
    check_enum!(Foo, Bar, Baz);
}

generates this error message:

error: unexpected end of macro invocation
 --> test.rs:9:25
9 |>     check_enum!(Foo, Bar, Baz);
  |>                         ^

The problem is that assert_eq! is expecting a comma. This is very hard to decipher though, because the span points to the outer macro invocation. (This may be related to #26615.) If a better span can't be found, it would be useful to at least include the name of the macro in the error message, e.g. "unepected end of assert_eq! invocation."

  1. We now generate this error, which to me is still largely incomprehensible. This is better, though; @mbrubeck Could you provide the "ideal" error message so we can either implement that or as close as possible?

    error: unexpected end of macro invocation
     --> ./test.rs:3:31
      |
    3 |         $(assert_eq!(0 == $e::$var);)*
      |                               ^^^^
    ...
    8 |     check_enum!(Foo, Bar, Baz);
      |     --------------------------- in this macro invocation
    
    
    

    Mark Rousskov at 2017-05-04 12:03:36

  2. Not mbrubeck, but imho the ideal message would expected "," not found with the point where the comma should be highlighted. When I stumbled across this with another macro, the "unexpected end" part made me think I had mismatching brackets.

    konsti at 2018-03-28 22:49:35

  3. Current output:

    error: expected identifier, found `,`
     --> src/main.rs:3:31
      |
    3 |         $(assert_eq!(0 == $e::$var);)*
      |                               ^
      |                               |
      |                               expected identifier
      |                               help: remove this comma
    ...
    8 |     check_enum!(Foo, Bar, Baz);
      |     --------------------------- in this macro invocation
    

    Esteban Kuber at 2019-01-18 22:28:15

  4. error: unexpected end of macro invocation
     --> src/main.rs:3:35
      |
    3 |         $(assert_eq!(0 == $e::$var);)*
      |                                   ^ missing tokens in macro arguments
      |
    note: while trying to match `,`
     --> /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/core/src/macros/mod.rs:37:16
    
    

    Esteban Kuber at 2023-08-03 19:11:41