about summary refs log tree commit diff
path: root/src/libstd/panic.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-04-12 04:17:36 -0700
committerbors <bors@rust-lang.org>2016-04-12 04:17:36 -0700
commitbed32d83fcd1337e962a58fd04fae6b8503e3283 (patch)
tree1602a9ea8b4221ba0b27018b8685f52f5d1dbbd0 /src/libstd/panic.rs
parent28c9fdafc06a259c25c1b889044fd49b4dfc69e2 (diff)
parent552eda70d33cead1398adfecce1a75e7a61e3daf (diff)
downloadrust-bed32d83fcd1337e962a58fd04fae6b8503e3283.tar.gz
rust-bed32d83fcd1337e962a58fd04fae6b8503e3283.zip
Auto merge of #32804 - alexcrichton:stabilize-1.9, r=brson
std: Stabilize APIs for the 1.9 release

This commit applies all stabilizations, renamings, and deprecations that the
library team has decided on for the upcoming 1.9 release. All tracking issues
have gone through a cycle-long "final comment period" and the specific APIs
stabilized/deprecated are:

Stable

* `std::panic`
* `std::panic::catch_unwind` (renamed from `recover`)
* `std::panic::resume_unwind` (renamed from `propagate`)
* `std::panic::AssertUnwindSafe` (renamed from `AssertRecoverSafe`)
* `std::panic::UnwindSafe` (renamed from `RecoverSafe`)
* `str::is_char_boundary`
* `<*const T>::as_ref`
* `<*mut T>::as_ref`
* `<*mut T>::as_mut`
* `AsciiExt::make_ascii_uppercase`
* `AsciiExt::make_ascii_lowercase`
* `char::decode_utf16`
* `char::DecodeUtf16`
* `char::DecodeUtf16Error`
* `char::DecodeUtf16Error::unpaired_surrogate`
* `BTreeSet::take`
* `BTreeSet::replace`
* `BTreeSet::get`
* `HashSet::take`
* `HashSet::replace`
* `HashSet::get`
* `OsString::with_capacity`
* `OsString::clear`
* `OsString::capacity`
* `OsString::reserve`
* `OsString::reserve_exact`
* `OsStr::is_empty`
* `OsStr::len`
* `std::os::unix::thread`
* `RawPthread`
* `JoinHandleExt`
* `JoinHandleExt::as_pthread_t`
* `JoinHandleExt::into_pthread_t`
* `HashSet::hasher`
* `HashMap::hasher`
* `CommandExt::exec`
* `File::try_clone`
* `SocketAddr::set_ip`
* `SocketAddr::set_port`
* `SocketAddrV4::set_ip`
* `SocketAddrV4::set_port`
* `SocketAddrV6::set_ip`
* `SocketAddrV6::set_port`
* `SocketAddrV6::set_flowinfo`
* `SocketAddrV6::set_scope_id`
* `<[T]>::copy_from_slice`
* `ptr::read_volatile`
* `ptr::write_volatile`
* The `#[deprecated]` attribute
* `OpenOptions::create_new`

Deprecated

* `std::raw::Slice` - use raw parts of `slice` module instead
* `std::raw::Repr` - use raw parts of `slice` module instead
* `str::char_range_at` - use slicing plus `chars()` plus `len_utf8`
* `str::char_range_at_reverse` - use slicing plus `chars().rev()` plus `len_utf8`
* `str::char_at` - use slicing plus `chars()`
* `str::char_at_reverse` - use slicing plus `chars().rev()`
* `str::slice_shift_char` - use `chars()` plus `Chars::as_str`
* `CommandExt::session_leader` - use `before_exec` instead.

