Leading pipe in `core::matches!()`

Rust allows a leading | in match arms:

match v {
    | 1
    | 2
    | 3 => true,
    _ => false,
}

However, the matches!() macro does not:

matches!(
    v,
    | 1 // Error
    | 2
    | 3
)

Allowing this is simple as changing the macro to:

macro_rules! matches {
    ($expression:expr, $(|)? $( $pattern:pat )|+ $( if $guard: expr )? $(,)?) => { // Added `$(|)?`
        match $expression {
            $( $pattern )|+ $( if $guard )? => true,
            _ => false
        }
    }
}

What do you think?

8 Likes

matches! should be consistent with match, so we should fix that. Please send a PR with that proposed change. Thanks!

3 Likes

This may tie into Rust 2021 changes around the :pattern matcher too, in a crate with edition = "2021" this works:

macro_rules! matches {
    ($expression:expr, $pattern:pat $( if $guard: expr )? $(,)?) => {
        match $expression {
            $pattern $( if $guard )? => true,
            _ => false
        }
    }
}

fn main() {
    dbg!(matches!(1, | 1 | 2 | 3));
}

I think the proposed change under Rust 2018 rules and this example under Rust 2021 rules have the same behaviour, so when core is updated the macro will just have to update to stay the same.

The macro will have to change anyway, either to use pat_param or to remove the repetition.