Make match statement more aware of possible values with numbers

The question does raise some interesting question for hypothetical pattern types in Rust. (Previously discussed in much more detail at least in Thoughts on pattern types and subtyping)

Suppose we had the syntax T @ pattern to denote the subtype of T matching the pattern.

Then with let val: u32 @ 0..4 = ..., that match should probably be accepted. (Since what would be the point otherwise.)

Next, should a literal 4_u32 have the minimal subtype it can, u32 @ 4? That would make sense since literals are also accepted where a constant is required. With the previous point, match 4 { 4 => println!("Four!") } would now compile.

Would inferred types always choose the minimal subtype as well? So that if % had signature fn rem(u32, u32 @ N) -> u32 @ 0..N (for every N), let val = n % 4; would result in the type u32 @ 0..4. Interestingly, the original example, as written with let val: u32 = ... % 4, could still receive the error because it's explicitly opting into the full range of the type.