about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libstd/panic.rs34
-rw-r--r--src/test/run-pass/panic-safe.rs6
2 files changed, 24 insertions, 16 deletions
diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs
index 1550d55d177..b42d1d1b8d4 100644
--- a/src/libstd/panic.rs
+++ b/src/libstd/panic.rs
@@ -101,8 +101,11 @@ pub use panicking::{take_handler, set_handler, PanicInfo, Location};
                             across a recover boundary"]
 pub trait RecoverSafe {}
 
-/// A marker trait representing types which do not contain an `UnsafeCell` by
-/// value internally.
+/// A marker trait representing types where a shared reference is considered
+/// recover safe.
+///
+/// This trait is namely not implemented by `UnsafeCell`, the root of all
+/// interior mutability.
 ///
 /// This is a "helper marker trait" used to provide impl blocks for the
 /// `RecoverSafe` trait, for more information see that documentation.
@@ -110,7 +113,7 @@ pub trait RecoverSafe {}
 #[rustc_on_unimplemented = "the type {Self} contains interior mutability \
                             and a reference may not be safely transferrable \
                             across a recover boundary"]
-pub trait NoUnsafeCell {}
+pub trait RefRecoverSafe {}
 
 /// A simple wrapper around a type to assert that it is panic safe.
 ///
@@ -159,11 +162,11 @@ pub struct AssertRecoverSafe<T>(T);
 // * Our custom AssertRecoverSafe wrapper is indeed recover safe
 impl RecoverSafe for .. {}
 impl<'a, T: ?Sized> !RecoverSafe for &'a mut T {}
-impl<'a, T: NoUnsafeCell + ?Sized> RecoverSafe for &'a T {}
-impl<T: NoUnsafeCell + ?Sized> RecoverSafe for *const T {}
-impl<T: NoUnsafeCell + ?Sized> RecoverSafe for *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: NoUnsafeCell + ?Sized> RecoverSafe for Shared<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> {}
@@ -171,15 +174,16 @@ impl<T> RecoverSafe 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: NoUnsafeCell + ?Sized> RecoverSafe for Rc<T> {}
-impl<T: NoUnsafeCell + ?Sized> RecoverSafe for Arc<T> {}
+impl<T: RefRecoverSafe + ?Sized> RecoverSafe for Rc<T> {}
+impl<T: RefRecoverSafe + ?Sized> RecoverSafe for Arc<T> {}
 
-// Pretty simple implementations for the `NoUnsafeCell` 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 NoUnsafeCell for .. {}
-impl<T: ?Sized> !NoUnsafeCell for UnsafeCell<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> {}
 
 impl<T> AssertRecoverSafe<T> {
     /// Creates a new `AssertRecoverSafe` wrapper around the provided type.
diff --git a/src/test/run-pass/panic-safe.rs b/src/test/run-pass/panic-safe.rs
index cd2457e8a52..9949b79278c 100644
--- a/src/test/run-pass/panic-safe.rs
+++ b/src/test/run-pass/panic-safe.rs
@@ -11,7 +11,7 @@
 #![allow(dead_code)]
 #![feature(recover)]
 
-use std::panic::RecoverSafe;
+use std::panic::{RecoverSafe, AssertRecoverSafe};
 use std::cell::RefCell;
 use std::sync::{Mutex, RwLock, Arc};
 use std::rc::Rc;
@@ -47,5 +47,9 @@ fn main() {
         assert::<Box<T>>();
         assert::<Vec<T>>();
         assert::<RefCell<T>>();
+        assert::<AssertRecoverSafe<T>>();
+        assert::<&AssertRecoverSafe<T>>();
+        assert::<Rc<AssertRecoverSafe<T>>>();
+        assert::<Arc<AssertRecoverSafe<T>>>();
     }
 }