Closes #27719
cc #27751 (deprecating the `Slice` bits)
Closes #27754
Closes #27780
Closes #27809
Closes #27811
Closes #27830
Closes #28050
Closes #29453
Closes #29791
Closes #29935
Closes #30014
Closes #30752
Closes #31262
cc #31398 (still need to deal with `before_exec`)
Closes #31405
Closes #31572
Closes #31755
Closes #31756
Diffstat (limited to 'src/libstd/panic.rs')
-rw-r--r--src/libstd/panic.rs222
1 files changed, 156 insertions, 66 deletions
diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs
index 4462ce24dce..16401c4527f 100644
--- a/src/libstd/panic.rs
+++ b/src/libstd/panic.rs
@@ -10,8 +10,7 @@
 
 //! Panic support in the standard library
 
-#![unstable(feature = "std_panic", reason = "awaiting feedback",
-            issue = "27719")]
+#![stable(feature = "std_panic", since = "1.9.0")]
 
 use any::Any;
 use boxed::Box;
@@ -23,6 +22,7 @@ use sync::{Arc, Mutex, RwLock};
 use sys_common::unwind;
 use thread::Result;
 
+#[unstable(feature = "panic_handler", issue = "30449")]
 pub use panicking::{take_hook, set_hook, PanicInfo, Location};
 
 ///
@@ -92,7 +92,7 @@ pub fn take_handler() -> Box<Fn(&PanicInfo) + 'static + Sync + Send> {
 /// "speed bump" to alert users of `recover` that broken invariants may be
 /// witnessed and may need to be accounted for.
 ///
-/// ## Who implements `RecoverSafe`?
+/// ## Who implements `UnwindSafe`?
 ///
 /// Types such as `&mut T` and `&RefCell<T>` are examples which are **not**
 /// recover safe. The general idea is that any mutable state which can be shared
@@ -104,7 +104,7 @@ pub fn take_handler() -> Box<Fn(&PanicInfo) + 'static + Sync + Send> {
 /// poisoning by default. They still allow witnessing a broken invariant, but
 /// they already provide their own "speed bumps" to do so.
 ///
-/// ## When should `RecoverSafe` be used?
+/// ## When should `UnwindSafe` be used?
 ///
 /// Is not intended that most types or functions need to worry about this trait.
 /// It is only used as a bound on the `recover` function and as mentioned above,
@@ -112,10 +112,18 @@ pub fn take_handler() -> Box<Fn(&PanicInfo) + 'static + Sync + Send> {
 /// wrapper struct in this module can be used to force this trait to be
 /// implemented for any closed over variables passed to the `recover` function
 /// (more on this below).
-#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
+#[stable(feature = "catch_unwind", since = "1.9.0")]
 #[rustc_on_unimplemented = "the type {Self} may not be safely transferred \
                             across a recover boundary"]
+pub trait UnwindSafe {}
+
+/// Deprecated, renamed to UnwindSafe
+#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
+#[rustc_deprecated(reason = "renamed to `UnwindSafe`", since = "1.9.0")]
 pub trait RecoverSafe {}
+#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
+#[allow(deprecated)]
+impl<T: UnwindSafe> RecoverSafe for T {}
 
 /// A marker trait representing types where a shared reference is considered
 /// recover safe.
@@ -124,12 +132,12 @@ pub trait RecoverSafe {}
 /// interior mutability.
 ///
 /// This is a "helper marker trait" used to provide impl blocks for the
-/// `RecoverSafe` trait, for more information see that documentation.
-#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
+/// `UnwindSafe` trait, for more information see that documentation.
+#[stable(feature = "catch_unwind", since = "1.9.0")]
 #[rustc_on_unimplemented = "the type {Self} contains interior mutability \
                             and a reference may not be safely transferrable \
                             across a recover boundary"]
-pub trait RefRecoverSafe {}
+pub trait RefUnwindSafe {}
 
 /// A simple wrapper around a type to assert that it is panic safe.
 ///
@@ -143,90 +151,141 @@ pub trait RefRecoverSafe {}
 ///
 /// # Examples
 ///
-/// One way to use `AssertRecoverSafe` is to assert that the entire closure
+/// One way to use `AssertUnwindSafe` is to assert that the entire closure
 /// itself is recover safe, bypassing all checks for all variables:
 ///
 /// ```
