konst

Macro assertc_eq

Source
macro_rules! assertc_eq {
    ($left:expr, $right:expr $(, $($fmt:tt)* )? ) => { ... };
}
Expand description

For asserting that two values are equal.

examples below

This macro is only evaluated at compile-time if used in a context that requires it (eg: in the expression assigned to a const _: () = )

§Formatting

This uses the same syntax for formatting arguments as const_panic::concat_panic.

By default, this only supports primitive types as arguments, to format arrays or custom types you must enable const_panic’s "non_basic" feature.

To pass user-defined types, they must implement both of these traits as described in their docs:

§Examples

§Zipping slices

This example requires the "iter" feature

use konst::{iter, slice};

const A: &[u8] = &[3, 5, 8, 13];
const B: &[u8] = &[0, 1, 2, 3];

const C: &[(u8, u8)] = &{
    konst::assertc_eq!(A.len(), B.len());

    iter::collect_const!((u8, u8) =>
        slice::iter_copied(A),
            zip(slice::iter_copied(B)),
    )
};

assert_eq!(C, [(3, 0), (5, 1), (8, 2), (13, 3)]);

If either slice was a different length, this would be the compile-time error:

error[E0080]: evaluation of constant value failed
  --> src/macros/assert_macros.rs:79:5
   |
10 |     konst::assertc_eq!(A.len(), B.len());
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at '
assertion failed: LEFT == RIGHT
 left: `3`
right: `4`
', src/macros/assert_macros.rs:10:5

§User-defined type

This example demonstrates formatting of user-defined types.

The const_panic::PanicFmt derive that this example uses requres enabling const_panic’s "derive" feature.

use konst::assertc_eq;
use konst::const_panic::PanicFmt;

const _: () = assert_same_layout(layout_for!(u32), layout_for!(i32));

#[track_caller]
const fn assert_same_layout(left: Layout, right: Layout) {
    assertc_eq!{left, right, "layout mismatch"}
}

#[derive(PanicFmt)]
struct Layout {
    type_name: &'static str,
    size: usize,
    alignment: usize,
}

konst::impl_cmp!{
    impl Layout;
     
    pub const fn const_eq(&self, other: &Self) -> bool {
        konst::const_eq!(self.size, other.size) &&
        konst::const_eq!(self.alignment, other.alignment)
    }
}

impl Layout {
    pub const fn new<T>(type_name: &'static str) -> Self {
        Self {
            type_name,
            size: std::mem::size_of::<T>(),
            alignment: std::mem::align_of::<T>(),
        }
    }
}

macro_rules! layout_for {
    ($ty:ty) => {
        Layout::new::<$ty>(stringify!($ty))
    }
} use layout_for;

If the types were changed, the example would fail compilation with this error:

error[E0080]: evaluation of constant value failed
 --> src/macros/assert_macros.rs:120:15
  |
6 | const _: () = assert_same_layout(layout_for!(u32), layout_for!([u8; 4]));
  |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at '
assertion failed: LEFT == RIGHT
 left: `Layout { type_name: "u32", size: 4, alignment: 4 }`
right: `Layout { type_name: "[u8; 4]", size: 4, alignment: 1 }`
: layout mismatch', src/macros/assert_macros.rs:6:15