From cb3826d9adcb185fbf438602e82ae99ff1878779 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 21 Dec 2015 09:39:45 -0800 Subject: std: Ensure AssertRecoverSafe indeed is more often Types like `&AssertRecoverSafe` and `Rc>` 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 --- src/libstd/panic.rs | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) (limited to 'src/libstd/panic.rs') 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); // * 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 RecoverSafe for *const T {} -impl RecoverSafe for *mut T {} +impl<'a, T: RefRecoverSafe + ?Sized> RecoverSafe for &'a T {} +impl RecoverSafe for *const T {} +impl RecoverSafe for *mut T {} impl RecoverSafe for Unique {} -impl RecoverSafe for Shared {} +impl RecoverSafe for Shared {} impl RecoverSafe for Mutex {} impl RecoverSafe for RwLock {} impl RecoverSafe for AssertRecoverSafe {} @@ -169,15 +172,16 @@ impl RecoverSafe for AssertRecoverSafe {} // 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 RecoverSafe for Rc {} -impl RecoverSafe for Arc {} +impl RecoverSafe for Rc {} +impl RecoverSafe for Arc {} -// 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 !NoUnsafeCell for UnsafeCell {} +// 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 !RefRecoverSafe for UnsafeCell {} +impl RefRecoverSafe for AssertRecoverSafe {} impl AssertRecoverSafe { /// Creates a new `AssertRecoverSafe` wrapper around the provided type. -- cgit 1.4.1-3-g733a5