One year later the situation has improved, Varkor and others have implemented the exhaustive integer patterns, usable in the last Nightly:
The implementation of #50912 was kind of exhausting, with 160+ messages and a lot of patience
It allows to write code like this, without the catch-all “_”:
#![feature(exclusive_range_pattern, exhaustive_integer_patterns)]
fn matcher1(x: u8) {
match x {
0 .. 32 => {},
32 => {},
33 ..= 255 => {},
}
}
Currently Rustc allows overlapping arms, like this:
fn matcher2(x: u8) {
match x {
0 .. 50 => {},
32 .. 60 => {},
33 ..= 255 => {},
}
}
You need the “match_overlapping_arm” default-warn Clippy lint to catch that possible mistake:
https://rust-lang-nursery.github.io/rust-clippy/master/index.html#match_overlapping_arm
Currently the type system is not able to handle code like this in a better way:
fn foo1(x: u32) {
match x % 3 {
0 => {},
1 => {},
_ => {},
}
}
But I think that it’s possible to extend Varkor work with a expression value-range analysis to allow code like:
fn foo2(x: u32) {
match x % 3 {
0 => {},
1 => {},
2 => {},
}
}
While supporting code like this could be left for later:
#![feature(euclidean_division)]
fn foo3(x: i32) {
match x.mod_euc(2) {
0 => {},
1 => {},
}
}
Lately some persons have suggested that ranged integrals could be added to Rust as library types (or even as a crate) once the Const Generics are implemented (worked on by Varkor again: https://github.com/rust-lang/rust/pull/53645 ). But I kind of think ranged integrals should be a language feature, because part of their value comes from their synergetic integration with several other language features (partially inspired by Ada features):
type Month = u8[1 ..= 12];
const DEC: Month = 12;
fn foo4() {
for d in Month::INF ..= Month::SUP {
match m {
1 | 2 | 3 => println!("{}", 0),
4 .. 12 => println!("{}", 1),
DEC => println!("{}", 2),
}
}
}