diff options
| author | Manish Goregaokar <manishsmail@gmail.com> | 2015-12-25 16:54:30 +0530 |
|---|---|---|
| committer | Manish Goregaokar <manishsmail@gmail.com> | 2015-12-25 18:39:54 +0530 |
| commit | 91440adbed5d68a3c9fb52cb0b88c192c771da43 (patch) | |
| tree | 6311a6825cd2644acdce111863a65a7be1a11199 /src/libstd | |
| parent | 12f171b052c07d60760cabbc109d15188ce285ec (diff) | |
| parent | cb3826d9adcb185fbf438602e82ae99ff1878779 (diff) | |
| download | rust-91440adbed5d68a3c9fb52cb0b88c192c771da43.tar.gz rust-91440adbed5d68a3c9fb52cb0b88c192c771da43.zip | |
Rollup merge of #30513 - alexcrichton:assert-is-safe, r=aturon
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')
| -rw-r--r-- | src/libstd/panic.rs | 34 |
1 files changed, 19 insertions, 15 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. |
