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