main--
main--

Reputation: 3973

Exhaustive integer matching

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

Answers (3)

varkor
varkor

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

main--
main--

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

thecoshman
thecoshman

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

Related Questions