1 // SPDX-License-Identifier: GPL-2.0
2 
3 //! Build-time assert.
4 
5 #[doc(hidden)]
6 pub use build_error::build_error;
7 
8 /// Fails the build if the code path calling `build_error!` can possibly be executed.
9 ///
10 /// If the macro is executed in const context, `build_error!` will panic.
11 /// If the compiler or optimizer cannot guarantee that `build_error!` can never
12 /// be called, a build error will be triggered.
13 ///
14 /// # Examples
15 ///
16 /// ```
17 /// #[inline]
18 /// fn foo(a: usize) -> usize {
19 ///     a.checked_add(1).unwrap_or_else(|| build_error!("overflow"))
20 /// }
21 ///
22 /// assert_eq!(foo(usize::MAX - 1), usize::MAX); // OK.
23 /// // foo(usize::MAX); // Fails to compile.
24 /// ```
25 #[macro_export]
26 macro_rules! build_error {
27     () => {{
28         $crate::build_assert::build_error("")
29     }};
30     ($msg:expr) => {{
31         $crate::build_assert::build_error($msg)
32     }};
33 }
34 
35 /// Asserts that a boolean expression is `true` at compile time.
36 ///
37 /// If the condition is evaluated to `false` in const context, `build_assert!`
38 /// will panic. If the compiler or optimizer cannot guarantee the condition will
39 /// be evaluated to `true`, a build error will be triggered.
40 ///
41 /// [`static_assert!`] should be preferred to `build_assert!` whenever possible.
42 ///
43 /// # Examples
44 ///
45 /// These examples show that different types of [`assert!`] will trigger errors
46 /// at different stage of compilation. It is preferred to err as early as
47 /// possible, so [`static_assert!`] should be used whenever possible.
48 /// ```ignore
49 /// fn foo() {
50 ///     static_assert!(1 > 1); // Compile-time error
51 ///     build_assert!(1 > 1); // Build-time error
52 ///     assert!(1 > 1); // Run-time error
53 /// }
54 /// ```
55 ///
56 /// When the condition refers to generic parameters or parameters of an inline function,
57 /// [`static_assert!`] cannot be used. Use `build_assert!` in this scenario.
58 /// ```
59 /// fn foo<const N: usize>() {
60 ///     // `static_assert!(N > 1);` is not allowed
61 ///     build_assert!(N > 1); // Build-time check
62 ///     assert!(N > 1); // Run-time check
63 /// }
64 ///
65 /// #[inline]
66 /// fn bar(n: usize) {
67 ///     // `static_assert!(n > 1);` is not allowed
68 ///     build_assert!(n > 1); // Build-time check
69 ///     assert!(n > 1); // Run-time check
70 /// }
71 /// ```
72 ///
73 /// [`static_assert!`]: crate::static_assert!
74 #[macro_export]
75 macro_rules! build_assert {
76     ($cond:expr $(,)?) => {{
77         if !$cond {
78             $crate::build_assert::build_error(concat!("assertion failed: ", stringify!($cond)));
79         }
80     }};
81     ($cond:expr, $msg:expr) => {{
82         if !$cond {
83             $crate::build_assert::build_error($msg);
84         }
85     }};
86 }
87