From 55fbd9754adb190c9af6dabe6ddcc8ebe1c0a54c Mon Sep 17 00:00:00 2001 From: DebugSteven Date: Mon, 17 Oct 2022 14:42:29 -0600 Subject: [PATCH 1/9] add error source to panic info --- library/core/src/panic/panic_info.rs | 11 +++++++- library/core/src/panicking.rs | 19 +++++++++++-- library/std/src/lib.rs | 1 + library/std/src/panicking.rs | 16 +++++++---- src/test/ui/error-trait/error-in-panic.rs | 33 +++++++++++++++++++++++ 5 files changed, 72 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/error-trait/error-in-panic.rs diff --git a/library/core/src/panic/panic_info.rs b/library/core/src/panic/panic_info.rs index 0d385c9d18744..46258e1fb33c1 100644 --- a/library/core/src/panic/panic_info.rs +++ b/library/core/src/panic/panic_info.rs @@ -1,4 +1,5 @@ use crate::any::Any; +use crate::error::Error; use crate::fmt; use crate::panic::Location; @@ -30,6 +31,7 @@ use crate::panic::Location; pub struct PanicInfo<'a> { payload: &'a (dyn Any + Send), message: Option<&'a fmt::Arguments<'a>>, + source: Option<&'a (dyn Error + 'static)>, location: &'a Location<'a>, can_unwind: bool, } @@ -45,10 +47,11 @@ impl<'a> PanicInfo<'a> { pub fn internal_constructor( message: Option<&'a fmt::Arguments<'a>>, location: &'a Location<'a>, + source: Option<&'a (dyn Error + 'static)>, can_unwind: bool, ) -> Self { struct NoPayload; - PanicInfo { location, message, payload: &NoPayload, can_unwind } + PanicInfo { location, message, payload: &NoPayload, source, can_unwind } } #[unstable( @@ -62,6 +65,12 @@ impl<'a> PanicInfo<'a> { self.payload = info; } + #[unstable(feature = "error_in_panic", issue = "none")] + /// FIXME + pub fn source(&self) -> Option<&(dyn Error + 'static)> { + self.source + } + /// Returns the payload associated with the panic. /// /// This will commonly, but not always, be a `&'static str` or [`String`]. diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index efeb726ab8eb8..6e15f3ec95096 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -26,6 +26,7 @@ issue = "none" )] +use crate::error::Error; use crate::fmt; use crate::panic::{Location, PanicInfo}; @@ -50,6 +51,18 @@ const _: () = assert!(cfg!(panic = "abort"), "panic_immediate_abort requires -C #[rustc_do_not_const_check] // hooked by const-eval #[rustc_const_unstable(feature = "core_panic", issue = "none")] pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! { + panic_source(fmt, None) +} + +#[cold] +// If panic_immediate_abort, inline the abort call, +// otherwise avoid inlining because of it is cold path. +#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] +#[cfg_attr(feature = "panic_immediate_abort", inline)] +#[track_caller] +#[rustc_do_not_const_check] // hooked by const-eval +#[rustc_const_unstable(feature = "core_panic", issue = "none")] +pub const fn panic_source(fmt: fmt::Arguments<'_>, source: Option<& (dyn Error + 'static)>) -> ! { if cfg!(feature = "panic_immediate_abort") { super::intrinsics::abort() } @@ -61,7 +74,7 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! { fn panic_impl(pi: &PanicInfo<'_>) -> !; } - let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller(), true); + let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller(), source, true); // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call. unsafe { panic_impl(&pi) } @@ -90,7 +103,9 @@ pub fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>) -> ! { } // PanicInfo with the `can_unwind` flag set to false forces an abort. - let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller(), false); + let pieces = [msg]; + let fmt = fmt::Arguments::new_v1(&pieces, &[]); + let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller(), None, false); // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call. unsafe { panic_impl(&pi) } diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 71f3576c93d4b..383a44dd03d0b 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -278,6 +278,7 @@ #![feature(duration_constants)] #![feature(error_generic_member_access)] #![feature(error_in_core)] +#![feature(error_in_panic)] #![feature(error_iter)] #![feature(exact_size_is_empty)] #![feature(exclusive_wrapper)] diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index a46a29cbad608..4c4dfb4fd5205 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -13,6 +13,7 @@ use crate::panic::BacktraceStyle; use core::panic::{BoxMeUp, Location, PanicInfo}; use crate::any::Any; +use crate::error::Error; use crate::fmt; use crate::intrinsics; use crate::mem::{self, ManuallyDrop}; @@ -258,7 +259,9 @@ fn default_hook(info: &PanicInfo<'_>) { let write = |err: &mut dyn crate::io::Write| { let _ = writeln!(err, "thread '{name}' panicked at '{msg}', {location}"); - + if info.source().is_some() { + writeln!(err, "fun is not allowed"); + } static FIRST_PANIC: AtomicBool = AtomicBool::new(true); match backtrace { @@ -574,15 +577,17 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! { } let loc = info.location().unwrap(); // The current implementation always returns Some + let source = info.source(); let msg = info.message().unwrap(); // The current implementation always returns Some crate::sys_common::backtrace::__rust_end_short_backtrace(move || { if let Some(msg) = msg.as_str() { - rust_panic_with_hook(&mut StrPanicPayload(msg), info.message(), loc, info.can_unwind()); + rust_panic_with_hook(&mut StrPanicPayload(msg), info.message(), loc, source, info.can_unwind()); } else { rust_panic_with_hook( &mut PanicPayload::new(msg), info.message(), loc, + source, info.can_unwind(), ); } @@ -608,7 +613,7 @@ pub const fn begin_panic(msg: M) -> ! { let loc = Location::caller(); return crate::sys_common::backtrace::__rust_end_short_backtrace(move || { - rust_panic_with_hook(&mut PanicPayload::new(msg), None, loc, true) + rust_panic_with_hook(&mut PanicPayload::new(msg), None, loc, None, true) }); struct PanicPayload { @@ -653,6 +658,7 @@ fn rust_panic_with_hook( payload: &mut dyn BoxMeUp, message: Option<&fmt::Arguments<'_>>, location: &Location<'_>, + source: Option<& (dyn Error + 'static)>, can_unwind: bool, ) -> ! { let (must_abort, panics) = panic_count::increase(); @@ -670,13 +676,13 @@ fn rust_panic_with_hook( } else { // Unfortunately, this does not print a backtrace, because creating // a `Backtrace` will allocate, which we must to avoid here. - let panicinfo = PanicInfo::internal_constructor(message, location, can_unwind); + let panicinfo = PanicInfo::internal_constructor(message, location, source, can_unwind); rtprintpanic!("{panicinfo}\npanicked after panic::always_abort(), aborting.\n"); } crate::sys::abort_internal(); } - let mut info = PanicInfo::internal_constructor(message, location, can_unwind); + let mut info = PanicInfo::internal_constructor(message, location, source, can_unwind); let hook = HOOK.read().unwrap_or_else(PoisonError::into_inner); match *hook { // Some platforms (like wasm) know that printing to stderr won't ever actually diff --git a/src/test/ui/error-trait/error-in-panic.rs b/src/test/ui/error-trait/error-in-panic.rs new file mode 100644 index 0000000000000..809c80e4e5552 --- /dev/null +++ b/src/test/ui/error-trait/error-in-panic.rs @@ -0,0 +1,33 @@ +// run-fail +// check-run-results + +#![allow(unused_imports)] +#![feature(core_panic)] +#![feature(error_in_core)] + +extern crate core; + +use core::panicking::panic_source; +use core::error; + +#[derive (Debug)] +struct MyErr; + +use std::fmt; +impl fmt::Display for MyErr { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + write!(f, "my source error message") + } +} + +impl error::Error for MyErr { + +} + +fn main() { + std::env::set_var("RUST_BACKTRACE", "full"); + let source = MyErr; + //FIXME make the function do the Some wrapping for us + panic_source(format_args!("here's my panic error message"), Some(&source)); + +} From 0bfd9c5cb1d8d1e200bed528b6ca27a773b78a8c Mon Sep 17 00:00:00 2001 From: DebugSteven Date: Mon, 17 Oct 2022 15:32:09 -0600 Subject: [PATCH 2/9] chain source errors --- library/core/src/panicking.rs | 2 +- library/std/src/panicking.rs | 17 +++++++++---- src/test/ui/error-trait/error-in-panic.rs | 24 ++++++++++++++++-- .../ui/error-trait/error-in-panic.run.stderr | 25 +++++++++++++++++++ 4 files changed, 60 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/error-trait/error-in-panic.run.stderr diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index 6e15f3ec95096..30f3d21dc2670 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -62,7 +62,7 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! { #[track_caller] #[rustc_do_not_const_check] // hooked by const-eval #[rustc_const_unstable(feature = "core_panic", issue = "none")] -pub const fn panic_source(fmt: fmt::Arguments<'_>, source: Option<& (dyn Error + 'static)>) -> ! { +pub const fn panic_source(fmt: fmt::Arguments<'_>, source: Option<&(dyn Error + 'static)>) -> ! { if cfg!(feature = "panic_immediate_abort") { super::intrinsics::abort() } diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index 4c4dfb4fd5205..f41f12841063b 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -13,7 +13,7 @@ use crate::panic::BacktraceStyle; use core::panic::{BoxMeUp, Location, PanicInfo}; use crate::any::Any; -use crate::error::Error; +use crate::error::{Error, Report}; use crate::fmt; use crate::intrinsics; use crate::mem::{self, ManuallyDrop}; @@ -259,8 +259,9 @@ fn default_hook(info: &PanicInfo<'_>) { let write = |err: &mut dyn crate::io::Write| { let _ = writeln!(err, "thread '{name}' panicked at '{msg}', {location}"); - if info.source().is_some() { - writeln!(err, "fun is not allowed"); + if let Some(source) = info.source() { + let report = Report::new(source).pretty(true); + let _ = writeln!(err, "Source: {report}"); } static FIRST_PANIC: AtomicBool = AtomicBool::new(true); @@ -581,7 +582,13 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! { let msg = info.message().unwrap(); // The current implementation always returns Some crate::sys_common::backtrace::__rust_end_short_backtrace(move || { if let Some(msg) = msg.as_str() { - rust_panic_with_hook(&mut StrPanicPayload(msg), info.message(), loc, source, info.can_unwind()); + rust_panic_with_hook( + &mut StrPanicPayload(msg), + info.message(), + loc, + source, + info.can_unwind(), + ); } else { rust_panic_with_hook( &mut PanicPayload::new(msg), @@ -658,7 +665,7 @@ fn rust_panic_with_hook( payload: &mut dyn BoxMeUp, message: Option<&fmt::Arguments<'_>>, location: &Location<'_>, - source: Option<& (dyn Error + 'static)>, + source: Option<&(dyn Error + 'static)>, can_unwind: bool, ) -> ! { let (must_abort, panics) = panic_count::increase(); diff --git a/src/test/ui/error-trait/error-in-panic.rs b/src/test/ui/error-trait/error-in-panic.rs index 809c80e4e5552..eb61edafde8bc 100644 --- a/src/test/ui/error-trait/error-in-panic.rs +++ b/src/test/ui/error-trait/error-in-panic.rs @@ -10,8 +10,15 @@ extern crate core; use core::panicking::panic_source; use core::error; +use std::error::Error; + +#[derive (Debug)] +struct MyErr { + super_source: SourceError, +} + #[derive (Debug)] -struct MyErr; +struct SourceError {} use std::fmt; impl fmt::Display for MyErr { @@ -21,12 +28,25 @@ impl fmt::Display for MyErr { } impl error::Error for MyErr { + fn source(&self) -> Option<& (dyn Error + 'static)> { + Some(&self.super_source) + } +} + +impl fmt::Display for SourceError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + write!(f, "my source's source error message") + } +} + +impl error::Error for SourceError { } fn main() { std::env::set_var("RUST_BACKTRACE", "full"); - let source = MyErr; + let source_error = SourceError {}; + let source = MyErr {super_source: source_error}; //FIXME make the function do the Some wrapping for us panic_source(format_args!("here's my panic error message"), Some(&source)); diff --git a/src/test/ui/error-trait/error-in-panic.run.stderr b/src/test/ui/error-trait/error-in-panic.run.stderr new file mode 100644 index 0000000000000..8dd86512e7b67 --- /dev/null +++ b/src/test/ui/error-trait/error-in-panic.run.stderr @@ -0,0 +1,25 @@ +thread 'main' panicked at 'here's my panic error message', $DIR/error-in-panic.rs:51:5 +Source: my source error message + +Caused by: + my source's source error message +stack backtrace: + 0: 0x10347e5cc - ::fmt::h739002e9033ecbde + 1: 0x1034c1ef4 - core::fmt::write::h7ee3c88f1a3812c3 + 2: 0x103467ad8 - std::io::Write::write_fmt::h46e675c7a43a1dc6 + 3: 0x10347e494 - std::sys_common::backtrace::print::h2db63c69899aa986 + 4: 0x103441588 - std::panicking::default_hook::{{closure}}::hbf1cbfed6089b966 + 5: 0x103441348 - std::panicking::default_hook::h394fc36f8066489c + 6: 0x103441a3c - std::panicking::rust_panic_with_hook::h022616bb2ba4e178 + 7: 0x10344907c - std::panicking::begin_panic_handler::{{closure}}::h3128246bc073fcbe + 8: 0x103448fdc - std::sys_common::backtrace::__rust_end_short_backtrace::hbb524939a68ed8b5 + 9: 0x103441660 - _rust_begin_unwind + 10: 0x1034dd910 - core::panicking::panic_source::hf14287b3ee2e7392 + 11: 0x102aeb728 - error_in_panic::main::hf4bbb2ae489ce4fd + 12: 0x102aeb404 - core::ops::function::FnOnce::call_once::h0f54538c8c239b20 + 13: 0x102aeafd8 - std::sys_common::backtrace::__rust_begin_short_backtrace::h2b8f58dd23d62fa6 + 14: 0x102aeb074 - std::rt::lang_start::{{closure}}::h6d7fe7ddaa109f16 + 15: 0x10344478c - std::panicking::try::h0286e30fd7b2d786 + 16: 0x103452248 - std::rt::lang_start_internal::hc2ec5a7105141124 + 17: 0x102aeb048 - std::rt::lang_start::h8ea75b901d46518a + 18: 0x102aeb7f0 - _main From fae2e3f428a27332cde2b1a0153f51b3947451a1 Mon Sep 17 00:00:00 2001 From: DebugSteven Date: Mon, 17 Oct 2022 16:19:17 -0600 Subject: [PATCH 3/9] cleanup FIXMEs --- library/core/src/panic/panic_info.rs | 2 +- library/core/src/panicking.rs | 21 ++++++++++++++--- src/test/ui/error-trait/error-in-panic.rs | 5 +--- .../ui/error-trait/error-in-panic.run.stderr | 23 ++----------------- 4 files changed, 22 insertions(+), 29 deletions(-) diff --git a/library/core/src/panic/panic_info.rs b/library/core/src/panic/panic_info.rs index 46258e1fb33c1..504d41bc4839b 100644 --- a/library/core/src/panic/panic_info.rs +++ b/library/core/src/panic/panic_info.rs @@ -66,7 +66,7 @@ impl<'a> PanicInfo<'a> { } #[unstable(feature = "error_in_panic", issue = "none")] - /// FIXME + /// The lower-level source of this panic, if any. pub fn source(&self) -> Option<&(dyn Error + 'static)> { self.source } diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index 30f3d21dc2670..8a96e4ae3e0d4 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -51,7 +51,22 @@ const _: () = assert!(cfg!(panic = "abort"), "panic_immediate_abort requires -C #[rustc_do_not_const_check] // hooked by const-eval #[rustc_const_unstable(feature = "core_panic", issue = "none")] pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! { - panic_source(fmt, None) + //panic_source(fmt, None) + 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<'_>) -> !; + } + + let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller(), None, true); + + // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call. + unsafe { panic_impl(&pi) } } #[cold] @@ -62,7 +77,7 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! { #[track_caller] #[rustc_do_not_const_check] // hooked by const-eval #[rustc_const_unstable(feature = "core_panic", issue = "none")] -pub const fn panic_source(fmt: fmt::Arguments<'_>, source: Option<&(dyn Error + 'static)>) -> ! { +pub const fn panic_source(fmt: fmt::Arguments<'_>, source: &(dyn Error + 'static)) -> ! { if cfg!(feature = "panic_immediate_abort") { super::intrinsics::abort() } @@ -74,7 +89,7 @@ pub const fn panic_source(fmt: fmt::Arguments<'_>, source: Option<&(dyn Error + fn panic_impl(pi: &PanicInfo<'_>) -> !; } - let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller(), source, true); + let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller(), Some(source), true); // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call. unsafe { panic_impl(&pi) } diff --git a/src/test/ui/error-trait/error-in-panic.rs b/src/test/ui/error-trait/error-in-panic.rs index eb61edafde8bc..ce354f0ce7372 100644 --- a/src/test/ui/error-trait/error-in-panic.rs +++ b/src/test/ui/error-trait/error-in-panic.rs @@ -44,10 +44,7 @@ impl error::Error for SourceError { } fn main() { - std::env::set_var("RUST_BACKTRACE", "full"); let source_error = SourceError {}; let source = MyErr {super_source: source_error}; - //FIXME make the function do the Some wrapping for us - panic_source(format_args!("here's my panic error message"), Some(&source)); - + panic_source(format_args!("here's my panic error message"), &source); } diff --git a/src/test/ui/error-trait/error-in-panic.run.stderr b/src/test/ui/error-trait/error-in-panic.run.stderr index 8dd86512e7b67..931392e63491e 100644 --- a/src/test/ui/error-trait/error-in-panic.run.stderr +++ b/src/test/ui/error-trait/error-in-panic.run.stderr @@ -1,25 +1,6 @@ -thread 'main' panicked at 'here's my panic error message', $DIR/error-in-panic.rs:51:5 +thread 'main' panicked at 'here's my panic error message', $DIR/error-in-panic.rs:49:5 Source: my source error message Caused by: my source's source error message -stack backtrace: - 0: 0x10347e5cc - ::fmt::h739002e9033ecbde - 1: 0x1034c1ef4 - core::fmt::write::h7ee3c88f1a3812c3 - 2: 0x103467ad8 - std::io::Write::write_fmt::h46e675c7a43a1dc6 - 3: 0x10347e494 - std::sys_common::backtrace::print::h2db63c69899aa986 - 4: 0x103441588 - std::panicking::default_hook::{{closure}}::hbf1cbfed6089b966 - 5: 0x103441348 - std::panicking::default_hook::h394fc36f8066489c - 6: 0x103441a3c - std::panicking::rust_panic_with_hook::h022616bb2ba4e178 - 7: 0x10344907c - std::panicking::begin_panic_handler::{{closure}}::h3128246bc073fcbe - 8: 0x103448fdc - std::sys_common::backtrace::__rust_end_short_backtrace::hbb524939a68ed8b5 - 9: 0x103441660 - _rust_begin_unwind - 10: 0x1034dd910 - core::panicking::panic_source::hf14287b3ee2e7392 - 11: 0x102aeb728 - error_in_panic::main::hf4bbb2ae489ce4fd - 12: 0x102aeb404 - core::ops::function::FnOnce::call_once::h0f54538c8c239b20 - 13: 0x102aeafd8 - std::sys_common::backtrace::__rust_begin_short_backtrace::h2b8f58dd23d62fa6 - 14: 0x102aeb074 - std::rt::lang_start::{{closure}}::h6d7fe7ddaa109f16 - 15: 0x10344478c - std::panicking::try::h0286e30fd7b2d786 - 16: 0x103452248 - std::rt::lang_start_internal::hc2ec5a7105141124 - 17: 0x102aeb048 - std::rt::lang_start::h8ea75b901d46518a - 18: 0x102aeb7f0 - _main +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace From 9d7a01e49e95a48c4986049bef5bed723f01e9e7 Mon Sep 17 00:00:00 2001 From: DebugSteven Date: Thu, 27 Oct 2022 16:36:13 -0600 Subject: [PATCH 4/9] cleanup and formatting --- library/core/src/panic/panic_info.rs | 2 +- library/core/src/panicking.rs | 22 +++++++--------------- library/std/src/panicking.rs | 7 +++---- 3 files changed, 11 insertions(+), 20 deletions(-) diff --git a/library/core/src/panic/panic_info.rs b/library/core/src/panic/panic_info.rs index 504d41bc4839b..12cef7a1c3bf6 100644 --- a/library/core/src/panic/panic_info.rs +++ b/library/core/src/panic/panic_info.rs @@ -66,7 +66,7 @@ impl<'a> PanicInfo<'a> { } #[unstable(feature = "error_in_panic", issue = "none")] - /// The lower-level source of this panic, if any. + /// The [`Error`] that caused this panic, if known. pub fn source(&self) -> Option<&(dyn Error + 'static)> { self.source } diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index 8a96e4ae3e0d4..965fd0fbf3448 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -51,18 +51,10 @@ const _: () = assert!(cfg!(panic = "abort"), "panic_immediate_abort requires -C #[rustc_do_not_const_check] // hooked by const-eval #[rustc_const_unstable(feature = "core_panic", issue = "none")] pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! { - //panic_source(fmt, None) 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<'_>) -> !; - } - let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller(), None, true); // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call. @@ -82,19 +74,19 @@ pub const fn panic_source(fmt: fmt::Arguments<'_>, source: &(dyn Error + 'static 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<'_>) -> !; - } - let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller(), Some(source), true); // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call. unsafe { panic_impl(&pi) } } +// 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<'_>) -> !; +} + /// Like `panic_fmt`, but for non-unwinding panics. /// /// Has to be a separate function so that it can carry the `rustc_nounwind` attribute. diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index f41f12841063b..6c2501da21a78 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -261,7 +261,7 @@ fn default_hook(info: &PanicInfo<'_>) { let _ = writeln!(err, "thread '{name}' panicked at '{msg}', {location}"); if let Some(source) = info.source() { let report = Report::new(source).pretty(true); - let _ = writeln!(err, "Source: {report}"); + let _ = writeln!(err, "\nSource: {report}\n"); } static FIRST_PANIC: AtomicBool = AtomicBool::new(true); @@ -578,7 +578,6 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! { } let loc = info.location().unwrap(); // The current implementation always returns Some - let source = info.source(); let msg = info.message().unwrap(); // The current implementation always returns Some crate::sys_common::backtrace::__rust_end_short_backtrace(move || { if let Some(msg) = msg.as_str() { @@ -586,7 +585,7 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! { &mut StrPanicPayload(msg), info.message(), loc, - source, + info.source(), info.can_unwind(), ); } else { @@ -594,7 +593,7 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! { &mut PanicPayload::new(msg), info.message(), loc, - source, + info.source(), info.can_unwind(), ); } From e77cc5049506e11548f573c9c327bbcfd174fdc2 Mon Sep 17 00:00:00 2001 From: DebugSteven Date: Mon, 31 Oct 2022 16:01:23 -0600 Subject: [PATCH 5/9] remove const --- library/core/src/panicking.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index 965fd0fbf3448..cc08b71f073d8 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -67,9 +67,8 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! { #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[track_caller] -#[rustc_do_not_const_check] // hooked by const-eval -#[rustc_const_unstable(feature = "core_panic", issue = "none")] -pub const fn panic_source(fmt: fmt::Arguments<'_>, source: &(dyn Error + 'static)) -> ! { +#[unstable(feature = "error_in_panic", issue = "none")] +pub fn panic_source(fmt: fmt::Arguments<'_>, source: &(dyn Error + 'static)) -> ! { if cfg!(feature = "panic_immediate_abort") { super::intrinsics::abort() } From c5db75e2f882034927537b8203fa20f0a1abc9e2 Mon Sep 17 00:00:00 2001 From: DebugSteven Date: Mon, 7 Nov 2022 15:31:03 -0700 Subject: [PATCH 6/9] update test --- src/test/ui/error-trait/error-in-panic.rs | 1 + src/test/ui/error-trait/error-in-panic.run.stderr | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/test/ui/error-trait/error-in-panic.rs b/src/test/ui/error-trait/error-in-panic.rs index ce354f0ce7372..702d85d51dd7a 100644 --- a/src/test/ui/error-trait/error-in-panic.rs +++ b/src/test/ui/error-trait/error-in-panic.rs @@ -4,6 +4,7 @@ #![allow(unused_imports)] #![feature(core_panic)] #![feature(error_in_core)] +#![feature(error_in_panic)] extern crate core; diff --git a/src/test/ui/error-trait/error-in-panic.run.stderr b/src/test/ui/error-trait/error-in-panic.run.stderr index 931392e63491e..ec8e18d20ce50 100644 --- a/src/test/ui/error-trait/error-in-panic.run.stderr +++ b/src/test/ui/error-trait/error-in-panic.run.stderr @@ -1,6 +1,8 @@ -thread 'main' panicked at 'here's my panic error message', $DIR/error-in-panic.rs:49:5 +thread 'main' panicked at 'here's my panic error message', $DIR/error-in-panic.rs:50:5 + Source: my source error message Caused by: my source's source error message + note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace From 78cff688c89500fde5dbc2954dd97574d840ea69 Mon Sep 17 00:00:00 2001 From: DebugSteven Date: Thu, 13 Apr 2023 17:41:54 -0600 Subject: [PATCH 7/9] move tests --- .../ui/errors/issue-103169-error-in-panic.rs | 14 ++++++-------- .../ui/errors/issue-103169-error-in-panic.stderr | 0 2 files changed, 6 insertions(+), 8 deletions(-) rename src/test/ui/error-trait/error-in-panic.rs => tests/ui/errors/issue-103169-error-in-panic.rs (82%) rename src/test/ui/error-trait/error-in-panic.run.stderr => tests/ui/errors/issue-103169-error-in-panic.stderr (100%) diff --git a/src/test/ui/error-trait/error-in-panic.rs b/tests/ui/errors/issue-103169-error-in-panic.rs similarity index 82% rename from src/test/ui/error-trait/error-in-panic.rs rename to tests/ui/errors/issue-103169-error-in-panic.rs index 702d85d51dd7a..dc8a09d2be60d 100644 --- a/src/test/ui/error-trait/error-in-panic.rs +++ b/tests/ui/errors/issue-103169-error-in-panic.rs @@ -8,17 +8,17 @@ extern crate core; -use core::panicking::panic_source; use core::error; +use core::panicking::panic_source; use std::error::Error; -#[derive (Debug)] +#[derive(Debug)] struct MyErr { super_source: SourceError, } -#[derive (Debug)] +#[derive(Debug)] struct SourceError {} use std::fmt; @@ -29,7 +29,7 @@ impl fmt::Display for MyErr { } impl error::Error for MyErr { - fn source(&self) -> Option<& (dyn Error + 'static)> { + fn source(&self) -> Option<&(dyn Error + 'static)> { Some(&self.super_source) } } @@ -40,12 +40,10 @@ impl fmt::Display for SourceError { } } -impl error::Error for SourceError { - -} +impl error::Error for SourceError {} fn main() { let source_error = SourceError {}; - let source = MyErr {super_source: source_error}; + let source = MyErr { super_source: source_error }; panic_source(format_args!("here's my panic error message"), &source); } diff --git a/src/test/ui/error-trait/error-in-panic.run.stderr b/tests/ui/errors/issue-103169-error-in-panic.stderr similarity index 100% rename from src/test/ui/error-trait/error-in-panic.run.stderr rename to tests/ui/errors/issue-103169-error-in-panic.stderr From 03df365b5601171467c38f046eb8ac8b193051c5 Mon Sep 17 00:00:00 2001 From: DebugSteven Date: Fri, 14 Apr 2023 13:30:55 -0600 Subject: [PATCH 8/9] fix errors introduced in rebase --- library/core/src/panicking.rs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index cc08b71f073d8..f7614951cf253 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -101,16 +101,7 @@ pub fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>) -> ! { 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<'_>) -> !; - } - // PanicInfo with the `can_unwind` flag set to false forces an abort. - let pieces = [msg]; - let fmt = fmt::Arguments::new_v1(&pieces, &[]); let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller(), None, false); // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call. From 125171c9f80d818df2ba53525c0e535c6b6ccf1d Mon Sep 17 00:00:00 2001 From: DebugSteven Date: Fri, 14 Apr 2023 16:03:05 -0600 Subject: [PATCH 9/9] fix test --- tests/ui/errors/issue-103169-error-in-panic.rs | 1 + ...r-in-panic.stderr => issue-103169-error-in-panic.run.stderr} | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) rename tests/ui/errors/{issue-103169-error-in-panic.stderr => issue-103169-error-in-panic.run.stderr} (86%) diff --git a/tests/ui/errors/issue-103169-error-in-panic.rs b/tests/ui/errors/issue-103169-error-in-panic.rs index dc8a09d2be60d..5589c32b33ad8 100644 --- a/tests/ui/errors/issue-103169-error-in-panic.rs +++ b/tests/ui/errors/issue-103169-error-in-panic.rs @@ -1,4 +1,5 @@ // run-fail +// needs-run-enabled // check-run-results #![allow(unused_imports)] diff --git a/tests/ui/errors/issue-103169-error-in-panic.stderr b/tests/ui/errors/issue-103169-error-in-panic.run.stderr similarity index 86% rename from tests/ui/errors/issue-103169-error-in-panic.stderr rename to tests/ui/errors/issue-103169-error-in-panic.run.stderr index ec8e18d20ce50..c3747a42da778 100644 --- a/tests/ui/errors/issue-103169-error-in-panic.stderr +++ b/tests/ui/errors/issue-103169-error-in-panic.run.stderr @@ -1,4 +1,4 @@ -thread 'main' panicked at 'here's my panic error message', $DIR/error-in-panic.rs:50:5 +thread 'main' panicked at 'here's my panic error message', $DIR/issue-103169-error-in-panic.rs:49:5 Source: my source error message