This lint warns when an assertion can use a stronger compile-time assertion form.
The preference order is:
static_assert!const_assert!build_assert!
static_assert! is preferred when the condition is fully closed over compile-time context.
const_assert! is preferred when the condition is valid in a generic-aware const context but still
depends on generics or expression-local bindings. build_assert! is only needed once the condition
depends on variables or other non-const context.
These trigger the lint with a static_assert! suggestion:
fn literal_const_only() {
build_assert!(1 < LIMIT);
}fn wrapper_const_only() {
forward_build_assert!(OFFSET < LIMIT);
}Macro-generated assertions can also trigger:
macro_rules! forward_const_check {
($expr:expr $(,)?) => {
build_assert!($expr);
let _x = 0usize;
};
}
fn f<const N: usize>() {
forward_const_check!(N > 0);
}These trigger the lint with a const_assert! suggestion:
fn const_generic_only<const N: usize>() {
build_assert!(OFFSET < N);
}const fn helper<const N: usize>() -> usize {
N - 1
}
fn const_fn_helper_only<const N: usize>() {
build_assert!(helper::<N>() < N);
}This also applies to const_assert! when it does not actually need generic-aware const context:
fn const_assert_static_only() {
const_assert!(1 < LIMIT);
}These do not trigger assert_hierarchy:
fn const_assert_generic<const N: usize>() {
const_assert!(OFFSET < N);
}fn runtime_direct(offset: usize, n: usize) {
build_assert!(offset < n);
}fn non_const_fn_helper<const N: usize>() {
build_assert!(helper::<N>() < N);
}