Const evaluation

From Rust Community Wiki
Jump to navigation Jump to search

Const evaluation is the evaluation of expressions at compile time. It is used when an expression is assigned to a const or static item. Function calls can be const-evaluated, if they are const fns.

Note that in optimized builds, all expressions that are guaranteed to be side-effect free and can be evaluated at compile time, will be evaluated at compile time. However, this is an optimization by LLVM, Rust's compiler backend, and does not affect language semantics. With const evaluation, we only refer to the language concept, not to LLVM optimizations. Const evaluation is independent of the optimization level and other build configurations.

Rust internally uses Miri for const evaluation. Miri is a Rust MIR interpreter.

Example[edit | edit source]

// this function can be const-evaluated!
const fn foo(n: u32) -> u32 {
    n * 42
}

static FOO: u32 = foo(7) + 42;

Note that foo is only const-evaluated when used in a const context. A const context is an expression used in a const or static item or in a function that is being const-evaluated.

Limitations[edit | edit source]

Currently, many operations (e.g. panicking, recursion, using mutable references) in const contexts are only supported as nightly-only features. The most important features (conditions and loops) have been stabilized in Rust Beta (1.46) and will become available on Stable Rust soon.

Here's an example of what is possible on nightly:

#![feature(const_fn, const_panic)]

const fn is_sorted(arr: &[i32]) -> bool {
    let mut i = 1;
    while i < arr.len() {
        if arr[i - 1] > arr[i] {
            return false;
        }
        i += 1;
    }
    true
}

const fn sorted(arr: &[i32]) -> &[i32] {
    assert!(is_sorted(arr));
    arr
}

static ARR: &[i32] = sorted(&[1, 2, 3, 3, 4, 7, 12]);

See also[edit | edit source]