-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Error in panic #103169
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error in panic #103169
Changes from all commits
55fbd97
0bfd9c5
fae2e3f
9d7a01e
e77cc50
c5db75e
78cff68
03df365
125171c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -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")] | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
/// The [`Error`] that caused this panic, if known. | ||||||||||
pub fn source(&self) -> Option<&(dyn Error + 'static)> { | ||||||||||
self.source | ||||||||||
Comment on lines
+70
to
+71
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
(etc.) See comment above. |
||||||||||
} | ||||||||||
|
||||||||||
/// Returns the payload associated with the panic. | ||||||||||
/// | ||||||||||
/// This will commonly, but not always, be a `&'static str` or [`String`]. | ||||||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -26,6 +26,7 @@ | |||||
issue = "none" | ||||||
)] | ||||||
|
||||||
use crate::error::Error; | ||||||
use crate::fmt; | ||||||
use crate::panic::{Location, PanicInfo}; | ||||||
|
||||||
|
@@ -54,19 +55,37 @@ pub const fn panic_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<'_>) -> !; | ||||||
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] | ||||||
// 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] | ||||||
#[unstable(feature = "error_in_panic", issue = "none")] | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not part of the public
Suggested change
|
||||||
pub fn panic_source(fmt: fmt::Arguments<'_>, source: &(dyn Error + 'static)) -> ! { | ||||||
if cfg!(feature = "panic_immediate_abort") { | ||||||
super::intrinsics::abort() | ||||||
} | ||||||
|
||||||
let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller(), 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) } | ||||||
} | ||||||
|
||||||
// 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. | ||||||
|
@@ -82,15 +101,8 @@ 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 pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller(), false); | ||||||
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) } | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// run-fail | ||
// needs-run-enabled | ||
// check-run-results | ||
|
||
#![allow(unused_imports)] | ||
#![feature(core_panic)] | ||
#![feature(error_in_core)] | ||
#![feature(error_in_panic)] | ||
|
||
extern crate core; | ||
|
||
use core::error; | ||
use core::panicking::panic_source; | ||
|
||
use std::error::Error; | ||
|
||
#[derive(Debug)] | ||
struct MyErr { | ||
super_source: SourceError, | ||
} | ||
|
||
#[derive(Debug)] | ||
struct SourceError {} | ||
|
||
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 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() { | ||
let source_error = SourceError {}; | ||
let source = MyErr { super_source: source_error }; | ||
panic_source(format_args!("here's my panic error message"), &source); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
thread 'main' panicked at 'here's my panic error message', $DIR/issue-103169-error-in-panic.rs:49: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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you open a tracking issue for this feature? Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tracking issue is here: #103820