]> git.proxmox.com Git - rustc.git/blame - library/std/src/panic.rs
New upstream version 1.51.0+dfsg1
[rustc.git] / library / std / src / panic.rs
CommitLineData
ff7c6d11 1//! Panic support in the standard library.
9cc50fc6 2
54a0048b 3#![stable(feature = "std_panic", since = "1.9.0")]
9cc50fc6 4
532ac7d7
XL
5use crate::any::Any;
6use crate::cell::UnsafeCell;
48663c56 7use crate::collections;
532ac7d7
XL
8use crate::fmt;
9use crate::future::Future;
532ac7d7
XL
10use crate::ops::{Deref, DerefMut};
11use crate::panicking;
60c5eb7d
XL
12use crate::pin::Pin;
13use crate::ptr::{NonNull, Unique};
532ac7d7 14use crate::rc::Rc;
5869c6ff 15use crate::stream::Stream;
e74abb32 16use crate::sync::atomic;
60c5eb7d 17use crate::sync::{Arc, Mutex, RwLock};
532ac7d7
XL
18use crate::task::{Context, Poll};
19use crate::thread::Result;
9cc50fc6 20
5869c6ff
XL
21#[doc(hidden)]
22#[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]
23#[allow_internal_unstable(libstd_sys_internals)]
24#[cfg_attr(not(test), rustc_diagnostic_item = "std_panic_2015_macro")]
25#[rustc_macro_transparency = "semitransparent"]
26pub macro panic_2015 {
27 () => ({
28 $crate::rt::begin_panic("explicit panic")
29 }),
30 ($msg:expr $(,)?) => ({
31 $crate::rt::begin_panic($msg)
32 }),
33 ($fmt:expr, $($arg:tt)+) => ({
34 $crate::rt::begin_panic_fmt(&$crate::format_args!($fmt, $($arg)+))
35 }),
36}
37
38#[doc(hidden)]
39#[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]
40pub use core::panic::panic_2021;
41
a7813a04 42#[stable(feature = "panic_hooks", since = "1.10.0")]
60c5eb7d 43pub use crate::panicking::{set_hook, take_hook};
0531ce1d
XL
44
45#[stable(feature = "panic_hooks", since = "1.10.0")]
60c5eb7d 46pub use core::panic::{Location, PanicInfo};
54a0048b 47
29967ef6
XL
48/// Panic the current thread with the given message as the panic payload.
49///
50/// The message can be of any (`Any + Send`) type, not just strings.
51///
52/// The message is wrapped in a `Box<'static + Any + Send>`, which can be
53/// accessed later using [`PanicInfo::payload`].
54///
55/// See the [`panic!`] macro for more information about panicking.
5869c6ff 56#[stable(feature = "panic_any", since = "1.51.0")]
29967ef6 57#[inline]
5869c6ff 58pub fn panic_any<M: 'static + Any + Send>(msg: M) -> ! {
29967ef6
XL
59 crate::panicking::begin_panic(msg);
60}
61
9cc50fc6
SL
62/// A marker trait which represents "panic safe" types in Rust.
63///
64/// This trait is implemented by default for many types and behaves similarly in
83c7162d
XL
65/// terms of inference of implementation to the [`Send`] and [`Sync`] traits. The
66/// purpose of this trait is to encode what types are safe to cross a [`catch_unwind`]
3157f602 67/// boundary with no fear of unwind safety.
9cc50fc6 68///
3157f602 69/// ## What is unwind safety?
9cc50fc6
SL
70///
71/// In Rust a function can "return" early if it either panics or calls a
72/// function which transitively panics. This sort of control flow is not always
73/// anticipated, and has the possibility of causing subtle bugs through a
3b2f2976 74/// combination of two critical components:
9cc50fc6
SL
75///
76/// 1. A data structure is in a temporarily invalid state when the thread
77/// panics.
78/// 2. This broken invariant is then later observed.
79///
80/// Typically in Rust, it is difficult to perform step (2) because catching a
81/// panic involves either spawning a thread (which in turns makes it difficult
3157f602 82/// to later witness broken invariants) or using the `catch_unwind` function in this
9cc50fc6 83/// module. Additionally, even if an invariant is witnessed, it typically isn't a
3157f602 84/// problem in Rust because there are no uninitialized values (like in C or C++).
9cc50fc6
SL
85///
86/// It is possible, however, for **logical** invariants to be broken in Rust,
3157f602 87/// which can end up causing behavioral bugs. Another key aspect of unwind safety
9cc50fc6
SL
88/// in Rust is that, in the absence of `unsafe` code, a panic cannot lead to
89/// memory unsafety.
90///
3157f602
XL
91/// That was a bit of a whirlwind tour of unwind safety, but for more information
92/// about unwind safety and how it applies to Rust, see an [associated RFC][rfc].
9cc50fc6
SL
93///
94/// [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1236-stabilize-catch-panic.md
95///
a7813a04 96/// ## What is `UnwindSafe`?
9cc50fc6 97///
3157f602 98/// Now that we've got an idea of what unwind safety is in Rust, it's also
9cc50fc6 99/// important to understand what this trait represents. As mentioned above, one
3157f602 100/// way to witness broken invariants is through the `catch_unwind` function in this
9cc50fc6
SL
101/// module as it allows catching a panic and then re-using the environment of
102/// the closure.
103///
a7813a04 104/// Simply put, a type `T` implements `UnwindSafe` if it cannot easily allow
3157f602 105/// witnessing a broken invariant through the use of `catch_unwind` (catching a
0bf4aa26 106/// panic). This trait is an auto trait, so it is automatically implemented for
0731742a 107/// many types, and it is also structurally composed (e.g., a struct is unwind
3157f602 108/// safe if all of its components are unwind safe).
9cc50fc6
SL
109///
110/// Note, however, that this is not an unsafe trait, so there is not a succinct
111/// contract that this trait is providing. Instead it is intended as more of a
3157f602 112/// "speed bump" to alert users of `catch_unwind` that broken invariants may be
9cc50fc6
SL
113/// witnessed and may need to be accounted for.
114///
54a0048b 115/// ## Who implements `UnwindSafe`?
9cc50fc6
SL
116///
117/// Types such as `&mut T` and `&RefCell<T>` are examples which are **not**
3157f602
XL
118/// unwind safe. The general idea is that any mutable state which can be shared
119/// across `catch_unwind` is not unwind safe by default. This is because it is very
120/// easy to witness a broken invariant outside of `catch_unwind` as the data is
7453a54e 121/// simply accessed as usual.
9cc50fc6 122///
3157f602 123/// Types like `&Mutex<T>`, however, are unwind safe because they implement
9cc50fc6
SL
124/// poisoning by default. They still allow witnessing a broken invariant, but
125/// they already provide their own "speed bumps" to do so.
126///
54a0048b 127/// ## When should `UnwindSafe` be used?
9cc50fc6 128///
83c7162d
XL
129/// It is not intended that most types or functions need to worry about this trait.
130/// It is only used as a bound on the `catch_unwind` function and as mentioned
131/// above, the lack of `unsafe` means it is mostly an advisory. The
132/// [`AssertUnwindSafe`] wrapper struct can be used to force this trait to be
133/// implemented for any closed over variables passed to `catch_unwind`.
54a0048b 134#[stable(feature = "catch_unwind", since = "1.9.0")]
8faf50e0 135#[rustc_on_unimplemented(
60c5eb7d
XL
136 message = "the type `{Self}` may not be safely transferred across an unwind boundary",
137 label = "`{Self}` may not be safely transferred across an unwind boundary"
8faf50e0 138)]
2c00a5a8 139pub auto trait UnwindSafe {}
54a0048b 140
9cc50fc6 141/// A marker trait representing types where a shared reference is considered
3157f602 142/// unwind safe.
9cc50fc6 143///
83c7162d 144/// This trait is namely not implemented by [`UnsafeCell`], the root of all
9cc50fc6
SL
145/// interior mutability.
146///
147/// This is a "helper marker trait" used to provide impl blocks for the
83c7162d 148/// [`UnwindSafe`] trait, for more information see that documentation.
54a0048b 149#[stable(feature = "catch_unwind", since = "1.9.0")]
8faf50e0 150#[rustc_on_unimplemented(
60c5eb7d
XL
151 message = "the type `{Self}` may contain interior mutability and a reference may not be safely \
152 transferrable across a catch_unwind boundary",
153 label = "`{Self}` may contain interior mutability and a reference may not be safely \
154 transferrable across a catch_unwind boundary"
8faf50e0 155)]
2c00a5a8 156pub auto trait RefUnwindSafe {}
9cc50fc6 157
3157f602 158/// A simple wrapper around a type to assert that it is unwind safe.
9cc50fc6 159///
83c7162d 160/// When using [`catch_unwind`] it may be the case that some of the closed over
3157f602
XL
161/// variables are not unwind safe. For example if `&mut T` is captured the
162/// compiler will generate a warning indicating that it is not unwind safe. It
9cc50fc6 163/// may not be the case, however, that this is actually a problem due to the
83c7162d 164/// specific usage of [`catch_unwind`] if unwind safety is specifically taken into
9cc50fc6 165/// account. This wrapper struct is useful for a quick and lightweight
3157f602 166/// annotation that a variable is indeed unwind safe.
9cc50fc6
SL
167///
168/// # Examples
169///
54a0048b 170/// One way to use `AssertUnwindSafe` is to assert that the entire closure
3157f602 171/// itself is unwind safe, bypassing all checks for all variables:
9cc50fc6 172///
54a0048b
SL
173/// ```
174/// use std::panic::{self, AssertUnwindSafe};
9cc50fc6
SL
175///
176/// let mut variable = 4;
177///
178/// // This code will not compile because the closure captures `&mut variable`
3157f602 179/// // which is not considered unwind safe by default.
9cc50fc6 180///
54a0048b 181/// // panic::catch_unwind(|| {
9cc50fc6
SL
182/// // variable += 3;
183/// // });
184///
54a0048b
SL
185/// // This, however, will compile due to the `AssertUnwindSafe` wrapper
186/// let result = panic::catch_unwind(AssertUnwindSafe(|| {
187/// variable += 3;
188/// }));
189/// // ...
190/// ```
191///
192/// Wrapping the entire closure amounts to a blanket assertion that all captured
193/// variables are unwind safe. This has the downside that if new captures are
194/// added in the future, they will also be considered unwind safe. Therefore,
195/// you may prefer to just wrap individual captures, as shown below. This is
196/// more annotation, but it ensures that if a new capture is added which is not
197/// unwind safe, you will get a compilation error at that time, which will
198/// allow you to consider whether that new capture in fact represent a bug or
199/// not.
200///
201/// ```
202/// use std::panic::{self, AssertUnwindSafe};
203///
204/// let mut variable = 4;
205/// let other_capture = 3;
206///
9cc50fc6 207/// let result = {
54a0048b
SL
208/// let mut wrapper = AssertUnwindSafe(&mut variable);
209/// panic::catch_unwind(move || {
210/// **wrapper += other_capture;
9cc50fc6
SL
211/// })
212/// };
213/// // ...
214/// ```
54a0048b 215#[stable(feature = "catch_unwind", since = "1.9.0")]
60c5eb7d 216pub struct AssertUnwindSafe<T>(#[stable(feature = "catch_unwind", since = "1.9.0")] pub T);
9cc50fc6 217
54a0048b 218// Implementations of the `UnwindSafe` trait:
9cc50fc6 219//
54a0048b
SL
220// * By default everything is unwind safe
221// * pointers T contains mutability of some form are not unwind safe
9cc50fc6 222// * Unique, an owning pointer, lifts an implementation
83c7162d 223// * Types like Mutex/RwLock which are explicitly poisoned are unwind safe
54a0048b 224// * Our custom AssertUnwindSafe wrapper is indeed unwind safe
2c00a5a8 225
54a0048b 226#[stable(feature = "catch_unwind", since = "1.9.0")]
9fa01778 227impl<T: ?Sized> !UnwindSafe for &mut T {}
54a0048b 228#[stable(feature = "catch_unwind", since = "1.9.0")]
9fa01778 229impl<T: RefUnwindSafe + ?Sized> UnwindSafe for &T {}
54a0048b
SL
230#[stable(feature = "catch_unwind", since = "1.9.0")]
231impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *const T {}
232#[stable(feature = "catch_unwind", since = "1.9.0")]
233impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *mut T {}
dfeec247 234#[unstable(feature = "ptr_internals", issue = "none")]
32a655c1 235impl<T: UnwindSafe + ?Sized> UnwindSafe for Unique<T> {}
2c00a5a8
XL
236#[stable(feature = "nonnull", since = "1.25.0")]
237impl<T: RefUnwindSafe + ?Sized> UnwindSafe for NonNull<T> {}
54a0048b
SL
238#[stable(feature = "catch_unwind", since = "1.9.0")]
239impl<T: ?Sized> UnwindSafe for Mutex<T> {}
240#[stable(feature = "catch_unwind", since = "1.9.0")]
241impl<T: ?Sized> UnwindSafe for RwLock<T> {}
242#[stable(feature = "catch_unwind", since = "1.9.0")]
243impl<T> UnwindSafe for AssertUnwindSafe<T> {}
9cc50fc6
SL
244
245// not covered via the Shared impl above b/c the inner contents use
3157f602 246// Cell/AtomicUsize, but the usage here is unwind safe so we can lift the
9cc50fc6 247// impl up one level to Arc/Rc itself
54a0048b
SL
248#[stable(feature = "catch_unwind", since = "1.9.0")]
249impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Rc<T> {}
250#[stable(feature = "catch_unwind", since = "1.9.0")]
251impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Arc<T> {}
9cc50fc6 252
a7813a04 253// Pretty simple implementations for the `RefUnwindSafe` marker trait,
2c00a5a8 254// basically just saying that `UnsafeCell` is the
9cc50fc6
SL
255// only thing which doesn't implement it (which then transitively applies to
256// everything else).
54a0048b 257#[stable(feature = "catch_unwind", since = "1.9.0")]
54a0048b
SL
258impl<T: ?Sized> !RefUnwindSafe for UnsafeCell<T> {}
259#[stable(feature = "catch_unwind", since = "1.9.0")]
260impl<T> RefUnwindSafe for AssertUnwindSafe<T> {}
54a0048b 261
5bcae85e
SL
262#[stable(feature = "unwind_safe_lock_refs", since = "1.12.0")]
263impl<T: ?Sized> RefUnwindSafe for Mutex<T> {}
264#[stable(feature = "unwind_safe_lock_refs", since = "1.12.0")]
265impl<T: ?Sized> RefUnwindSafe for RwLock<T> {}
266
e74abb32 267#[cfg(target_has_atomic_load_store = "ptr")]
c30ab7b3
SL
268#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
269impl RefUnwindSafe for atomic::AtomicIsize {}
e74abb32 270#[cfg(target_has_atomic_load_store = "8")]
1b1a35ee 271#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
c30ab7b3 272impl RefUnwindSafe for atomic::AtomicI8 {}
e74abb32 273#[cfg(target_has_atomic_load_store = "16")]
1b1a35ee 274#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
c30ab7b3 275impl RefUnwindSafe for atomic::AtomicI16 {}
e74abb32 276#[cfg(target_has_atomic_load_store = "32")]
1b1a35ee 277#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
c30ab7b3 278impl RefUnwindSafe for atomic::AtomicI32 {}
e74abb32 279#[cfg(target_has_atomic_load_store = "64")]
1b1a35ee 280#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
c30ab7b3 281impl RefUnwindSafe for atomic::AtomicI64 {}
e74abb32 282#[cfg(target_has_atomic_load_store = "128")]
a1dfa0c6
XL
283#[unstable(feature = "integer_atomics", issue = "32976")]
284impl RefUnwindSafe for atomic::AtomicI128 {}
c30ab7b3 285
e74abb32 286#[cfg(target_has_atomic_load_store = "ptr")]
c30ab7b3
SL
287#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
288impl RefUnwindSafe for atomic::AtomicUsize {}
e74abb32 289#[cfg(target_has_atomic_load_store = "8")]
1b1a35ee 290#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
c30ab7b3 291impl RefUnwindSafe for atomic::AtomicU8 {}
e74abb32 292#[cfg(target_has_atomic_load_store = "16")]
1b1a35ee 293#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
c30ab7b3 294impl RefUnwindSafe for atomic::AtomicU16 {}
e74abb32 295#[cfg(target_has_atomic_load_store = "32")]
1b1a35ee 296#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
c30ab7b3 297impl RefUnwindSafe for atomic::AtomicU32 {}
e74abb32 298#[cfg(target_has_atomic_load_store = "64")]
1b1a35ee 299#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
c30ab7b3 300impl RefUnwindSafe for atomic::AtomicU64 {}
e74abb32 301#[cfg(target_has_atomic_load_store = "128")]
a1dfa0c6
XL
302#[unstable(feature = "integer_atomics", issue = "32976")]
303impl RefUnwindSafe for atomic::AtomicU128 {}
c30ab7b3 304
e74abb32 305#[cfg(target_has_atomic_load_store = "8")]
c30ab7b3
SL
306#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
307impl RefUnwindSafe for atomic::AtomicBool {}
308
e74abb32 309#[cfg(target_has_atomic_load_store = "ptr")]
c30ab7b3
SL
310#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
311impl<T> RefUnwindSafe for atomic::AtomicPtr<T> {}
312
48663c56
XL
313// https://github.com/rust-lang/rust/issues/62301
314#[stable(feature = "hashbrown", since = "1.36.0")]
315impl<K, V, S> UnwindSafe for collections::HashMap<K, V, S>
60c5eb7d
XL
316where
317 K: UnwindSafe,
318 V: UnwindSafe,
319 S: UnwindSafe,
320{
321}
48663c56 322
54a0048b
SL
323#[stable(feature = "catch_unwind", since = "1.9.0")]
324impl<T> Deref for AssertUnwindSafe<T> {
325 type Target = T;
9cc50fc6 326
54a0048b
SL
327 fn deref(&self) -> &T {
328 &self.0
329 }
330}
331
332#[stable(feature = "catch_unwind", since = "1.9.0")]
333impl<T> DerefMut for AssertUnwindSafe<T> {
334 fn deref_mut(&mut self) -> &mut T {
335 &mut self.0
336 }
337}
338
339#[stable(feature = "catch_unwind", since = "1.9.0")]
340impl<R, F: FnOnce() -> R> FnOnce<()> for AssertUnwindSafe<F> {
341 type Output = R;
342
343 extern "rust-call" fn call_once(self, _args: ()) -> R {
344 (self.0)()
345 }
346}
347
8bb4bdeb 348#[stable(feature = "std_debug", since = "1.16.0")]
32a655c1 349impl<T: fmt::Debug> fmt::Debug for AssertUnwindSafe<T> {
532ac7d7 350 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60c5eb7d 351 f.debug_tuple("AssertUnwindSafe").field(&self.0).finish()
32a655c1
SL
352 }
353}
354
48663c56 355#[stable(feature = "futures_api", since = "1.36.0")]
9fa01778 356impl<F: Future> Future for AssertUnwindSafe<F> {
94b46f34
XL
357 type Output = F::Output;
358
532ac7d7 359 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
0bf4aa26 360 let pinned_field = unsafe { Pin::map_unchecked_mut(self, |x| &mut x.0) };
532ac7d7 361 F::poll(pinned_field, cx)
94b46f34
XL
362 }
363}
364
5869c6ff
XL
365#[unstable(feature = "async_stream", issue = "79024")]
366impl<S: Stream> Stream for AssertUnwindSafe<S> {
367 type Item = S::Item;
368
369 fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<S::Item>> {
370 unsafe { self.map_unchecked_mut(|x| &mut x.0) }.poll_next(cx)
371 }
372
373 fn size_hint(&self) -> (usize, Option<usize>) {
374 self.0.size_hint()
375 }
376}
377
54a0048b 378/// Invokes a closure, capturing the cause of an unwinding panic if one occurs.
9cc50fc6
SL
379///
380/// This function will return `Ok` with the closure's result if the closure
381/// does not panic, and will return `Err(cause)` if the closure panics. The
382/// `cause` returned is the object with which panic was originally invoked.
383///
384/// It is currently undefined behavior to unwind from Rust code into foreign
385/// code, so this function is particularly useful when Rust is called from
386/// another language (normally C). This can run arbitrary Rust code, capturing a
387/// panic and allowing a graceful handling of the error.
388///
389/// It is **not** recommended to use this function for a general try/catch
83c7162d 390/// mechanism. The [`Result`] type is more appropriate to use for functions that
54a0048b 391/// can fail on a regular basis. Additionally, this function is not guaranteed
a7813a04 392/// to catch all panics, see the "Notes" section below.
54a0048b 393///
83c7162d 394/// The closure provided is required to adhere to the [`UnwindSafe`] trait to ensure
54a0048b
SL
395/// that all captured variables are safe to cross this boundary. The purpose of
396/// this bound is to encode the concept of [exception safety][rfc] in the type
397/// system. Most usage of this function should not need to worry about this
3157f602 398/// bound as programs are naturally unwind safe without `unsafe` code. If it
83c7162d
XL
399/// becomes a problem the [`AssertUnwindSafe`] wrapper struct can be used to quickly
400/// assert that the usage here is indeed unwind safe.
401///
9cc50fc6
SL
402/// [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1236-stabilize-catch-panic.md
403///
54a0048b
SL
404/// # Notes
405///
406/// Note that this function **may not catch all panics** in Rust. A panic in
407/// Rust is not always implemented via unwinding, but can be implemented by
408/// aborting the process as well. This function *only* catches unwinding panics,
409/// not those that abort the process.
410///
1b1a35ee
XL
411/// Also note that unwinding into Rust code with a foreign exception (e.g. a
412/// an exception thrown from C++ code) is undefined behavior.
413///
9cc50fc6
SL
414/// # Examples
415///
416/// ```
9cc50fc6
SL
417/// use std::panic;
418///
54a0048b 419/// let result = panic::catch_unwind(|| {
9cc50fc6
SL
420/// println!("hello!");
421/// });
422/// assert!(result.is_ok());
423///
54a0048b 424/// let result = panic::catch_unwind(|| {
9cc50fc6
SL
425/// panic!("oh no!");
426/// });
427/// assert!(result.is_err());
428/// ```
54a0048b
SL
429#[stable(feature = "catch_unwind", since = "1.9.0")]
430pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
60c5eb7d 431 unsafe { panicking::r#try(f) }
9cc50fc6
SL
432}
433
a7813a04 434/// Triggers a panic without invoking the panic hook.
9cc50fc6 435///
83c7162d 436/// This is designed to be used in conjunction with [`catch_unwind`] to, for
54a0048b
SL
437/// example, carry a panic across a layer of C code.
438///
439/// # Notes
440///
441/// Note that panics in Rust are not always implemented via unwinding, but they
442/// may be implemented by aborting the process. If this function is called when
443/// panics are implemented this way then this function will abort the process,
444/// not trigger an unwind.
9cc50fc6
SL
445///
446/// # Examples
447///
448/// ```should_panic
9cc50fc6
SL
449/// use std::panic;
450///
54a0048b 451/// let result = panic::catch_unwind(|| {
9cc50fc6
SL
452/// panic!("oh no!");
453/// });
454///
455/// if let Err(err) = result {
54a0048b 456/// panic::resume_unwind(err);
9cc50fc6
SL
457/// }
458/// ```
54a0048b 459#[stable(feature = "resume_unwind", since = "1.9.0")]
8faf50e0 460pub fn resume_unwind(payload: Box<dyn Any + Send>) -> ! {
60c5eb7d 461 panicking::rust_panic_without_hook(payload)
54a0048b 462}
1b1a35ee
XL
463
464#[cfg(test)]
465mod tests;