diff options
| author | Gary Guo <gary@garyguo.net> | 2023-04-14 01:14:26 +0100 |
|---|---|---|
| committer | Gary Guo <gary@garyguo.net> | 2023-11-25 23:58:51 +0000 |
| commit | 4ccec4558fea4c649ef92874bb26f3e96ab8eb21 (patch) | |
| tree | d3ef12ebcbc76c8042d4209ae317351bf221a6ed /library/core/src | |
| parent | f5dc2653fdd8b5d177b2ccbd84057954340a89fc (diff) | |
| download | rust-4ccec4558fea4c649ef92874bb26f3e96ab8eb21.tar.gz rust-4ccec4558fea4c649ef92874bb26f3e96ab8eb21.zip | |
Add `debug_assert_nounwind`
Diffstat (limited to 'library/core/src')
| -rw-r--r-- | library/core/src/panic.rs | 21 | ||||
| -rw-r--r-- | library/core/src/panicking.rs | 52 |
2 files changed, 54 insertions, 19 deletions
diff --git a/library/core/src/panic.rs b/library/core/src/panic.rs index b7cd10b5b19..f5d18ca0b3f 100644 --- a/library/core/src/panic.rs +++ b/library/core/src/panic.rs @@ -139,6 +139,27 @@ pub macro unreachable_2021 { ), } +#[doc(hidden)] +#[unstable(feature = "core_panic", issue = "none")] +#[allow_internal_unstable(core_panic, const_format_args)] +#[rustc_macro_transparency = "semitransparent"] +pub macro debug_assert_nounwind { + ($cond:expr $(,)?) => { + if $crate::cfg!(debug_assertions) { + if !$cond { + $crate::panicking::panic_nounwind($crate::concat!("assertion failed: ", $crate::stringify!($cond))); + } + } + }, + ($cond:expr, $($arg:tt)+) => { + if $crate::cfg!(debug_assertions) { + if !$cond { + $crate::panicking::panic_nounwind_fmt($crate::const_format_args!($($arg)+), false); + } + } + }, +} + /// An internal trait used by std to pass data from std to `panic_unwind` and /// other panic runtimes. Not intended to be stabilized any time soon, do not /// use. diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index fa6e5fe5d17..1c906b7d3b4 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -82,28 +82,41 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! { // and unwinds anyway, we will hit the "unwinding out of nounwind function" guard, // which causes a "panic in a function that cannot unwind". #[rustc_nounwind] -pub fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: bool) -> ! { - if cfg!(feature = "panic_immediate_abort") { - super::intrinsics::abort() - } +#[rustc_const_unstable(feature = "core_panic", issue = "none")] +pub const fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: bool) -> ! { + fn runtime(fmt: fmt::Arguments<'_>, force_no_backtrace: bool) -> ! { + if cfg!(feature = "panic_immediate_abort") { + super::intrinsics::abort() + } - // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call - // that gets resolved to the `#[panic_handler]` function. - extern "Rust" { - #[lang = "panic_impl"] - fn panic_impl(pi: &PanicInfo<'_>) -> !; + // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call + // that gets resolved to the `#[panic_handler]` function. + extern "Rust" { + #[lang = "panic_impl"] + fn panic_impl(pi: &PanicInfo<'_>) -> !; + } + + // PanicInfo with the `can_unwind` flag set to false forces an abort. + let pi = PanicInfo::internal_constructor( + Some(&fmt), + Location::caller(), + /* can_unwind */ false, + force_no_backtrace, + ); + + // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call. + unsafe { panic_impl(&pi) } } - // PanicInfo with the `can_unwind` flag set to false forces an abort. - let pi = PanicInfo::internal_constructor( - Some(&fmt), - Location::caller(), - /* can_unwind */ false, - force_no_backtrace, - ); + #[inline] + const fn comptime(fmt: fmt::Arguments<'_>, _force_no_backtrace: bool) -> ! { + panic_fmt(fmt); + } - // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call. - unsafe { panic_impl(&pi) } + // SAFETY: const panic does not care about unwinding + unsafe { + super::intrinsics::const_eval_select((fmt, force_no_backtrace), comptime, runtime); + } } // Next we define a bunch of higher-level wrappers that all bottom out in the two core functions @@ -132,7 +145,8 @@ pub const fn panic(expr: &'static str) -> ! { #[cfg_attr(feature = "panic_immediate_abort", inline)] #[lang = "panic_nounwind"] // needed by codegen for non-unwinding panics #[rustc_nounwind] -pub fn panic_nounwind(expr: &'static str) -> ! { +#[rustc_const_unstable(feature = "core_panic", issue = "none")] +pub const fn panic_nounwind(expr: &'static str) -> ! { panic_nounwind_fmt(fmt::Arguments::new_const(&[expr]), /* force_no_backtrace */ false); } |
