I try to exhaustively match integers like this:
fn main() {
for test in range(std::u8::MIN, std::u8::MAX) {
match test {
0x00..0xff => {},
}
}
}
But the compiler complains:
all.rs:3:9: 6:10 error: non-exhaustive patterns: `_` not covered [E0004]
all.rs:3 match test {
all.rs:4 0x00..0xff => {},
all.rs:5 }
error: aborting due to previous error
However, all possible values are covered. A quick check confirms this:
fn main() {
for test in range(std::u8::MIN, std::u8::MAX) {
match test {
0x00..0xff => {},
_ => fail!("impossible"),
}
}
}
And now compile and run it:
$ rustc all.rs
$ ./all
$
All possible values are covered, so why does rustc still want the obviously unreachable _
arm?
Finally, exhaustive pattern matching is a valuable tool for ensuring that code stays correct as requirements change, or during refactoring. Let’s say that the requirements change and we need to handle a third type of error: “Indeterminate”.
The fact that exhaustive matching is always done means that certain common errors will be detected by the compiler immediately: A missing case (often caused when a new choice has been added due to changed requirements or refactoring).
A proof that the set of cases is exhaustive; i.e., that each instance of the statement to be proved matches the conditions of (at least) one of the cases. A proof of each of the cases.
We briefly noted earlier that when pattern matching there is a requirement to match all possible cases. This turns out be a very powerful technique to ensure correctness. Let’s compare some C# to F# again.
Exhaustive integer matching was stabilised in Rust 1.33.0. The original example in the question now works (updated to use the modern syntax for ranges).
fn main() {
for i in std::u8::MIN..=std::u8::MAX {
match i {
0x00..=0xff => {}
}
}
}
As discussed in the referenced issue, Rust's exhaustiveness checking is based entirely on enums and never values, so this fails because u8
simply isn't an enum type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With