const_panic/macros/concat_assert.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
/// Asserts that `$condition` is true.
///
/// When only the `$condition` argument is passed,
/// this delegates to the [`core::assert`] macro.
///
/// When two or more arguments are passed,
/// this panics with formatting by delegating the second and remaining arguments
/// to the [`concat_panic`](macro@crate::concat_panic) macro.
///
/// ### Examples
///
/// ### Formatted assertion
///
/// ```compile_fail
/// use const_panic::concat_assert;
///
/// const ONE: Even = Even::new(1);
///
/// struct Even(u32);
///
/// impl Even {
/// #[track_caller]
/// const fn new(n: u32) -> Self {
/// concat_assert!(n % 2 == 0, "\nexpected the argument to be even, found: ", n);
///
/// Even(n)
/// }
/// }
/// ```
/// the above code errors with this message:
/// ```text
/// error[E0080]: evaluation of constant value failed
/// --> src/macros/concat_assert.rs:16:19
/// |
/// 4 | const ONE: Even = Even::new(1);
/// | ^^^^^^^^^^^^ the evaluated program panicked at '
/// expected the argument to be even, found: 1', src/macros/concat_assert.rs:4:19
///
/// ```
///
/// ### More formatting
///
/// This example demonstrates what error non-`#[track_caller]` functions produce,
/// and uses the `"non_basic"` feature(enabled by default).
///
/// ```compile_fail
/// use const_panic::concat_assert;
///
/// const SUM: u64 = sum(&[3, 5, 8], 1..40);
///
/// const fn sum(mut slice: &[u32], range: std::ops::Range<usize>) -> u64 {
/// concat_assert!(
/// range.start <= range.end && range.end <= slice.len(),
/// "\ncannot index slice of length `", slice.len(),
/// "` with `", range, "` range"
/// );
///
/// let mut sum = 0u64;
///
/// while let [curr, ref rem @ ..] = *slice {
/// sum += curr as u64;
///
/// slice = rem;
/// }
///
/// sum
/// }
/// ```
/// the above code errors with this message:
/// ```text
/// error[E0080]: evaluation of constant value failed
/// --> src/macros/concat_assert.rs:52:5
/// |
/// 6 | const SUM: u64 = sum(&[3, 5, 8], 1..40);
/// | ---------------------- inside `SUM` at src/macros/concat_assert.rs:6:18
/// ...
/// 9 | / concat_assert!(
/// 10 | | range.start <= range.end && range.end <= slice.len(),
/// 11 | | "\ncannot index slice of length `", slice.len(),
/// 12 | | "` with `", range, "` range"
/// 13 | | );
/// | | ^
/// | | |
/// | |_____the evaluated program panicked at '
/// cannot index slice of length `3` with `1..40` range', src/macros/concat_assert.rs:9:5
/// | inside `_doctest_main_src_macros_concat_assert_rs_46_0::sum` at /home/matias/Documents/proyectos programacion/const_panic/src/macros.rs:240:21
/// |
/// = note: this error originates in the macro `$crate::concat_panic` (in Nightly builds, run with -Z macro-backtrace for more info)
/// ```
///
/// ### Unformatted assertion
///
/// When only the `$condition` argument is passed,
/// this delegates to the [`core::assert`] macro.
///
/// ```compile_fail
/// use const_panic::concat_assert;
///
/// const _: () = concat_assert!(cfg!(any(feature = "foo", feature = "bar")) );
/// ```
/// the above code errors with this message:
/// ```text
/// error[E0080]: evaluation of constant value failed
/// --> src/macros/concat_assert.rs:48:15
/// |
/// 6 | const _: () = concat_assert!(cfg!(any(feature = "foo", feature = "bar")) );
/// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: cfg!(any(feature = \"foo\", feature = \"bar\"))', src/macros/concat_assert.rs:6:15
/// |
/// = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info)
/// ```
///
///
#[macro_export]
macro_rules! concat_assert {
($condition:expr $(,)?) => {
$crate::__::assert!($condition);
};
($condition:expr, $($fmt:tt)*) => {{
#[allow(clippy::equatable_if_let)]
if let false = $condition {
$crate::concat_panic!{$($fmt)*}
}
}};
}