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] 24 macro_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] 71 macro_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 } 83