-/// #![feature(recover, std_panic)]
-///
-/// use std::panic::{self, AssertRecoverSafe};
+/// use std::panic::{self, AssertUnwindSafe};
 ///
 /// let mut variable = 4;
 ///
 /// // This code will not compile because the closure captures `&mut variable`
 /// // which is not considered panic safe by default.
 ///
-/// // panic::recover(|| {
+/// // panic::catch_unwind(|| {
 /// //     variable += 3;
 /// // });
 ///
-/// // This, however, will compile due to the `AssertRecoverSafe` wrapper
-/// let result = panic::recover(AssertRecoverSafe(|| {
+/// // This, however, will compile due to the `AssertUnwindSafe` wrapper
+/// let result = panic::catch_unwind(AssertUnwindSafe(|| {
 ///     variable += 3;
 /// }));
 /// // ...
 /// ```
 ///
 /// Wrapping the entire closure amounts to a blanket assertion that all captured
-/// variables are recover safe. This has the downside that if new captures are
-/// added in the future, they will also be considered recover safe. Therefore,
+/// variables are unwind safe. This has the downside that if new captures are
+/// added in the future, they will also be considered unwind safe. Therefore,
 /// you may prefer to just wrap individual captures, as shown below. This is
 /// more annotation, but it ensures that if a new capture is added which is not
-/// recover safe, you will get a compilation error at that time, which will
+/// unwind safe, you will get a compilation error at that time, which will
 /// allow you to consider whether that new capture in fact represent a bug or
 /// not.
 ///
 /// ```
-/// #![feature(recover, std_panic)]
-///
-/// use std::panic::{self, AssertRecoverSafe};
+/// use std::panic::{self, AssertUnwindSafe};
 ///
 /// let mut variable = 4;
 /// let other_capture = 3;
 ///
 /// let result = {
-///     let mut wrapper = AssertRecoverSafe(&mut variable);
-///     panic::recover(move || {
+///     let mut wrapper = AssertUnwindSafe(&mut variable);
+///     panic::catch_unwind(move || {
 ///         **wrapper += other_capture;
 ///     })
 /// };
 /// // ...
 /// ```
-#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+pub struct AssertUnwindSafe<T>(
+    #[stable(feature = "catch_unwind", since = "1.9.0")]
+    pub T
+);
+
+/// Deprecated, renamed to `AssertUnwindSafe`
+#[unstable(feature = "recover", issue = "27719")]
+#[rustc_deprecated(reason = "renamed to `AssertUnwindSafe`", since = "1.9.0")]
 pub struct AssertRecoverSafe<T>(pub T);
 
-// Implementations of the `RecoverSafe` trait:
+// Implementations of the `UnwindSafe` trait:
 //
-// * By default everything is recover safe
-// * pointers T contains mutability of some form are not recover safe
+// * By default everything is unwind safe
+// * pointers T contains mutability of some form are not unwind safe
 // * Unique, an owning pointer, lifts an implementation
-// * Types like Mutex/RwLock which are explicilty poisoned are recover safe
-// * Our custom AssertRecoverSafe wrapper is indeed recover safe
-impl RecoverSafe for .. {}
-impl<'a, T: ?Sized> !RecoverSafe for &'a mut T {}
-impl<'a, T: RefRecoverSafe + ?Sized> RecoverSafe for &'a T {}
-impl<T: RefRecoverSafe + ?Sized> RecoverSafe for *const T {}
-impl<T: RefRecoverSafe + ?Sized> RecoverSafe for *mut T {}
-impl<T: RecoverSafe> RecoverSafe for Unique<T> {}
-impl<T: RefRecoverSafe + ?Sized> RecoverSafe for Shared<T> {}
-impl<T: ?Sized> RecoverSafe for Mutex<T> {}
-impl<T: ?Sized> RecoverSafe for RwLock<T> {}
-impl<T> RecoverSafe for AssertRecoverSafe<T> {}
+// * Types like Mutex/RwLock which are explicilty poisoned are unwind safe
+// * Our custom AssertUnwindSafe wrapper is indeed unwind safe
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl UnwindSafe for .. {}
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<'a, T: ?Sized> !UnwindSafe for &'a mut T {}
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<'a, T: RefUnwindSafe + ?Sized> UnwindSafe for &'a T {}
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *const T {}
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *mut T {}
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<T: UnwindSafe> UnwindSafe for Unique<T> {}
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Shared<T> {}
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<T: ?Sized> UnwindSafe for Mutex<T> {}
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<T: ?Sized> UnwindSafe for RwLock<T> {}
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<T> UnwindSafe for AssertUnwindSafe<T> {}
+#[unstable(feature = "recover", issue = "27719")]
+#[allow(deprecated)]
+impl<T> UnwindSafe for AssertRecoverSafe<T> {}
 
 // not covered via the Shared impl above b/c the inner contents use
 // Cell/AtomicUsize, but the usage here is recover safe so we can lift the
 // impl up one level to Arc/Rc itself
