Macro match the destructured variable

Hi!

I have the following macro

macro_rules! must {
    ($expression:expr, $pattern:pat_param, $e:expr ) => {
        match $expression {
            $pattern => $e,
            _ => panic!("oops"),
        }
    };
}

enum A {
    A(u64),
    B(u64),
}

fn main() {
    let a = A::A(1);
    let d = must!(a, A::A(c), c);
    println!("{}", d);
    // will panic
    let e = must!(a, A::B(b), b);
}

Is there any way to avoid specificing the last argument in the macro? I.e. the $e:expr and have to somehow figure it out from the pattern?

So when I use the macro I don't have write must!(a, A::B(b), b) but just write must(a, A::B(b) instead.

No, it's not possible, but your macro is pretty much what this RFC is about: Proposal for a macro like `matches!()` that maps extracted value to `Option` · Issue #2960 · rust-lang/rfcs · GitHub

Edit:

On a side note. Your macro can be written differently so that you pass the whole expression rather than a pattern, alas:

must!(a, A::B(b) => b);
1 Like

If

let A::A(d) = a else { panic!("oops") };

isn't too complicated for you, you won't need a macro at all :slight_smile:

3 Likes