From d6bd8d8491e89277edbfc9a4e0f8953847abbdd6 Mon Sep 17 00:00:00 2001 From: Andrew Paseltiner Date: Fri, 16 Oct 2015 11:54:05 -0400 Subject: Add `Shared` pointer and have `{Arc, Rc}` use it This change has two consequences: 1. It makes `Arc` and `Rc` covariant in `T`. 2. It causes the compiler to reject code that was unsound with respect to dropck. See compile-fail/issue-29106.rs for an example of code that no longer compiles. Because of this, this is a [breaking-change]. Fixes #29037. Fixes #29106. --- src/liballoc/arc.rs | 11 ++++++----- src/liballoc/lib.rs | 1 + src/liballoc/rc.rs | 11 ++++++----- 3 files changed, 13 insertions(+), 10 deletions(-) (limited to 'src/liballoc') diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index d8f10e6780f..33ca80ba372 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -79,9 +79,8 @@ use core::cmp::Ordering; use core::mem::{align_of_val, size_of_val}; use core::intrinsics::{drop_in_place, abort}; use core::mem; -use core::nonzero::NonZero; use core::ops::{Deref, CoerceUnsized}; -use core::ptr; +use core::ptr::{self, Shared}; use core::marker::Unsize; use core::hash::{Hash, Hasher}; use core::{usize, isize}; @@ -124,12 +123,13 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; pub struct Arc { // FIXME #12808: strange name to try to avoid interfering with // field accesses of the contained type via Deref - _ptr: NonZero<*mut ArcInner>, + _ptr: Shared>, } unsafe impl Send for Arc { } unsafe impl Sync for Arc { } +#[cfg(not(stage0))] // remove cfg after new snapshot impl, U: ?Sized> CoerceUnsized> for Arc {} /// A weak pointer to an `Arc`. @@ -141,12 +141,13 @@ impl, U: ?Sized> CoerceUnsized> for Arc {} pub struct Weak { // FIXME #12808: strange name to try to avoid interfering with // field accesses of the contained type via Deref - _ptr: NonZero<*mut ArcInner>, + _ptr: Shared>, } unsafe impl Send for Weak { } unsafe impl Sync for Weak { } +#[cfg(not(stage0))] // remove cfg after new snapshot impl, U: ?Sized> CoerceUnsized> for Weak {} #[stable(feature = "rust1", since = "1.0.0")] @@ -190,7 +191,7 @@ impl Arc { weak: atomic::AtomicUsize::new(1), data: data, }; - Arc { _ptr: unsafe { NonZero::new(Box::into_raw(x)) } } + Arc { _ptr: unsafe { Shared::new(Box::into_raw(x)) } } } /// Unwraps the contained value if the `Arc` has only one strong reference. diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 8ecc78a231e..c78ebdf4340 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -90,6 +90,7 @@ #![feature(placement_in_syntax)] #![feature(placement_new_protocol)] #![feature(raw)] +#![feature(shared)] #![feature(staged_api)] #![feature(unboxed_closures)] #![feature(unique)] diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 4753bb2379a..d695c0edd1d 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -163,9 +163,8 @@ use core::hash::{Hasher, Hash}; use core::intrinsics::{assume, drop_in_place, abort}; use core::marker::{self, Unsize}; use core::mem::{self, align_of_val, size_of_val, forget}; -use core::nonzero::NonZero; use core::ops::{CoerceUnsized, Deref}; -use core::ptr; +use core::ptr::{self, Shared}; use heap::deallocate; @@ -184,12 +183,13 @@ struct RcBox { pub struct Rc { // FIXME #12808: strange names to try to avoid interfering with field // accesses of the contained type via Deref - _ptr: NonZero<*mut RcBox>, + _ptr: Shared>, } impl !marker::Send for Rc {} impl !marker::Sync for Rc {} +#[cfg(not(stage0))] // remove cfg after new snapshot impl, U: ?Sized> CoerceUnsized> for Rc {} impl Rc { @@ -210,7 +210,7 @@ impl Rc { // pointers, which ensures that the weak destructor never frees // the allocation while the strong destructor is running, even // if the weak pointer is stored inside the strong one. - _ptr: NonZero::new(Box::into_raw(box RcBox { + _ptr: Shared::new(Box::into_raw(box RcBox { strong: Cell::new(1), weak: Cell::new(1), value: value, @@ -712,12 +712,13 @@ impl fmt::Pointer for Rc { pub struct Weak { // FIXME #12808: strange names to try to avoid interfering with // field accesses of the contained type via Deref - _ptr: NonZero<*mut RcBox>, + _ptr: Shared>, } impl !marker::Send for Weak {} impl !marker::Sync for Weak {} +#[cfg(not(stage0))] // remove cfg after new snapshot impl, U: ?Sized> CoerceUnsized> for Weak {} impl Weak { -- cgit 1.4.1-3-g733a5