diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs index 6e4ba337b08ee..0f5a08ba3ffe7 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. diff --git a/src/test/run-pass/panic-safe.rs b/src/test/run-pass/panic-safe.rs index cd2457e8a52f7..9949b79278c11 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::>(); assert::>(); assert::>(); + assert::>(); + assert::<&AssertRecoverSafe>(); + assert::>>(); + assert::>>(); } }