]> git.lizzy.rs Git - rust.git/blobdiff - src/libstd/panic.rs
Auto merge of #30917 - arthurprs:bs_bounds_check, r=alexcrichton
[rust.git] / src / libstd / panic.rs
index b42d1d1b8d4ce5fb95d4cdc7d1d09207b150d6fc..3677bd27b16194f90fe6b37f8439c9735331647b 100644 (file)
@@ -13,6 +13,8 @@
 #![unstable(feature = "std_panic", reason = "awaiting feedback",
             issue = "27719")]
 
+use any::Any;
+use boxed::Box;
 use cell::UnsafeCell;
 use ops::{Deref, DerefMut};
 use ptr::{Unique, Shared};
 ///    panics.
 /// 2. This broken invariant is then later observed.
 ///
-/// Typically in Rust it is difficult to perform step (2) because catching a
+/// Typically in Rust, it is difficult to perform step (2) because catching a
 /// panic involves either spawning a thread (which in turns makes it difficult
 /// to later witness broken invariants) or using the `recover` function in this
-/// module. Additionally, even if an invariant is witness, it typically isn't a
+/// module. Additionally, even if an invariant is witnessed, it typically isn't a
 /// problem in Rust because there's no uninitialized values (like in C or C++).
 ///
 /// It is possible, however, for **logical** invariants to be broken in Rust,
 /// which can end up causing behavioral bugs. Another key aspect of panic safety
-/// in Rust is that in the absence of `unsafe` code, a panic cannot lead to
+/// in Rust is that, in the absence of `unsafe` code, a panic cannot lead to
 /// memory unsafety.
 ///
 /// That was a bit of a whirlwind tour of panic safety, but for more information
 /// ## What is `RecoverSafe`?
 ///
 /// Now that we've got an idea of what panic safety is in Rust, it's also
-/// important to understand that this trait represents. As mentioned above, one
+/// important to understand what this trait represents. As mentioned above, one
 /// way to witness broken invariants is through the `recover` function in this
 /// module as it allows catching a panic and then re-using the environment of
 /// the closure.
 ///
-/// Simply but, a type `T` implements `RecoverSafe` if it cannot easily allow
+/// Simply put, a type `T` implements `RecoverSafe` if it cannot easily allow
 /// witnessing a broken invariant through the use of `recover` (catching a
 /// panic). This trait is a marker trait, so it is automatically implemented for
 /// many types, and it is also structurally composed (e.g. a struct is recover
@@ -134,7 +136,7 @@ pub trait RefRecoverSafe {}
 ///
 /// let mut variable = 4;
 ///
-/// // This code will not compile becuause the closure captures `&mut variable`
+/// // This code will not compile because the closure captures `&mut variable`
 /// // which is not considered panic safe by default.
 ///
 /// // panic::recover(|| {
@@ -180,7 +182,7 @@ impl<T: RefRecoverSafe + ?Sized> RecoverSafe for Arc<T> {}
 // Pretty simple implementations for the `RefRecoverSafe` marker trait,
 // basically just saying that this is a marker trait and `UnsafeCell` is the
 // only thing which doesn't implement it (which then transitively applies to
-// everything else.
+// everything else).
 impl RefRecoverSafe for .. {}
 impl<T: ?Sized> !RefRecoverSafe for UnsafeCell<T> {}
 impl<T> RefRecoverSafe for AssertRecoverSafe<T> {}
@@ -259,3 +261,28 @@ pub fn recover<F: FnOnce() -> R + RecoverSafe, R>(f: F) -> Result<R> {
     }
     Ok(result.unwrap())
 }
+
+/// Triggers a panic without invoking the panic handler.
+///
+/// This is designed to be used in conjunction with `recover` to, for example,
+/// carry a panic across a layer of C code.
+///
+/// # Examples
+///
+/// ```should_panic
+/// #![feature(std_panic, recover, panic_propagate)]
+///
+/// use std::panic;
+///
+/// let result = panic::recover(|| {
+///     panic!("oh no!");
+/// });
+///
+/// if let Err(err) = result {
+///     panic::propagate(err);
+/// }
+/// ```
+#[unstable(feature = "panic_propagate", reason = "awaiting feedback", issue = "30752")]
+pub fn propagate(payload: Box<Any + Send>) -> ! {
+    unwind::rust_panic(payload)
+}