How to inform the Rust compiler of an enforced integer range?

227 points BoxyStopper 70 comments

In a no-IO, CPU-bound computation, I have an integer in the range 0..=63 represented by a u8. It is used to represent bit positions in a u64, index arrays with 64 elements, etc.

If turns out that if I simply replace this u8 by an enum, I get a full 10% performance boost. It is basically all range checking.

It's a silly, obtuse, round-about way to inform the compiler that I have an integer in a restricted range. I did it by defining the enum, having 64 elements in it, using transmute(value) to set the value and self as u8 to get the value. The elements in the enum are meaningless, only the integer value itself is meaningful.

Is there any other way to do this without this blunt hack? Some decoration #[range(0, 64)] ?

I can use unchecked accesses, but this is even worse.

ps: yes, --release, lto = true, etc ...

Update:

Unstable, but exists:

#![feature(rustc_attrs)]
#[rustc_layout_scalar_valid_range_start(0)]
#[rustc_layout_scalar_valid_range_end(63)]