mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-22 07:53:11 -05:00
4401565fe9
The sibling `build_assert!` is already in the prelude, it makes sense that a "core"/"language" facility like this is part of the prelude and users should not be defining their own one (thus there should be no risk of future name collisions and we would want to be aware of them anyway). Thus add `build_error!` into the prelude. Reviewed-by: Alice Ryhl <aliceryhl@google.com> Link: https://lore.kernel.org/r/20241123222849.350287-3-ojeda@kernel.org [ Applied the change to the new miscdevice cases. - Miguel ] Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
86 lines
2.5 KiB
Rust
86 lines
2.5 KiB
Rust
// 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
|
|
/// }
|
|
///
|
|
/// #[inline]
|
|
/// 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);
|
|
}
|
|
}};
|
|
}
|