As of Rust 1.57, now that const_panic
is stable it's now possible to do the following:
pub const FOO: usize = 42;
pub const BAR: usize = 42;
// Flagged as dead code unfortunately
#[allow(dead_code)]
const fn assert_foo_equals_bar() {
assert!(FOO == BAR);
}
const _: () = assert_foo_equals_bar();
...and that's pretty cool and a nice workaround to enforce some properties which are checked at compile time to the point that if something's wrong you get a compile error:
error[E0080]: evaluation of constant value failed
--> src/lib.rs:6:5
|
6 | assert!(FOO == BAR);
| ^^^^^^^^^^^^^^^^^^^
| |
| the evaluated program panicked at 'assertion failed: FOO == BAR', src/lib.rs:6:5
| inside `assert_foo_equals_bar` at src/lib.rs:6:5
...
9 | const _: () = assert_foo_equals_bar();
| ----------------------- inside `_` at src/lib.rs:9:15
But what would really be nice is this (which I believe is closer to what C++'s static_assert
provides):
pub const FOO: usize = 42;
pub const BAR: usize = 42;
// Or potentially `assert!` if it's possible
static_assert!(FOO == BAR);
Has anyone proposed this before, and if so, is there a relevant tracking issue?
It's easy enough to write (not quite complete, but the basic idea):
macro_rules! static_assert {
($cond:expr) => {
#[allow(dead_code)]
const fn static_assertion() {
assert!($cond);
}
const _: () = static_assertion();
}
}
...but this is one of those things that's tiny enough and fundamental enough that I don't really want to pull in an external crate to define it, but annoying boilerplate to copy from crate-to-crate, especially if I just want to use it once.