-impl<T: RefRecoverSafe + ?Sized> RecoverSafe for Rc<T> {}
-impl<T: RefRecoverSafe + ?Sized> RecoverSafe for Arc<T> {}
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Rc<T> {}
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<T: RefUnwindSafe + ?Sized> UnwindSafe 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).
-impl RefRecoverSafe for .. {}
-impl<T: ?Sized> !RefRecoverSafe for UnsafeCell<T> {}
-impl<T> RefRecoverSafe for AssertRecoverSafe<T> {}
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl RefUnwindSafe for .. {}
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<T: ?Sized> !RefUnwindSafe for UnsafeCell<T> {}
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<T> RefUnwindSafe for AssertUnwindSafe<T> {}
+#[unstable(feature = "recover", issue = "27719")]
+#[allow(deprecated)]
+impl<T> RefUnwindSafe for AssertRecoverSafe<T> {}
+
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<T> Deref for AssertUnwindSafe<T> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        &self.0
+    }
+}
+
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<T> DerefMut for AssertUnwindSafe<T> {
+    fn deref_mut(&mut self) -> &mut T {
+        &mut self.0
+    }
+}
 
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<R, F: FnOnce() -> R> FnOnce<()> for AssertUnwindSafe<F> {
+    type Output = R;
+
+    extern "rust-call" fn call_once(self, _args: ()) -> R {
+        (self.0)()
+    }
+}
+
+#[allow(deprecated)]
 impl<T> AssertRecoverSafe<T> {
     /// Creates a new `AssertRecoverSafe` wrapper around the provided type.
     #[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
@@ -245,6 +304,8 @@ impl<T> AssertRecoverSafe<T> {
     }
 }
 
+#[unstable(feature = "recover", issue = "27719")]
+#[allow(deprecated)]
 impl<T> Deref for AssertRecoverSafe<T> {
     type Target = T;
 
@@ -253,12 +314,16 @@ impl<T> Deref for AssertRecoverSafe<T> {
     }
 }
 
+#[unstable(feature = "recover", issue = "27719")]
+#[allow(deprecated)]
 impl<T> DerefMut for AssertRecoverSafe<T> {
     fn deref_mut(&mut self) -> &mut T {
         &mut self.0
     }
 }
 
+#[unstable(feature = "recover", issue = "27719")]
+#[allow(deprecated)]
 impl<R, F: FnOnce() -> R> FnOnce<()> for AssertRecoverSafe<F> {
     type Output = R;
 
@@ -267,7 +332,7 @@ impl<R, F: FnOnce() -> R> FnOnce<()> for AssertRecoverSafe<F> {
     }
 }
 
-/// Invokes a closure, capturing the cause of panic if one occurs.
+/// Invokes a closure, capturing the cause of an unwinding panic if one occurs.
 ///
 /// This function will return `Ok` with the closure's result if the closure
 /// does not panic, and will return `Err(cause)` if the closure panics. The
