// SPDX-License-Identifier: GPL-2.0//! Build-time assert.#[doc(hidden)]pub use build_error::build_error;/// Fails the build if the code path calling `build_error!` can possibly be executed.////// If the macro is executed in const context, `build_error!` will panic./// If the compiler or optimizer cannot guarantee that `build_error!` can never/// be called, a build error will be triggered.////// # Examples////// ```/// #[inline]/// fn foo(a: usize) -> usize {/// a.checked_add(1).unwrap_or_else(|| build_error!("overflow"))/// }////// assert_eq!(foo(usize::MAX - 1), usize::MAX); // OK./// // foo(usize::MAX); // Fails to compile./// ```#[macro_export]macro_rules! build_error { () => {{ $crate::build_assert::build_error("") }}; ($msg:expr) => {{ $crate::build_assert::build_error($msg) }};}/// Asserts that a boolean expression is `true` at compile time.////// If the condition is evaluated to `false` in const context, `build_assert!`/// will panic. If the compiler or optimizer cannot guarantee the condition will/// be evaluated to `true`, a build error will be triggered.////// [`static_assert!`] should be preferred to `build_assert!` whenever possible.////// # Examples////// These examples show that different types of [`assert!`] will trigger errors/// at different stage of compilation. It is preferred to err as early as/// possible, so [`static_assert!`] should be used whenever possible./// ```ignore/// fn foo() {/// static_assert!(1 > 1); // Compile-time error/// build_assert!(1 > 1); // Build-time error/// assert!(1 > 1); // Run-time error/// }/// ```////// When the condition refers to generic parameters or parameters of an inline function,/// [`static_assert!`] cannot be used. Use `build_assert!` in this scenario./// ```/// fn foo<const N: usize>() {/// // `static_assert!(N > 1);` is not allowed/// build_assert!(N > 1); // Build-time check/// assert!(N > 1); // Run-time check/// }/// ```////// When a condition depends on a function argument, the function must be annotated with/// `#[inline(always)]`. Without this attribute, the compiler may choose to not inline the/// function, preventing it from optimizing out the error path./// ```/// #[inline(always)]/// fn bar(n: usize) {/// // `static_assert!(n > 1);` is not allowed/// build_assert!(n > 1); // Build-time check/// assert!(n > 1); // Run-time check/// }/// ```////// [`static_assert!`]: crate::static_assert!#[macro_export]macro_rules! build_assert { ($cond:expr $(,)?) => {{ if !$cond { $crate::build_assert::build_error(concat!("assertion failed: ", stringify!($cond))); } }}; ($cond:expr, $msg:expr) => {{ if !$cond { $crate::build_assert::build_error($msg); } }};}
// SPDX-License-Identifier: GPL-2.0
//! Build-time assert.
#[doc(hidden)]
pub use build_error::build_error;
/// Fails the build if the code path calling `build_error!` can possibly be executed.
///
/// If the macro is executed in const context, `build_error!` will panic.
/// If the compiler or optimizer cannot guarantee that `build_error!` can never
/// be called, a build error will be triggered.
///
/// # Examples
///
/// ```
/// #[inline]
/// fn foo(a: usize) -> usize {
/// a.checked_add(1).unwrap_or_else(|| build_error!("overflow"))
/// }
///
/// assert_eq!(foo(usize::MAX - 1), usize::MAX); // OK.
/// // foo(usize::MAX); // Fails to compile.
/// ```
#[macro_export]
macro_rules! build_error {
() => {{
$crate::build_assert::build_error("")
}};
($msg:expr) => {{
$crate::build_assert::build_error($msg)
}};
}
/// Asserts that a boolean expression is `true` at compile time.
///
/// If the condition is evaluated to `false` in const context, `build_assert!`
/// will panic. If the compiler or optimizer cannot guarantee the condition will
/// be evaluated to `true`, a build error will be triggered.
///
/// [`static_assert!`] should be preferred to `build_assert!` whenever possible.
///
/// # Examples
///
/// These examples show that different types of [`assert!`] will trigger errors
/// at different stage of compilation. It is preferred to err as early as
/// possible, so [`static_assert!`] should be used whenever possible.
/// ```ignore
/// fn foo() {
/// static_assert!(1 > 1); // Compile-time error
/// build_assert!(1 > 1); // Build-time error
/// assert!(1 > 1); // Run-time error
/// }
/// ```
///
/// When the condition refers to generic parameters or parameters of an inline function,
/// [`static_assert!`] cannot be used. Use `build_assert!` in this scenario.
/// ```
/// fn foo<const N: usize>() {
/// // `static_assert!(N > 1);` is not allowed
/// build_assert!(N > 1); // Build-time check
/// assert!(N > 1); // Run-time check
/// }
/// ```
///
/// When a condition depends on a function argument, the function must be annotated with
/// `#[inline(always)]`. Without this attribute, the compiler may choose to not inline the
/// function, preventing it from optimizing out the error path.
/// ```
/// #[inline(always)]
/// fn bar(n: usize) {
/// // `static_assert!(n > 1);` is not allowed
/// build_assert!(n > 1); // Build-time check
/// assert!(n > 1); // Run-time check
/// }
/// ```
///
/// [`static_assert!`]: crate::static_assert!
#[macro_export]
macro_rules! build_assert {
($cond:expr $(,)?) => {{
if !$cond {
$crate::build_assert::build_error(concat!("assertion failed: ", stringify!($cond)));
}
}};
($cond:expr, $msg:expr) => {{
if !$cond {
$crate::build_assert::build_error($msg);
}
}};
}