Invalid casts for C-style enums should trigger the "overflowing_literals" lint

d6c7ad3
Opened by Michael Bryan at 2020-06-11 18:01:51

Is there any reason why the "integer out of range" lint doesn't trigger when you cast a C-style enum to an integer type which isn't big enough?

For example say I have the following program:

enum Foo {
    A = 1,
    C = 1234,
}

fn main() {
    let a = Foo::A as u32;
    let c = Foo::C as u8;
    let normal = 1234 as u8;
    println!("{}, {}, {}", a, c, normal);
}

When you compile it, you get a warning on the integer cast, but not the Foo::C as u8 line.

   Compiling playground v0.0.1 (file:///playground)
warning: literal out of range for u8
 --> src/main.rs:9:18
  |
9 |     let normal = 1234 as u8;
  |                  ^^^^
  |
  = note: #[warn(overflowing_literals)] on by default

    Finished dev [unoptimized + debuginfo] target(s) in 0.46 secs
     Running `target/debug/playground`

1, 210, 210

I would have thought the compiler knows what integer size a C-style enum can fit into and then be able to lint accordingly. So for this case a Foo's largest variant has a value of 1234 meaning it can fit into a u16 (or i16), but not a u8.

(playground)

  1. It looks like it's because Foo::C is isize while the 1234 in let normal = 1234 as u8; is i32. if you specify 1234isize then the warning disappears. If you want, you can use num::ToPrimitive to ensure conversions from isize or usize can fit in another integer type.

    Juliette Regimbal at 2017-11-12 18:46:40