about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMara Bos <m-ou.se@m-ou.se>2023-10-02 14:17:16 +0200
committerMara Bos <m-ou.se@m-ou.se>2024-06-11 15:46:59 +0200
commit1642de33d3c4e59f3b4a766d0ad1abe046f0433f (patch)
tree4a4229baf01bb7af3ab8581cf69cf606c2223e9d
parent22f7399b32dcf1bd4d38b7e88a9b482fba889a8f (diff)
downloadrust-1642de33d3c4e59f3b4a766d0ad1abe046f0433f.tar.gz
rust-1642de33d3c4e59f3b4a766d0ad1abe046f0433f.zip
Impl Display for PanicPayload to simplify things.
-rw-r--r--library/core/src/panic.rs2
-rw-r--r--library/std/src/panicking.rs37
2 files changed, 29 insertions, 10 deletions
diff --git a/library/core/src/panic.rs b/library/core/src/panic.rs
index 8771f40f9b4..c9f3702e178 100644
--- a/library/core/src/panic.rs
+++ b/library/core/src/panic.rs
@@ -144,7 +144,7 @@ pub macro unreachable_2021 {
 /// use.
 #[unstable(feature = "std_internals", issue = "none")]
 #[doc(hidden)]
-pub unsafe trait PanicPayload {
+pub unsafe trait PanicPayload: crate::fmt::Display {
     /// Take full ownership of the contents.
     /// The return type is actually `Box<dyn Any + Send>`, but we cannot use `Box` in core.
     ///
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index a460f41b93d..362aa8d06f3 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -625,6 +625,12 @@ pub fn begin_panic_handler(info: &core::panic::PanicInfo<'_>) -> ! {
         }
     }
 
+    impl fmt::Display for FormatStringPayload<'_> {
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            if let Some(s) = &self.string { f.write_str(s) } else { f.write_fmt(*self.inner) }
+        }
+    }
+
     struct StaticStrPayload(&'static str);
 
     unsafe impl PanicPayload for StaticStrPayload {
@@ -637,13 +643,18 @@ pub fn begin_panic_handler(info: &core::panic::PanicInfo<'_>) -> ! {
         }
     }
 
+    impl fmt::Display for StaticStrPayload {
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            f.write_str(self.0)
+        }
+    }
+
     let loc = info.location().unwrap(); // The current implementation always returns Some
     let msg = info.message();
     crate::sys_common::backtrace::__rust_end_short_backtrace(move || {
         if let Some(s) = msg.as_str() {
             rust_panic_with_hook(
                 &mut StaticStrPayload(s),
-                Some(msg),
                 loc,
                 info.can_unwind(),
                 info.force_no_backtrace(),
@@ -651,7 +662,6 @@ pub fn begin_panic_handler(info: &core::panic::PanicInfo<'_>) -> ! {
         } else {
             rust_panic_with_hook(
                 &mut FormatStringPayload { inner: &msg, string: None },
-                Some(msg),
                 loc,
                 info.can_unwind(),
                 info.force_no_backtrace(),
@@ -681,7 +691,6 @@ pub const fn begin_panic<M: Any + Send>(msg: M) -> ! {
     return crate::sys_common::backtrace::__rust_end_short_backtrace(move || {
         rust_panic_with_hook(
             &mut Payload::new(msg),
-            None,
             loc,
             /* can_unwind */ true,
             /* force_no_backtrace */ false,
@@ -719,6 +728,15 @@ pub const fn begin_panic<M: Any + Send>(msg: M) -> ! {
             }
         }
     }
+
+    impl<A: Send + 'static> fmt::Display for Payload<A> {
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            match &self.inner {
+                Some(a) => f.write_str(payload_as_str(a)),
+                None => process::abort(),
+            }
+        }
+    }
 }
 
 fn payload_as_str(payload: &dyn Any) -> &str {
@@ -738,7 +756,6 @@ fn payload_as_str(payload: &dyn Any) -> &str {
 /// abort or unwind.
 fn rust_panic_with_hook(
     payload: &mut dyn PanicPayload,
-    message: Option<fmt::Arguments<'_>>,
     location: &Location<'_>,
     can_unwind: bool,
     force_no_backtrace: bool,
@@ -765,11 +782,7 @@ fn rust_panic_with_hook(
             panic_count::MustAbort::AlwaysAbort => {
                 // Unfortunately, this does not print a backtrace, because creating
                 // a `Backtrace` will allocate, which we must avoid here.
-                if let Some(message) = message {
-                    rtprintpanic!("aborting due to panic at {location}:\n{message}\n");
-                } else {
-                    rtprintpanic!("aborting due to panic at {location}\n");
-                }
+                rtprintpanic!("aborting due to panic at {location}:\n{payload}\n");
             }
         }
         crate::sys::abort_internal();
@@ -825,6 +838,12 @@ pub fn rust_panic_without_hook(payload: Box<dyn Any + Send>) -> ! {
         }
     }
 
+    impl fmt::Display for RewrapBox {
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            f.write_str(payload_as_str(&self.0))
+        }
+    }
+
     rust_panic(&mut RewrapBox(payload))
 }