Skip to content

Commit 0bfd9c5

Browse files
committed
chain source errors
1 parent 55fbd97 commit 0bfd9c5

File tree

4 files changed

+60
-8
lines changed

4 files changed

+60
-8
lines changed

library/core/src/panicking.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
6262
#[track_caller]
6363
#[rustc_do_not_const_check] // hooked by const-eval
6464
#[rustc_const_unstable(feature = "core_panic", issue = "none")]
65-
pub const fn panic_source(fmt: fmt::Arguments<'_>, source: Option<& (dyn Error + 'static)>) -> ! {
65+
pub const fn panic_source(fmt: fmt::Arguments<'_>, source: Option<&(dyn Error + 'static)>) -> ! {
6666
if cfg!(feature = "panic_immediate_abort") {
6767
super::intrinsics::abort()
6868
}

library/std/src/panicking.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::panic::BacktraceStyle;
1313
use core::panic::{BoxMeUp, Location, PanicInfo};
1414

1515
use crate::any::Any;
16-
use crate::error::Error;
16+
use crate::error::{Error, Report};
1717
use crate::fmt;
1818
use crate::intrinsics;
1919
use crate::mem::{self, ManuallyDrop};
@@ -259,8 +259,9 @@ fn default_hook(info: &PanicInfo<'_>) {
259259

260260
let write = |err: &mut dyn crate::io::Write| {
261261
let _ = writeln!(err, "thread '{name}' panicked at '{msg}', {location}");
262-
if info.source().is_some() {
263-
writeln!(err, "fun is not allowed");
262+
if let Some(source) = info.source() {
263+
let report = Report::new(source).pretty(true);
264+
let _ = writeln!(err, "Source: {report}");
264265
}
265266
static FIRST_PANIC: AtomicBool = AtomicBool::new(true);
266267

@@ -581,7 +582,13 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! {
581582
let msg = info.message().unwrap(); // The current implementation always returns Some
582583
crate::sys_common::backtrace::__rust_end_short_backtrace(move || {
583584
if let Some(msg) = msg.as_str() {
584-
rust_panic_with_hook(&mut StrPanicPayload(msg), info.message(), loc, source, info.can_unwind());
585+
rust_panic_with_hook(
586+
&mut StrPanicPayload(msg),
587+
info.message(),
588+
loc,
589+
source,
590+
info.can_unwind(),
591+
);
585592
} else {
586593
rust_panic_with_hook(
587594
&mut PanicPayload::new(msg),
@@ -658,7 +665,7 @@ fn rust_panic_with_hook(
658665
payload: &mut dyn BoxMeUp,
659666
message: Option<&fmt::Arguments<'_>>,
660667
location: &Location<'_>,
661-
source: Option<& (dyn Error + 'static)>,
668+
source: Option<&(dyn Error + 'static)>,
662669
can_unwind: bool,
663670
) -> ! {
664671
let (must_abort, panics) = panic_count::increase();

src/test/ui/error-trait/error-in-panic.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,15 @@ extern crate core;
1010
use core::panicking::panic_source;
1111
use core::error;
1212

13+
use std::error::Error;
14+
15+
#[derive (Debug)]
16+
struct MyErr {
17+
super_source: SourceError,
18+
}
19+
1320
#[derive (Debug)]
14-
struct MyErr;
21+
struct SourceError {}
1522

1623
use std::fmt;
1724
impl fmt::Display for MyErr {
@@ -21,12 +28,25 @@ impl fmt::Display for MyErr {
2128
}
2229

2330
impl error::Error for MyErr {
31+
fn source(&self) -> Option<& (dyn Error + 'static)> {
32+
Some(&self.super_source)
33+
}
34+
}
35+
36+
impl fmt::Display for SourceError {
37+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
38+
write!(f, "my source's source error message")
39+
}
40+
}
41+
42+
impl error::Error for SourceError {
2443

2544
}
2645

2746
fn main() {
2847
std::env::set_var("RUST_BACKTRACE", "full");
29-
let source = MyErr;
48+
let source_error = SourceError {};
49+
let source = MyErr {super_source: source_error};
3050
//FIXME make the function do the Some wrapping for us
3151
panic_source(format_args!("here's my panic error message"), Some(&source));
3252

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
thread 'main' panicked at 'here's my panic error message', $DIR/error-in-panic.rs:51:5
2+
Source: my source error message
3+
4+
Caused by:
5+
my source's source error message
6+
stack backtrace:
7+
0: 0x10347e5cc - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h739002e9033ecbde
8+
1: 0x1034c1ef4 - core::fmt::write::h7ee3c88f1a3812c3
9+
2: 0x103467ad8 - std::io::Write::write_fmt::h46e675c7a43a1dc6
10+
3: 0x10347e494 - std::sys_common::backtrace::print::h2db63c69899aa986
11+
4: 0x103441588 - std::panicking::default_hook::{{closure}}::hbf1cbfed6089b966
12+
5: 0x103441348 - std::panicking::default_hook::h394fc36f8066489c
13+
6: 0x103441a3c - std::panicking::rust_panic_with_hook::h022616bb2ba4e178
14+
7: 0x10344907c - std::panicking::begin_panic_handler::{{closure}}::h3128246bc073fcbe
15+
8: 0x103448fdc - std::sys_common::backtrace::__rust_end_short_backtrace::hbb524939a68ed8b5
16+
9: 0x103441660 - _rust_begin_unwind
17+
10: 0x1034dd910 - core::panicking::panic_source::hf14287b3ee2e7392
18+
11: 0x102aeb728 - error_in_panic::main::hf4bbb2ae489ce4fd
19+
12: 0x102aeb404 - core::ops::function::FnOnce::call_once::h0f54538c8c239b20
20+
13: 0x102aeafd8 - std::sys_common::backtrace::__rust_begin_short_backtrace::h2b8f58dd23d62fa6
21+
14: 0x102aeb074 - std::rt::lang_start::{{closure}}::h6d7fe7ddaa109f16
22+
15: 0x10344478c - std::panicking::try::h0286e30fd7b2d786
23+
16: 0x103452248 - std::rt::lang_start_internal::hc2ec5a7105141124
24+
17: 0x102aeb048 - std::rt::lang_start::h8ea75b901d46518a
25+
18: 0x102aeb7f0 - _main

0 commit comments

Comments
 (0)