Compile-time array indexing bounds checks for constants

Is there a reason that bounds checks are not applied at compile time for indices that constant?

For example:

fn main() {
    let array = [3; 5];
    let index = 7;
    let value = array[index];
    println!("The value of the array at index {} is {}", index, value);
}

Rust does some constant propagation itself, but I don't think it would ever move a runtime panic to a compile time error, at least not implicitly. LLVM will do much more constant propagation while optimizing, but still preserving the runtime semantics as if it had run normally. In fact your example compiles down to nothing but the panic!

; playground::main
; Function Attrs: noreturn nonlazybind uwtable
define internal void @_ZN10playground4main17hf28bffb86a3b972bE() unnamed_addr #4 {
start:
; call core::panicking::panic_bounds_check
  call void @_ZN4core9panicking18panic_bounds_check17h7e4a875efe91e705E(i64 7, i64 5, %"std::panic::Location"* noalias readonly align 8 dereferenceable(24) bitcast (<{ i8*, [16 x i8] }>* @alloc42 to %"std::panic::Location"*))
  unreachable
}

(If you change that to a direct index, array[7], then you do get an unconditional_panic error.)

Note that this means if your constant is const, you'll get the unconditional_panic error.

fn main() {
    let array = [3; 5];
    const INDEX: usize = 7;
    let value = array[INDEX];
    println!("The value of the array at index {} is {}", INDEX, value);
}
error: this operation will panic at runtime
 --> src/main.rs:4:17
  |
4 |     let value = array[INDEX];
  |                 ^^^^^^^^^^^^ index out of bounds: the length is 5 but the index is 7
  |
  = note: `#[deny(unconditional_panic)]` on by default
3 Likes

Interesting, why is there a difference in behavior for const vs. non-const?

Yes, in Rust const variables are guarantied to be evaluated a compilation time. so they need to be initialized with an expression using only const values and functions.

Non mutable variables are just guarantied to not be modified after initialization, but they can be initialized with any expression.