const_panic/macros/
concat_assert.rs

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