(name/syntax to be bikeshedded; In this post I use T as U as abbreviation of let x: T; x as U).
Currently the as operator used for casting does one of two things:
- Lossless, reliable conversion to a compatible type of same or larger size (e.g.
u32 as u64).
- Potentially lossy and dangerous truncation to a smaller type (e.g.
usize as u8).
The problem is that I often only want the first one, but I have no way of preventing the second case from unintentionally happening.
Although unexpected integer overflow is “safe” per Rust’s strict definition, it’s still a problem that can cause bugs, data loss and panics in Rust code, and cause memory safety issues when wrong values are passed through FFI.
For example usize as u32 is correct on 32-bit architectures, but on 64-bit architectures it will compile without warnings to code that may be subtly broken (and vice-versa with u64 as usize).
It’s easy to say “well, just be careful with types you cast”, but that’s not so easy in practice:
-
Sizes of aliased type names are non-obvious. How do you know whether somelibrary::Distance as usize is correct (lossless), on all platforms?
And you can’t know whether it’ll remain correct in v2.0 of the library (but the cast will, unfortunately, compile without warnings even when it becomes incorrect).
-
Size of usize and C types can vary, especially on architectures that I don’t test on 
I suppose all of my Rust code would compile on 16-bit platforms, but would fail miserably at runtime. I’d prefer it to fail to compile on some architectures if some uses of as that were lossless on 64-bit became lossy on the smaller architecture, as the compile errors would help reviewing and fixing the code.
For integers Rust has overflow-checked and wrapping variants. I think of current as operator as the wrapping variant of type conversion, and I’d like to have a variant that prevents unintentional overflows.