1#[allow(unused_imports)]
2use crate::*;
3
4#[macro_export]
28macro_rules! ASSERT {
29 ($cond:expr, ($($fmt:tt)*) $(,$($args:expr),*)?) => {{
30 $crate::TRACE_NOBUG!(($($fmt)*) $(,$($args),*)?);
31 #[cfg(all(debug_assertions,test))] $crate::set_testing();
32 if !$cond {
33 $crate::DIE!(($($fmt)*) $(,$($args),*)?)
34 }
35 }};
36 ($cond:expr, $fmt:literal $(,$($args:expr),*)?) => {{
37 $crate::TRACE_NOBUG!($fmt $(,$($args),*)?);
38 #[cfg(all(debug_assertions,test))] $crate::set_testing();
39 if !$cond {
40 $crate::DIE!($fmt $(,$($args),*)?)
41 }
42 }};
43 ($cond:expr) => {{
44 $crate::TRACE_NOBUG!("ASSERTION FAILED: {}", stringify!($cond));
45 #[cfg(all(debug_assertions,test))] $crate::set_testing();
46 if !$cond {
47 $crate::DIE!("ASSERTION FAILED: {}", stringify!($cond))
48 }
49 }};
50}
51
52#[macro_export]
54macro_rules! ASSERT_DBG {
55 ($($tt:tt)*) => {
56 #[cfg(debug_assertions)]
57 $crate::ASSERT!($($tt)*);
58 }
59}
60
61#[test]
62fn test_assert() {
63 ASSERT!(true);
64}
65
66#[test]
67#[cfg(debug_assertions)]
68#[should_panic = "ASSERTION FAILED: false"]
69fn test_assert1() {
70 ASSERT!(false);
71}
72
73#[test]
74#[cfg(debug_assertions)]
75#[should_panic = "foo"]
76fn test_assert2() {
77 ASSERT!(false, "foo");
78}
79
80#[test]
81#[cfg(debug_assertions)]
82#[should_panic = "foo 42"]
83fn test_assert3() {
84 ASSERT!(false, "foo {}", 42);
85}
86
87#[macro_export]
99macro_rules! ASSERT_ONCE {
100($($code:tt)*) => {
101 {
102 $crate::ONCE!($crate::ASSERT!($($code)*));
103 true
104 }
105 };
106}
107
108#[test]
109#[cfg(debug_assertions)]
110#[should_panic = "ASSERTION FAILED"]
111fn test_assert_once() {
112 ASSERT_ONCE!(false, "ASSERTION FAILED");
113}
114
115#[test]
116#[cfg(debug_assertions)]
117fn test_fixme_assert_once() {
118 for i in 0..10 {
119 FIXME!({ASSERT_ONCE!(i == 0)} "not to be used this way in real code");
120 }
121}
122
123#[macro_export]
155macro_rules! REQUIRE {
156 ([$($cond:expr $(, $fmt:literal $(,$args:expr)*)?;)*]) => {
157 $($crate::REQUIRE!($cond $(,$fmt $(,$args)*)?);)*
158 };
159 (const { $cond:expr } $(, $fmt:literal $(, $($args:expr),*)?)?) => {
160 $crate::CFG_IF! {
161 if #[cfg(feature = "const_expr")] {
162 $crate::ASSERT!(
163 (const { $cond }),
164 ("PRECONDITION FAILED: {}" $(, ": ", $fmt)?),
165 stringify!($cond) $($(,$($args),*)?)?
166 );
167 } else {
168 const COND: bool = $cond;
169 $crate::ASSERT!(
170 COND,
171 ("PRECONDITION FAILED: {}" $(, ": ", $fmt)?),
172 stringify!($cond) $($(,$($args),*)?)?
173 );
174 }
175 }
176 };
177 (($lhs:expr) == ($rhs:expr) $(, $fmt:literal $(, $($args:expr),*)?)?) => {
178 $crate::ASSERT!($lhs == $rhs,
179 ("PRECONDITION FAILED: {} == {}" $(, ": ", $fmt)? , "\n lhs: {:?}\n rhs: {:?}"),
180 stringify!($lhs), stringify!($rhs)
181 $($(, $($args),*)?)?, $lhs, $rhs)
182 };
183 (($lhs:expr) != ($rhs:expr) $(, $fmt:literal $(, $($args:expr),*)?)?) => {
184 $crate::ASSERT!($lhs != $rhs,
185 ("PRECONDITION FAILED: {} != {}" $(, ": ", $fmt)? , "\n lhs: {:?}\n rhs: {:?}"),
186 stringify!($lhs), stringify!($rhs)
187 $($(, $($args),*)?)?, $lhs, $rhs)
188 };
189 (($lhs:expr) < ($rhs:expr) $(, $fmt:literal $(, $($args:expr),*)?)?) => {
190 $crate::ASSERT!($lhs < $rhs,
191 ("PRECONDITION FAILED: {} < {}" $(, ": ", $fmt)? , "\n lhs: {:?}\n rhs: {:?}"),
192 stringify!($lhs), stringify!($rhs)
193 $($(, $($args),*)?)?, $lhs, $rhs)
194 };
195 (($lhs:expr) <= ($rhs:expr) $(, $fmt:literal $(, $($args:expr),*)?)?) => {
196 $crate::ASSERT!($lhs <= $rhs,
197 ("PRECONDITION FAILED: {} <= {}" $(, ": ", $fmt)? , "\n lhs: {:?}\n rhs: {:?}"),
198 stringify!($lhs), stringify!($rhs)
199 $($(, $($args),*)?)?, $lhs, $rhs)
200 };
201 (($lhs:expr) > ($rhs:expr) $(, $fmt:literal $(, $($args:expr),*)?)?) => {
202 $crate::ASSERT!($lhs > $rhs,
203 ("PRECONDITION FAILED: {} > {}" $(, ": ", $fmt)? , "\n lhs: {:?}\n rhs: {:?}"),
204 stringify!($lhs), stringify!($rhs)
205 $($(, $($args),*)?)?, $lhs, $rhs)
206 };
207 (($lhs:expr) >= ($rhs:expr) $(, $fmt:literal $(, $($args:expr),*)?)?) => {
208 $crate::ASSERT!($lhs >= $rhs,
209 ("PRECONDITION FAILED: {} >= {}" $(, ": ", $fmt)? , "\n lhs: {:?}\n rhs: {:?}"),
210 stringify!($lhs), stringify!($rhs)
211 $($(, $($args),*)?)?, $lhs, $rhs)
212 };
213 ($cond:expr $(, $fmt:literal $(, $($args:expr),*)?)?) => {
214 $crate::ASSERT!($cond, ("PRECONDITION FAILED: {}" $(, ": ", $fmt)?), stringify!($cond)
215 $($(, $($args),*)?)?)
216 };
217}
218
219#[macro_export]
221macro_rules! REQUIRE_DBG {
222 ($($tt:tt)*) => {
223 #[cfg(debug_assertions)]
224 $crate::REQUIRE!($($tt)*);
225 }
226}
227
228#[test]
229fn test_require() {
230 let yes = true;
231 REQUIRE!(true);
232 REQUIRE!(const { true });
233 REQUIRE!((yes) == (true));
234}
235
236#[test]
237#[cfg(debug_assertions)]
238#[should_panic = "PRECONDITION FAILED: false"]
239fn test_require1() {
240 REQUIRE!(false);
241}
242
243#[test]
244fn test_braced() {
245 REQUIRE!({ true }, "foo {}", 42);
246}
247
248#[test]
249#[cfg(debug_assertions)]
250#[should_panic = "PRECONDITION FAILED: false: foo"]
251fn test_require2() {
252 REQUIRE!(false, "foo");
253}
254
255#[test]
256#[cfg(debug_assertions)]
257#[should_panic = "PRECONDITION FAILED: false: foo 42"]
258fn test_require3() {
259 REQUIRE!(false, "foo {}", 42);
260}
261
262#[test]
263#[cfg(debug_assertions)]
264#[should_panic = "PRECONDITION FAILED: false: baz 43"]
265fn test_require4() {
266 REQUIRE!([
267 true;
268 true, "bar";
269 false, "baz {}", 43;
270 ]);
271}
272
273#[cfg(feature = "const_expr")]
274#[cfg(debug_assertions)]
275#[allow(clippy::items_after_test_module)]
276#[cfg(test)]
277mod test {
278 struct ConstGeneric<const N: i32>;
279
280 impl<const N: i32> ConstGeneric<N> {
281 fn new() -> Self {
282 REQUIRE!(const { N > 0 }, "N out of range");
283 Self
284 }
285 }
286
287 #[test]
288 #[should_panic(expected = "N out of range")]
289 fn test_const_generic() {
290 let _a = ConstGeneric::<1>::new();
291 let _b = ConstGeneric::<0>::new();
292 }
293}
294
295#[macro_export]
337macro_rules! ENSURE {
338 (
339 [$($cond:expr $(, $fmt:literal $(, $($args:expr),*)? )?);* $(;)?]
340 $result:ident = $code:expr) => {{
341 let mut early_return = true;
342 let $result = (|| {
343 let result = $code;
344 early_return = false;
345 result
346 })();
347 $($crate::ASSERT!($cond, ("POSTCONDITON FAILED: {}" $(, ": ", $fmt)?), stringify!($cond) $($(, $($args),*)?)?);)*
348 if early_return {
349 return $result;
350 }
351 $result
352 }};
353 (
354 $cond:expr $(, $fmt:literal $(, $($args:expr),*)? )?;
355 $result:ident = $code:expr) => {{
356 let mut early_return = true;
357 let $result = (|| {
358 let result = $code;
359 early_return = false;
360 result
361 })();
362 $crate::ASSERT!($cond, ("POSTCONDITON FAILED: {}" $(, ": ", $fmt)?), stringify!($cond) $($(, $($args),*)?)?);
363 if early_return {
364 return $result;
365 }
366 $result
367 }};
368}
369
370#[macro_export]
372macro_rules! ENSURE_DBG {
373 (
374 [$($cond:expr $(, $fmt:literal $(, $($args:expr),*)? )?);* $(;)?]
375 $result:ident = $code:expr) => {
376 #[cfg(debug_assertions)]
377 $crate::ENSURE!(
378 [$($cond $(, $fmt $(, $($args),*)?)?);*]
379 $result = $code
380 );
381 #[cfg(not(debug_assertions))]
382 {$code}
383 };
384 (
385 $cond:expr $(, $fmt:literal $(, $($args:expr),*)? )?;
386 $result:ident = $code:expr) => {
387 #[cfg(debug_assertions)]
388 $crate::ENSURE!(
389 $cond $(, $fmt $(, $($args),*)?)?;
390 $result = $code
391 );
392 #[cfg(not(debug_assertions))]
393 {$code}
394 };
395}
396
397#[macro_export]
423macro_rules! CHECK {
424 ([$($cond:expr $(, $fmt:literal $(,$args:expr)*)?;)*]) => {
425 $($crate::CHECK!($cond $(,$fmt $(,$args)*)?);)*
426 true
427 };
428 (const { $cond:expr } $(, $fmt:literal $(, $($args:expr),*)?)?) => {
429 $crate::CFG_IF! {
430 if #[cfg(feature = "const_expr")] {
431 $crate::ASSERT!(
432 (const { $cond }),
433 ("TEST FAILED: {}" $(, ": ", $fmt)?),
434 stringify!($cond) $($(,$($args),*)?)?
435 );
436 true
437 } else {
438 const COND: bool = $cond;
439 $crate::ASSERT!(
440 COND,
441 ("TEST FAILED: {}" $(, ": ", $fmt)?),
442 stringify!($cond) $($(,$($args),*)?)?
443 );
444 true
445 }
446 }
447 };
448 (($lhs:expr) == ($rhs:expr) $(, $fmt:literal $(, $($args:expr),*)?)?) => {
449 $crate::ASSERT!($lhs == $rhs,
450 ("TEST FAILED: {} == {}" $(, ": ", $fmt)? , "\n lhs: {:?}\n rhs: {:?}"),
451 stringify!($lhs), stringify!($rhs)
452 $($(, $($args),*)?)?, $lhs, $rhs);
453 true
454 };
455 (($lhs:expr) != ($rhs:expr) $(, $fmt:literal $(, $($args:expr),*)?)?) => {
456 $crate::ASSERT!($lhs != $rhs,
457 ("TEST FAILED: {} != {}" $(, ": ", $fmt)? , "\n lhs: {:?}\n rhs: {:?}"),
458 stringify!($lhs), stringify!($rhs)
459 $($(, $($args),*)?)?, $lhs, $rhs);
460 true
461 };
462 (($lhs:expr) < ($rhs:expr) $(, $fmt:literal $(, $($args:expr),*)?)?) => {
463 $crate::ASSERT!($lhs < $rhs,
464 ("TEST FAILED: {} < {}" $(, ": ", $fmt)? , "\n lhs: {:?}\n rhs: {:?}"),
465 stringify!($lhs), stringify!($rhs)
466 $($(, $($args),*)?)?, $lhs, $rhs);
467 true
468 };
469 (($lhs:expr) <= ($rhs:expr) $(, $fmt:literal $(, $($args:expr),*)?)?) => {
470 $crate::ASSERT!($lhs <= $rhs,
471 ("TEST FAILED: {} <= {}" $(, ": ", $fmt)? , "\n lhs: {:?}\n rhs: {:?}"),
472 stringify!($lhs), stringify!($rhs)
473 $($(, $($args),*)?)?, $lhs, $rhs);
474 true
475 };
476 (($lhs:expr) > ($rhs:expr) $(, $fmt:literal $(, $($args:expr),*)?)?) => {
477 $crate::ASSERT!($lhs > $rhs,
478 ("TEST FAILED: {} > {}" $(, ": ", $fmt)? , "\n lhs: {:?}\n rhs: {:?}"),
479 stringify!($lhs), stringify!($rhs)
480 $($(, $($args),*)?)?, $lhs, $rhs);
481 true
482 };
483 (($lhs:expr) >= ($rhs:expr) $(, $fmt:literal $(, $($args:expr),*)?)?) => {
484 $crate::ASSERT!($lhs >= $rhs,
485 ("TEST FAILED: {} >= {}" $(, ": ", $fmt)? , "\n lhs: {:?}\n rhs: {:?}"),
486 stringify!($lhs), stringify!($rhs)
487 $($(, $($args),*)?)?, $lhs, $rhs);
488 true
489 };
490 ($cond:expr $(, $fmt:literal $(, $($args:expr),*)?)?) => {
491 $crate::ASSERT!($cond, ("TEST FAILED: {}" $(, ": ", $fmt)?), stringify!($cond)
492 $($(, $($args),*)?)?);
493 true
494 };
495}
496
497#[test]
498fn test_check() {
499 CHECK!(const { true });
500}