Skip to content

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

Closed
@SimonSapin

Description

@SimonSapin
Contributor

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.

Activity

added
A-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)
on Jan 11, 2015
steveklabnik

steveklabnik commented on Jan 4, 2016

@steveklabnik
Member

Triage: I am not aware of any change here. @SimonSapin do you still feel this pain? (and is this RFC-worthy?)

SimonSapin

SimonSapin commented on Jan 5, 2016

@SimonSapin
ContributorAuthor

I’m not very happy with the work-around described above, but it’s hidden away in https://crates.io/crates/matches/ so I don’t think need to about it.

pnkfelix

pnkfelix commented on Jan 5, 2016

@pnkfelix
Member

| has been added to FOLLOW(pat) in RFC amendment rust-lang/rfcs#1384 , so once the associated implementation lands ( #30450 ) this can probably be closed ... I will try to remember to add a specific unit test for it.

pnkfelix

pnkfelix commented on Jan 14, 2016

@pnkfelix
Member

Okay it landed and here's the test: https://github.com/rust-lang/rust/pull/30694/files#diff-b3d1417aaa1fb8f3fa7c449b1f54cbfc

So I'm closing this ticket.

SimonSapin

SimonSapin commented on Jan 18, 2016

@SimonSapin
ContributorAuthor

Confirmed that the original macro in this issue (with $($pattern:pat)|+) now works without the "tt as expr" hack on Nightly. Thanks! (I’ll keep the hack in the crate at least until the fix hits stable.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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

        Participants

        @steveklabnik@pnkfelix@SimonSapin@kmcallister

        Issue actions

          Enable `$($pattern)|+` or equivalent in `macro_rules!` · Issue #20843 · rust-lang/rust