Static assertions?

I have a "base" crate that defines a bunch of constants and types for a larger system. There are other crates within this system that have a fixed number of "channels". The number of channels is defined in the base crate using a pub const NUM_FOO_CHANNELS: usize = 32;. In many places the channels are are represented as bitflags, so u32. For this the base crate has pub type FooChFlags = u32;.

If someone changes NUM_FOO_CHANNELS to 16, they must also change FooChFlags to u16.

While it's not really important (these things will basically never change), it would be nice if the compilation would fail if there's a mismatch. For whatever reason, I thought I had seen some form of static assertions in std before, so I thought I could simply do something along the line of static_assert!(NUM_FOO_CHANNELS, FooChFlags::BITS, "NUM_FOO_CHANNELS and FooChFlags::BITS do not match"), but apparently that's not a thing.

Like I said, this is highly unimportant -- these things will basically never change.. Still, I'm curious if there's a way to do this, in the unlikely scenario that someone in the future needs fewer or more channels and doesn't read the code comments.

Turns out it is possible, there just isn't an explicit static_assert. :tada:

Also:

const {
    assert!(
        NUM_FOO_CHANNELS == FooChFlags::BITS as usize,
        "NUM_FOO_CHANNELS and FooChFlags::BITS do not match"
    )
}

But assert_eq, etc, are not supported yet because they use Debug which is not const.

2 Likes

You can put your assertion in a const block: const { assert!(args) } (which jumpnbrownweasel said before I finished typing).

But in your code, is there a reason you can’t just declare pub const NUM_FOO_CHANNELS: usize = FooChFlags::BITS as usize;?

2 Likes

That's neat -- it hadn't even occurred to me to express it that way.

2 Likes