10f595babSGary Guo // SPDX-License-Identifier: GPL-2.0 20f595babSGary Guo 30f595babSGary Guo //! Build-time assert. 40f595babSGary Guo 5*614724e7SMiguel Ojeda #[doc(hidden)] 6*614724e7SMiguel Ojeda pub use build_error::build_error; 7*614724e7SMiguel Ojeda 80f595babSGary Guo /// Fails the build if the code path calling `build_error!` can possibly be executed. 90f595babSGary Guo /// 100f595babSGary Guo /// If the macro is executed in const context, `build_error!` will panic. 110f595babSGary Guo /// If the compiler or optimizer cannot guarantee that `build_error!` can never 120f595babSGary Guo /// be called, a build error will be triggered. 130f595babSGary Guo /// 140f595babSGary Guo /// # Examples 150f595babSGary Guo /// 160f595babSGary Guo /// ``` 170f595babSGary Guo /// #[inline] 180f595babSGary Guo /// fn foo(a: usize) -> usize { 190f595babSGary Guo /// a.checked_add(1).unwrap_or_else(|| build_error!("overflow")) 200f595babSGary Guo /// } 210f595babSGary Guo /// 220f595babSGary Guo /// assert_eq!(foo(usize::MAX - 1), usize::MAX); // OK. 230f595babSGary Guo /// // foo(usize::MAX); // Fails to compile. 240f595babSGary Guo /// ``` 250f595babSGary Guo #[macro_export] 260f595babSGary Guo macro_rules! build_error { 270f595babSGary Guo () => {{ 28*614724e7SMiguel Ojeda $crate::build_assert::build_error("") 290f595babSGary Guo }}; 300f595babSGary Guo ($msg:expr) => {{ 31*614724e7SMiguel Ojeda $crate::build_assert::build_error($msg) 320f595babSGary Guo }}; 330f595babSGary Guo } 340f595babSGary Guo 350f595babSGary Guo /// Asserts that a boolean expression is `true` at compile time. 360f595babSGary Guo /// 370f595babSGary Guo /// If the condition is evaluated to `false` in const context, `build_assert!` 380f595babSGary Guo /// will panic. If the compiler or optimizer cannot guarantee the condition will 390f595babSGary Guo /// be evaluated to `true`, a build error will be triggered. 400f595babSGary Guo /// 410f595babSGary Guo /// [`static_assert!`] should be preferred to `build_assert!` whenever possible. 420f595babSGary Guo /// 430f595babSGary Guo /// # Examples 440f595babSGary Guo /// 450f595babSGary Guo /// These examples show that different types of [`assert!`] will trigger errors 460f595babSGary Guo /// at different stage of compilation. It is preferred to err as early as 470f595babSGary Guo /// possible, so [`static_assert!`] should be used whenever possible. 480f595babSGary Guo /// ```ignore 490f595babSGary Guo /// fn foo() { 500f595babSGary Guo /// static_assert!(1 > 1); // Compile-time error 510f595babSGary Guo /// build_assert!(1 > 1); // Build-time error 520f595babSGary Guo /// assert!(1 > 1); // Run-time error 530f595babSGary Guo /// } 540f595babSGary Guo /// ``` 550f595babSGary Guo /// 560f595babSGary Guo /// When the condition refers to generic parameters or parameters of an inline function, 570f595babSGary Guo /// [`static_assert!`] cannot be used. Use `build_assert!` in this scenario. 580f595babSGary Guo /// ``` 590f595babSGary Guo /// fn foo<const N: usize>() { 600f595babSGary Guo /// // `static_assert!(N > 1);` is not allowed 610f595babSGary Guo /// build_assert!(N > 1); // Build-time check 620f595babSGary Guo /// assert!(N > 1); // Run-time check 630f595babSGary Guo /// } 640f595babSGary Guo /// 650f595babSGary Guo /// #[inline] 660f595babSGary Guo /// fn bar(n: usize) { 670f595babSGary Guo /// // `static_assert!(n > 1);` is not allowed 680f595babSGary Guo /// build_assert!(n > 1); // Build-time check 690f595babSGary Guo /// assert!(n > 1); // Run-time check 700f595babSGary Guo /// } 710f595babSGary Guo /// ``` 723ed03f4dSMiguel Ojeda /// 733ed03f4dSMiguel Ojeda /// [`static_assert!`]: crate::static_assert! 740f595babSGary Guo #[macro_export] 750f595babSGary Guo macro_rules! build_assert { 760f595babSGary Guo ($cond:expr $(,)?) => {{ 770f595babSGary Guo if !$cond { 78*614724e7SMiguel Ojeda $crate::build_assert::build_error(concat!("assertion failed: ", stringify!($cond))); 790f595babSGary Guo } 800f595babSGary Guo }}; 810f595babSGary Guo ($cond:expr, $msg:expr) => {{ 820f595babSGary Guo if !$cond { 83*614724e7SMiguel Ojeda $crate::build_assert::build_error($msg); 840f595babSGary Guo } 850f595babSGary Guo }}; 860f595babSGary Guo } 87