Skip to content

Enable $($pattern)|+ or equivalent in macro_rules! #20843

Closed
@SimonSapin

Description

@SimonSapin

I use this macro a lot:

macro_rules! is_match {
    ($value:expr, $($pattern:pat)|+) => {
        match $value {
            $($pattern)|+ => true,
            _ => false
        }
    }
}

But today’s Nightly broke it (#20563 (comment)) with apparently no fix that don’t involve changing the usage syntax.

error: `$pattern:pat` is followed by `|`, which is not allowed for `pat` 

A work around (that I’m going to use) is to use tt:

#[macro_export]
macro_rules! matches {
    ($expression: expr, $($pattern:tt)+) => {
        _tt_as_expr_hack! {
            match $expression {
                $($pattern)+ => true,
                _ => false
            }
        }
    }
}

/// Work around "error: unexpected token: `an interpolated tt`", whatever that means.
#[macro_export]
macro_rules! _tt_as_expr_hack {
    ($value:expr) => ($value)
}

But it’s not great since it allows sneaking another match arm into the macro expansion:

fn foo(arg: &str, flux: i32) {
    matches!(arg, "bar" | "baz" => flux> 9000, "fuzz");
}

Therefore, I think think that something like the original macro should be possible to write.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions