Skip to content

Correctly expanded macro_rules! still throws error #82398

@Ofenhed

Description

@Ofenhed

Code

macro_rules! parse {
  ($var:expr => $varname:ident: $type:ty) => {
    let $varname: $type = $var.parse().map_err(|x| std::io::Error::new(std::io::ErrorKind::Other, x))?;
  };
  (($($args:tt)+) $(,)?) => {
    parse!($($args)+)
  };
  (($($args:tt)+), $($rest:tt)+) => {
    parse!($($args)+);
    parse!($($rest)+)
  };
  () => {};
}
fn main() -> std::io::Result<()> {
    let var1 = "50";
    let var2 = "60";
    trace_macros!(true);
    parse!((var1 => newvar1: u8), (var2 => newvar2: u8)); // Doesn't work
    //parse!(var1 => newvar1: u8); // Works
    //parse!(var2 => newvar2: u8); // Works
    println!("{}", newvar1);
    Ok(())
}

Meta

rustc --version --verbose:

rustc 1.50.0 (cb75ad5db 2021-02-10)
binary: rustc
commit-hash: cb75ad5db02783e8b0222fee363c5f63f7e2cf5b
commit-date: 2021-02-10
host: x86_64-unknown-linux-gnu
release: 1.50.0

Also ran in rust playground with versions:

1.50.0
1.52.0-nightly (2021-02-14 5fa22fe6f821ac3801d0)
1.62.0

Error output

   Compiling playground v0.0.1 (/playground)
error[E0658]: use of unstable library feature 'trace_macros': `trace_macros` is not stable enough for use and is subject to change
  --> src/main.rs:17:5
   |
17 |     trace_macros!(true);
   |     ^^^^^^^^^^^^
   |
   = note: see issue #29598 <https://github.com/rust-lang/rust/issues/29598> for more information
   = help: add `#![feature(trace_macros)]` to the crate attributes to enable

error: expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found `=>`
  --> src/main.rs:18:18
   |
18 |     parse!((var1 => newvar1: u8), (var2 => newvar2: u8));
   |                  ^^ expected one of 8 possible tokens

error: expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found `=>`
  --> src/main.rs:18:41
   |
18 |     parse!((var1 => newvar1: u8), (var2 => newvar2: u8));
   |                                         ^^ expected one of 8 possible tokens

note: trace_macro
  --> src/main.rs:21:5
   |
21 |     println!("{}", newvar1);
   |     ^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: expanding `println! { "{}", newvar1 }`
   = note: to `{ $crate :: io :: _print($crate :: format_args_nl ! ("{}", newvar1)) ; }`

note: trace_macro
  --> src/main.rs:18:5
   |
18 |     parse!((var1 => newvar1: u8), (var2 => newvar2: u8));
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: expanding `parse! { (var1 => newvar1 : u8), (var2 => newvar2 : u8) }`
   = note: to `parse ! (var1 => newvar1 : u8) ; parse ! ((var2 => newvar2 : u8))`
   = note: expanding `parse! { var1 => newvar1 : u8 }`
   = note: to `let newvar1 : u8 = var1 . parse() .
           map_err(| x | std :: io :: Error :: new(std :: io :: ErrorKind :: Other, x)) ?
           ;`
   = note: expanding `parse! { (var2 => newvar2 : u8) }`
   = note: to `parse ! (var2 => newvar2 : u8)`
   = note: expanding `parse! { var2 => newvar2 : u8 }`
   = note: to `let newvar2 : u8 = var2 . parse() .
           map_err(| x | std :: io :: Error :: new(std :: io :: ErrorKind :: Other, x)) ?
           ;`

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0658`.
error: could not compile `playground`

To learn more, run the command again with --verbose.

Note that the trace_macros! macro shows the correct output of the macro, yet the compilation fails.

Backtrace

No compiler crash; no additional information.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)C-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions