Ensuring a sorted constant array at compile time

I would like to know what would be your preferred construction to achieve compile time assertions on constants. My first effort interferes a bit with dead code analysis.

struct Check<const COND: bool>;
impl Check<true> {const OK: () = ();}

macro_rules! static_assert {
    ($cond:expr) => {
        #[allow(dead_code)]
        const _: () = Check::<{$cond}>::OK;
    }
}

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

const A: [i32; 4] = [1, 2, 3, 4];

static_assert!(is_sorted(&A));

fn main() {
}
1 Like

There's a popular crate that does it. They also disable some lints.

I wouldn't say I have a preferred construction, but this one causes no dead code lints (or name hazards):

macro_rules! static_assert {
    ($assertion:expr) => {
       const _: u8 = 0 / $assertion as u8;
    }
}

(Technically when it fails it triggers a lint, but the plan is to make it a hard error.)

A slight enhancement:

macro_rules! const_assert {
    ($cond:expr) => {
        #[allow(dead_code)]
        const _: () = {
            struct Bool<const COND: bool>;
            const _: Bool<true> = Bool::<{$cond}>;
        };
    }
}

It bothers me a little that const _ behaves differently than let _ regarding dead_code.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.