1use std::any::Any;
6use std::cell::RefCell;
7use std::panic::{catch_unwind, resume_unwind, AssertUnwindSafe};
8
9thread_local!(static PANIC_PAYLOAD: RefCell<Option<Box<dyn Any + Send>>> = RefCell::new(None));
10
11pub fn maybe_resume_unwind() {
13 if let Some(error) = PANIC_PAYLOAD.with(|result| result.borrow_mut().take()) {
14 resume_unwind(error);
15 }
16}
17
18#[inline(never)]
21pub fn wrap_panic(function: &mut dyn FnMut()) {
22 match catch_unwind(AssertUnwindSafe(function)) {
23 Ok(()) => {}
24 Err(payload) => {
25 PANIC_PAYLOAD.with(|opt_payload| {
26 let mut opt_payload = opt_payload.borrow_mut();
27 assert!(opt_payload.is_none());
28 *opt_payload = Some(payload);
29 });
30 }
31 }
32}