Why 1 is considered a pattern but 0+1 not

Hey, I'm not sure I fully understand why we can't have "simple" expressions in match clauses. For example,

fn main() {
    let x: usize = 0;
        match x {
            0 => println!("x is zero"),
            1 => println!("x is one"),
            _ => println!("x is neither 0 or 1")
        }
}

Compiles just fine, but if I change it to

fn main() {
    let x: usize = 0;
        match x {
            0 => println!("x is zero"),
            0+1 => println!("x is one"),
            _ => println!("x is neither 0 or 1")
        }
}

Suddenly I get

ERROR!
error: expected a pattern, found an expression
  |
5 |             0+1 => println!("x is one"),
  |             ^^^ not a pattern
  |
  = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>

With two quick solution options - using a match arm guard, or defining a const. Both solution work, but why can't I leave it as-is and let the compiler create the const (at compile time)? Is there a reason why "1" and "0+1" are not considered the same for this case?

Thanks!

0 + 1 is an expression. The evaluation of an expression can be used as a pattern discriminator in a match guard:

match x {
    0 => println!("x is zero"),
    _ if x == 0+1 => println!("x is one"),
    _ => println!("x is neither 0 or 1")
}

See the linked book page in the error message for what constitutes a pattern:

  • Literals
  • Destructured arrays, enums, structs, or tuples
  • Variables
  • Wildcards
  • Placeholders

These items are valid for patterns, expressions are not. I do not know the specific reason for the limitation. It may be syntactic or semantic ambiguity. For instance, how would a pattern like foo + bar be matched? These are two variables that acquire the value being matched.

3 Likes

There is a feature for like it.

2 Likes

Great, I'll add my support for this feature. Thanks!

There is a logic. If an expression can be used as a pattern,

match x { y => 42, _=> 0 }

Would mean if x == y then 42 else 0 which is not the intended semantic of this expression. (Here y should be a new variable set with the x value).