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