Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
SimonSapin opened this issue Jan 10, 2015 · 5 comments
Closed

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

SimonSapin opened this issue Jan 10, 2015 · 5 comments
Labels
A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..)

Comments

@SimonSapin
Copy link
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.

@kmcallister kmcallister added the A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) label Jan 11, 2015
@steveklabnik
Copy link
Member

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

@SimonSapin
Copy link
Contributor Author

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
Copy link
Member

pnkfelix commented Jan 5, 2016

| 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
Copy link
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
Copy link
Contributor Author

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
Labels
A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..)
Projects
None yet
Development

No branches or pull requests

4 participants