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