add const_eval_select macro to reduce redundancy
also move internal const_panic helpers to a better location
This commit is contained in:
@@ -189,3 +189,59 @@ pub unsafe trait PanicPayload: crate::fmt::Display {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper macro for panicking in a `const fn`.
|
||||
/// Invoke as:
|
||||
/// ```rust,ignore (just an example)
|
||||
/// core::macros::const_panic!("boring message", "flavored message {a} {b:?}", a: u32 = foo.len(), b: Something = bar);
|
||||
/// ```
|
||||
/// where the first message will be printed in const-eval,
|
||||
/// and the second message will be printed at runtime.
|
||||
// All uses of this macro are FIXME(const-hack).
|
||||
#[unstable(feature = "panic_internals", issue = "none")]
|
||||
#[doc(hidden)]
|
||||
pub macro const_panic {
|
||||
($const_msg:literal, $runtime_msg:literal, $($arg:ident : $ty:ty = $val:expr),* $(,)?) => {{
|
||||
// Wrap call to `const_eval_select` in a function so that we can
|
||||
// add the `rustc_allow_const_fn_unstable`. This is okay to do
|
||||
// because both variants will panic, just with different messages.
|
||||
#[rustc_allow_const_fn_unstable(const_eval_select)]
|
||||
#[inline(always)]
|
||||
#[track_caller]
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_panic", since = "CURRENT_RUSTC_VERSION"))]
|
||||
const fn do_panic($($arg: $ty),*) -> ! {
|
||||
$crate::intrinsics::const_eval_select!(
|
||||
@capture { $($arg: $ty),* } -> !:
|
||||
if const #[track_caller] {
|
||||
$crate::panic!($const_msg)
|
||||
} else #[track_caller] {
|
||||
$crate::panic!($runtime_msg)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
do_panic($($val),*)
|
||||
}},
|
||||
// We support leaving away the `val` expressions for *all* arguments
|
||||
// (but not for *some* arguments, that's too tricky).
|
||||
($const_msg:literal, $runtime_msg:literal, $($arg:ident : $ty:ty),* $(,)?) => {
|
||||
$crate::panic::const_panic!(
|
||||
$const_msg,
|
||||
$runtime_msg,
|
||||
$($arg: $ty = $arg),*
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
/// A version of `assert` that prints a non-formatting message in const contexts.
|
||||
///
|
||||
/// See [`const_panic!`].
|
||||
#[unstable(feature = "panic_internals", issue = "none")]
|
||||
#[doc(hidden)]
|
||||
pub macro const_assert {
|
||||
($condition: expr, $const_msg:literal, $runtime_msg:literal, $($arg:tt)*) => {{
|
||||
if !$crate::intrinsics::likely($condition) {
|
||||
$crate::panic::const_panic!($const_msg, $runtime_msg, $($arg)*)
|
||||
}
|
||||
}}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user