about summary refs log tree commit diff
path: root/src/libstd/panic.rs
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-12-21 09:39:45 -0800
committerAlex Crichton <alex@alexcrichton.com>2015-12-21 14:00:17 -0800
commitcb3826d9adcb185fbf438602e82ae99ff1878779 (patch)
treee76bf3242b13d29bf488a2acdeabd4df9172d91c /src/libstd/panic.rs
parente2834a20e7c5bbfb1502f582545153dc6b25a70c (diff)
downloadrust-cb3826d9adcb185fbf438602e82ae99ff1878779.tar.gz
rust-cb3826d9adcb185fbf438602e82ae99ff1878779.zip
std: Ensure AssertRecoverSafe indeed is more often
Types like `&AssertRecoverSafe<T>` and `Rc<AssertRecoverSafe<T>>` were
mistakenly not considered recover safe, but the point of the assertion wrapper
is that it indeed is! This was caused by an interaction between the
`RecoverSafe` and `NoUnsafeCell` marker traits, and this is updated by adding an
impl of the `NoUnsafeCell` marker trait for `AssertRecoverSafe` to ensure that
it never interacts with the other negative impls of `RecoverSafe`.

cc #30510
Diffstat (limited to 'src/libstd/panic.rs')
-rw-r--r--src/libstd/panic.rs34
1 files changed, 19 insertions, 15 deletions
diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs
index 6e4ba337b08..0f5a08ba3ff 100644
--- a/src/libstd/panic.rs
+++ b/src/libstd/panic.rs
@@ -99,8 +99,11 @@ use thread::Result;
                             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.
@@ -108,7 +111,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.
 ///
@@ -157,11 +160,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> {}
@@ -169,15 +172,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.