# Nicer static assertions

**URL:** <https://internals.rust-lang.org/t/nicer-static-assertions/15986>\
**Category:** language design\
**Created:** [January 18, 2022, 10:36pm UTC](https://internals.rust-lang.org/t/nicer-static-assertions/15986 "2022-01-18T22:36:53Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![bascule](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bascule/32/3057_2.png) [@bascule](https://internals.rust-lang.org/u/bascule)\
**Post date:** [January 18, 2022, 10:36pm UTC](https://internals.rust-lang.org/t/nicer-static-assertions/15986/1 "2022-01-18T22:36:53Z")

</div>

As of Rust 1.57, now that `const_panic` is stable it's now possible to do the following:

```rust
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:

```rust
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):

```rust
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):

```rust
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.

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [January 18, 2022, 11:04pm UTC](https://internals.rust-lang.org/t/nicer-static-assertions/15986/2 "2022-01-18T23:04:23Z")

</div>

You can [already just write](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=8dcc0471ee46b0179c987da7a8b44a84)

```rust
const _: () = assert!(FOO == BAR, "assert_foo_equals_bar");

```

with no need for the function.

There's no way for a macro to know if it's used in expression or item position (and there shouldn't be), so the only way to make bare `assert!` work would be to make statements in item position evaluated at const time. This is probably not the best idea, as it's likely to be confused with script-style execution.

It probably is worth adding a `const_assert!` to the stdlib, as

```rust
macro_rules! const_assert {
    ($($tt:tt)*) => {
        const _: () = assert!($($tt)*);
    }
}

```

(perhaps with `assert!`'s match arms instead of a pass-through catch-all).

> [@bascule](#):
>
> ...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

Just for linking's sake, here's the crate that does so (with pre-const-panic methods):

> **[static\_assertions](https://lib.rs/crates/static_assertions)**
>
> Compile-time assertions to ensure that invariants are met

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [April 18, 2022, 11:05pm UTC](https://internals.rust-lang.org/t/nicer-static-assertions/15986/3 "2022-04-18T23:05:18Z")

</div>

Closed on April 18, 2022, 11:05pm UTC

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
