Reputation: 3973
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?
Upvotes: 6
Views: 2222
Reputation: 509
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 => {}
}
}
}
Upvotes: 7
Reputation: 3973
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.
Upvotes: 3
Reputation: 8650
I'd imagine the compile just see that you are matching on type u8
(though any number type would work for this argument), and for the sake of simplicity does not actually check that your patterns cover the full range. It's much easier for the compiler to expect you to have a 'catch all' with _
and make the developer handle it.
Also consider that it's very stupid to use a match
when you are going to match every result any way, in that case you should just use the value.
Upvotes: -2