Out od curiosity, why Rust insisted on the case?

I have the following code,

let (len, mut shift) = 
    match input[1] >> 1 {
        len @ 0..=125 => (len as u64, 2_usize),
        126 => (input[2] as u64 | (input[3] as u64) << 8, 4_usize),
        127 => (input[9] as u64 | (input[8] as u64)<<8 | (input[7] as u64)<<16 |
          (input[6] as u64)<<24 | (input[4] as u64)<<32 | (input[4] as u64)<<40 | (input[3] as u64)<<48 | (input[2] as u64)<<56, 10_usize),
        128_u8..=u8::MAX => todo!()
    };

Since I do the right shift on 1 and it isn't cyclic, the value can't exceed 127, however Rust insisted on the last condition. Why? Did I miss something?

Broadly, the compiler never uses the possible range that an expression could evaluate to to decide whether to accept or reject some code. You always have to handle the full range implied by the type of the value.

Someday there might be additional types with which you can specify restricted numeric range, but those types won't be automatically used based on the possible results of evaluating an expression.

8 Likes

The body of if false { ... } isn't considered unreachable code either, and that one doesn't involve invoking an operation. More generally, see this comment.

Incidentally there's an alternative to todo!() which is spelled unreachable!().

5 Likes

True, but the code won't appear in the final code generation for a release goal. Your point seems is valid for the case like,

match true {
  true => (),
  false => unreachable!().
}

too. The suggestion regarding unreachable!(). is really cool. I didn't know it, so thank you.