Skip to content

Commit

Permalink
Rollup merge of #78119 - fusion-engineering-forks:panic-use-as-str, r…
Browse files Browse the repository at this point in the history
…=Amanieu

Throw core::panic!("message") as &str instead of String.

This makes `core::panic!("message")` consistent with `std::panic!("message")`, which throws a `&str` and not a `String`.

This also makes any other panics from `core::panicking::panic` result in a `&str` rather than a `String`, which includes compiler-generated panics such as the panics generated for `mem::zeroed()`.

---

Demonstration:

```rust
use std::panic;
use std::any::Any;

fn main() {
    panic::set_hook(Box::new(|panic_info| check(panic_info.payload())));

    check(&*panic::catch_unwind(|| core::panic!("core")).unwrap_err());
    check(&*panic::catch_unwind(|| std::panic!("std")).unwrap_err());
}

fn check(msg: &(dyn Any + Send)) {
    if let Some(s) = msg.downcast_ref::<String>() {
        println!("Got a String: {:?}", s);
    } else if let Some(s) = msg.downcast_ref::<&str>() {
        println!("Got a &str: {:?}", s);
    }
}
```

Before:
```
Got a String: "core"
Got a String: "core"
Got a &str: "std"
Got a &str: "std"
```

After:
```
Got a &str: "core"
Got a &str: "core"
Got a &str: "std"
Got a &str: "std"
```
  • Loading branch information
jonas-schievink authored Oct 24, 2020
2 parents e12e972 + 9890217 commit e3808ed
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 3 deletions.
1 change: 1 addition & 0 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@
#![feature(exhaustive_patterns)]
#![feature(extend_one)]
#![feature(external_doc)]
#![feature(fmt_as_str)]
#![feature(fn_traits)]
#![feature(format_args_nl)]
#![feature(gen_future)]
Expand Down
18 changes: 17 additions & 1 deletion library/std/src/panicking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -478,10 +478,26 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! {
}
}

struct StrPanicPayload(&'static str);

unsafe impl BoxMeUp for StrPanicPayload {
fn take_box(&mut self) -> *mut (dyn Any + Send) {
Box::into_raw(Box::new(self.0))
}

fn get(&mut self) -> &(dyn Any + Send) {
&self.0
}
}

let loc = info.location().unwrap(); // The current implementation always returns Some
let msg = info.message().unwrap(); // The current implementation always returns Some
crate::sys_common::backtrace::__rust_end_short_backtrace(move || {
rust_panic_with_hook(&mut PanicPayload::new(msg), info.message(), loc);
if let Some(msg) = msg.as_str() {
rust_panic_with_hook(&mut StrPanicPayload(msg), info.message(), loc);
} else {
rust_panic_with_hook(&mut PanicPayload::new(msg), info.message(), loc);
}
})
}

Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ enum LR_NonZero {
fn test_panic_msg<T>(op: impl (FnOnce() -> T) + panic::UnwindSafe, msg: &str) {
let err = panic::catch_unwind(op).err();
assert_eq!(
err.as_ref().and_then(|a| a.downcast_ref::<String>()).map(|s| &**s),
Some(msg)
err.as_ref().and_then(|a| a.downcast_ref::<&str>()),
Some(&msg)
);
}

Expand Down

0 comments on commit e3808ed

Please sign in to comment.