@@ -280,38 +345,44 @@ impl<R, F: FnOnce() -> R> FnOnce<()> for AssertRecoverSafe<F> {
 ///
 /// It is **not** recommended to use this function for a general try/catch
 /// mechanism. The `Result` type is more appropriate to use for functions that
-/// can fail on a regular basis.
-///
-/// The closure provided is required to adhere to the `RecoverSafe` to ensure
-/// that all captured variables are safe to cross this recover boundary. The
-/// purpose of this bound is to encode the concept of [exception safety][rfc] in
-/// the type system. Most usage of this function should not need to worry about
-/// this bound as programs are naturally panic safe without `unsafe` code. If it
-/// becomes a problem the associated `AssertRecoverSafe` wrapper type in this
+/// can fail on a regular basis. Additionally, this function is not guaranteed
+/// to catch all panics, see the "Notes" sectino below.
+///
+/// The closure provided is required to adhere to the `UnwindSafe` to ensure
+/// that all captured variables are safe to cross this boundary. The purpose of
+/// this bound is to encode the concept of [exception safety][rfc] in the type
+/// system. Most usage of this function should not need to worry about this
+/// bound as programs are naturally panic safe without `unsafe` code. If it
+/// becomes a problem the associated `AssertUnwindSafe` wrapper type in this
 /// module can be used to quickly assert that the usage here is indeed exception
 /// safe.
 ///
 /// [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1236-stabilize-catch-panic.md
 ///
+/// # Notes
+///
+/// Note that this function **may not catch all panics** in Rust. A panic in
+/// Rust is not always implemented via unwinding, but can be implemented by
+/// aborting the process as well. This function *only* catches unwinding panics,
+/// not those that abort the process.
+///
 /// # Examples
 ///
 /// ```
-/// #![feature(recover, std_panic)]
-///
 /// use std::panic;
 ///
-/// let result = panic::recover(|| {
+/// let result = panic::catch_unwind(|| {
 ///     println!("hello!");
 /// });
 /// assert!(result.is_ok());
 ///
-/// let result = panic::recover(|| {
+/// let result = panic::catch_unwind(|| {
 ///     panic!("oh no!");
 /// });
 /// assert!(result.is_err());
 /// ```
-#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
-pub fn recover<F: FnOnce() -> R + RecoverSafe, R>(f: F) -> Result<R> {
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
     let mut result = None;
     unsafe {
         let result = &mut result;
@@ -320,27 +391,46 @@ pub fn recover<F: FnOnce() -> R + RecoverSafe, R>(f: F) -> Result<R> {
     Ok(result.unwrap())
 }
 
+/// Deprecated, renamed to `catch_unwind`
+#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
+#[rustc_deprecated(reason = "renamed to `catch_unwind`", since = "1.9.0")]
+pub fn recover<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
+    catch_unwind(f)
+}
+
 /// 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.
+/// This is designed to be used in conjunction with `catch_unwind` to, for
+/// example, carry a panic across a layer of C code.
+///
+/// # Notes
+///
+/// Note that panics in Rust are not always implemented via unwinding, but they
+/// may be implemented by aborting the process. If this function is called when
+/// panics are implemented this way then this function will abort the process,
+/// not trigger an unwind.
 ///
 /// # Examples
 ///
 /// ```should_panic
-/// #![feature(std_panic, recover, panic_propagate)]
-///
 /// use std::panic;
 ///
-/// let result = panic::recover(|| {
+/// let result = panic::catch_unwind(|| {
 ///     panic!("oh no!");
 /// });
 ///
 /// if let Err(err) = result {
-///     panic::propagate(err);
+///     panic::resume_unwind(err);
 /// }
 /// ```
+#[stable(feature = "resume_unwind", since = "1.9.0")]
+pub fn resume_unwind(payload: Box<Any + Send>) -> ! {
+    unwind::rust_panic(payload)
+}
+
+/// Deprecated, use resume_unwind instead
 #[unstable(feature = "panic_propagate", reason = "awaiting feedback", issue = "30752")]
+#[rustc_deprecated(reason = "renamed to `resume_unwind`", since = "1.9.0")]
 pub fn propagate(payload: Box<Any + Send>) -> ! {
-    unwind::rust_panic(payload)
+    resume_unwind(payload)
 }