Skip to content

Cannot use => inside the body of a macro_rules for defining match arms #113766

Closed
@TapGhoul

Description

@TapGhoul

I tried this code:

enum MyEnum {
    A(i32),
    B(i32),
    C(i32)
}

macro_rules! broken {
    ($n:ident) => { MyEnum::$n(n) => n }
}

fn main() {
    let e = MyEnum::A(1);
    
    match e {
        broken!(A),
        broken!(B),
        broken!(C),
    }
}
Cargo expand output
#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
enum MyEnum {
    A(i32),
    B(i32),
    C(i32),
}
fn main() {
    let e = MyEnum::A(1);
    match e {}
}

I expected to see this happen: It compiles successfully, generating my match arms.

Instead, this happened: Match arms are eaten in macro expansion (according to intellij-rust, as cargo-expand doesn't even show anything) - if I wrap the arm in () within the macro definition (i.e. (a => b)), it works, but this is not a valid match arm.

My understanding is that the macro is getting confused with the pattern:

macro_rules! my_macro {
    () => { () => {} }
}

It appears to see ) => { ( as a pattern

Meta

rustc --version --verbose:

rustc 1.71.0 (8ede3aae2 2023-07-12)
binary: rustc
commit-hash: 8ede3aae28fe6e4d52b38157d7bfe0d3bceef225
commit-date: 2023-07-12
host: x86_64-unknown-linux-gnu
release: 1.71.0
LLVM version: 16.0.5
Backtrace

❯ RUST_BACKTRACE=1 cargo build
   Compiling qwe v0.1.0 (/home/silvea/qwe)
error: unexpected `,` in pattern
  --> src/main.rs:15:19
   |
15 |         broken!(A),
   |                   ^
   |
help: try adding parentheses to match on a tuple...
   |
15 ~         (broken!(A),
16 |         broken!(B),
17 ~         broken!(C),)
   |
help: ...or a vertical bar to match on multiple alternatives
   |
15 ~         broken!(A) |
16 +         broken!(B) |
17 +         broken!(C) |
   |

warning: unused macro definition: `broken`
 --> src/main.rs:7:14
  |
7 | macro_rules! broken {
  |              ^^^^^^
  |
  = note: `#[warn(unused_macros)]` on by default

warning: `qwe` (bin "qwe") generated 1 warning
error: could not compile `qwe` (bin "qwe") due to previous error; 1 warning emitted

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)A-parserArea: The lexing & parsing of Rust source code to an ASTD-terseDiagnostics: An error or lint that doesn't give enough information about the problem at hand.T-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