Skip to main content

Module build_assert

Module build_assert 

Source
Expand description

Various assertions that happen during build-time.

There are three types of build-time assertions that you can use:

The ones towards the bottom of the list are more expressive, while the ones towards the top of the list are more robust and trigger earlier in the compilation pipeline. Therefore, you should prefer the ones towards the top of the list wherever possible.

§Choosing the correct assertion

If you’re asserting outside any bodies (e.g. initializers or function bodies), you should use static_assert! as it is the only assertion that can be used in that context.

Inside bodies, if your assertion condition does not depend on any variable or generics, you should use static_assert!. If the condition depends on generics, but not variables (including function arguments), you should use const_assert!. Otherwise, use build_assert!. The same is true regardless if the function is const fn.

// Outside any bodies.
static_assert!(core::mem::size_of::<u8>() == 1);
// `const_assert!` and `build_assert!` cannot be used here, they will fail to compile.

#[inline(always)]
fn foo<const N: usize>(v: usize) {
    static_assert!(core::mem::size_of::<u8>() == 1); // Preferred.
    const_assert!(core::mem::size_of::<u8>() == 1); // Discouraged.
    build_assert!(core::mem::size_of::<u8>() == 1); // Discouraged.

    // `static_assert!(N > 1);` is not allowed.
    const_assert!(N > 1); // Preferred.
    build_assert!(N > 1); // Discouraged.

    // `static_assert!(v > 1);` is not allowed.
    // `const_assert!(v > 1);` is not allowed.
    build_assert!(v > 1); // Works.
}

§Detailed behavior

static_assert!() is equivalent to static_assert in C. It requires expr to be a constant expression. This expression cannot refer to any generics. A static_assert!(expr) in a program is always evaluated, regardless if the function it appears in is used or not. This is also the only usable assertion outside a body.

const_assert!() has no direct C equivalence. It is a more powerful version of static_assert!(), where it may refer to generics in a function. Note that due to the ability to refer to generics, the assertion is tied to a specific instance of a function. So if it is used in a generic function that is not instantiated, the assertion will not be checked. For this reason, static_assert!() is preferred wherever possible.

build_assert!() is equivalent to BUILD_BUG_ON. It is even more powerful than const_assert!() because it can be used to check tautologies that depend on runtime value (this is the same as BUILD_BUG_ON). However, the assertion failure mechanism can possibly be undefined symbols and linker errors, it is not developer friendly to debug, so it is recommended to avoid it and prefer other two assertions where possible.

Re-exports§

pub use crate::build_assert;
pub use crate::build_assert;

Macros§

build_assert
Asserts that a boolean expression is true at compile time.
build_error
Fails the build if the code path calling build_error! can possibly be executed.
const_assert
Assertion during constant evaluation.
static_assert
Static assert (i.e. compile-time assert).