kernel/
build_assert.rs

1// SPDX-License-Identifier: GPL-2.0
2
3//! Build-time assert.
4
5#[doc(hidden)]
6pub 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]
26macro_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]
75macro_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}