From bb04121138b636f6aa43e10fa38629043a0f0f48 Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Sun, 11 Jan 2015 11:09:53 +0100 Subject: [PATCH] Don't use NoSend/NoSync in liballoc --- src/liballoc/lib.rs | 1 + src/liballoc/rc.rs | 159 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 160 insertions(+) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 4a85637625a..6c853306035 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -68,6 +68,7 @@ #![allow(unknown_features)] #![feature(lang_items, unsafe_destructor)] #![feature(box_syntax)] +#![feature(optin_builtin_traits)] #![allow(unknown_features)] #![feature(int_uint)] #[macro_use] diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index f42c6dbdc15..0e18cdda8dd 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -174,6 +174,7 @@ struct RcBox { /// See the [module level documentation](../index.html) for more details. #[unsafe_no_drop_flag] #[stable] +#[cfg(stage0)] // NOTE remove impl after next snapshot pub struct Rc { // FIXME #12808: strange names to try to avoid interfering with field accesses of the contained // type via Deref @@ -182,6 +183,24 @@ pub struct Rc { _noshare: marker::NoSync } +/// An immutable reference-counted pointer type. +/// +/// See the [module level documentation](../index.html) for more details. +#[unsafe_no_drop_flag] +#[stable] +#[cfg(not(stage0))] // NOTE remove cfg after next snapshot +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>, +} + +#[cfg(not(stage0))] // NOTE remove cfg after next snapshot +impl !marker::Send for Rc {} + +#[cfg(not(stage0))] // NOTE remove cfg after next snapshot +impl !marker::Sync for Rc {} + impl Rc { /// Constructs a new `Rc`. /// @@ -193,6 +212,7 @@ impl Rc { /// let five = Rc::new(5i); /// ``` #[stable] + #[cfg(stage0)] // NOTE remove after next snapshot pub fn new(value: T) -> Rc { unsafe { Rc { @@ -210,6 +230,32 @@ pub fn new(value: T) -> Rc { } } + /// Constructs a new `Rc`. + /// + /// # Examples + /// + /// ``` + /// use std::rc::Rc; + /// + /// let five = Rc::new(5i); + /// ``` + #[stable] + #[cfg(not(stage0))] // NOTE remove cfg after next snapshot + pub fn new(value: T) -> Rc { + unsafe { + Rc { + // there is an implicit weak pointer owned by all the strong 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(transmute(box RcBox { + value: value, + strong: Cell::new(1), + weak: Cell::new(1) + })), + } + } + } + /// Downgrades the `Rc` to a `Weak` reference. /// /// # Examples @@ -221,6 +267,7 @@ pub fn new(value: T) -> Rc { /// /// let weak_five = five.downgrade(); /// ``` + #[cfg(stage0)] // NOTE remove after next snapshot #[unstable = "Weak pointers may not belong in this module"] pub fn downgrade(&self) -> Weak { self.inc_weak(); @@ -230,6 +277,24 @@ pub fn downgrade(&self) -> Weak { _noshare: marker::NoSync } } + + /// Downgrades the `Rc` to a `Weak` reference. + /// + /// # Examples + /// + /// ``` + /// use std::rc::Rc; + /// + /// let five = Rc::new(5i); + /// + /// let weak_five = five.downgrade(); + /// ``` + #[cfg(not(stage0))] // NOTE remove cfg after next snapshot + #[unstable = "Weak pointers may not belong in this module"] + pub fn downgrade(&self) -> Weak { + self.inc_weak(); + Weak { _ptr: self._ptr } + } } /// Get the number of weak references to this value. @@ -432,10 +497,31 @@ impl Clone for Rc { /// five.clone(); /// ``` #[inline] + #[cfg(stage0)] // NOTE remove after next snapshot fn clone(&self) -> Rc { self.inc_strong(); Rc { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoSync } } + + /// Makes a clone of the `Rc`. + /// + /// This increases the strong reference count. + /// + /// # Examples + /// + /// ``` + /// use std::rc::Rc; + /// + /// let five = Rc::new(5i); + /// + /// five.clone(); + /// ``` + #[inline] + #[cfg(not(stage0))] // NOTE remove cfg after next snapshot + fn clone(&self) -> Rc { + self.inc_strong(); + Rc { _ptr: self._ptr } + } } #[stable] @@ -636,6 +722,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { /// See the [module level documentation](../index.html) for more. #[unsafe_no_drop_flag] #[unstable = "Weak pointers may not belong in this module."] +#[cfg(stage0)] // NOTE remove impl after next snapshot pub struct Weak { // FIXME #12808: strange names to try to avoid interfering with // field accesses of the contained type via Deref @@ -644,6 +731,29 @@ pub struct Weak { _noshare: marker::NoSync } +/// A weak version of `Rc`. +/// +/// Weak references do not count when determining if the inner value should be dropped. +/// +/// See the [module level documentation](../index.html) for more. +#[unsafe_no_drop_flag] +#[unstable = "Weak pointers may not belong in this module."] +#[cfg(not(stage0))] // NOTE remove cfg after next snapshot +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>, +} + +#[cfg(not(stage0))] // NOTE remove cfg after next snapshot +#[allow(unstable)] +impl !marker::Send for Weak {} + +#[cfg(not(stage0))] // NOTE remove cfg after next snapshot +#[allow(unstable)] +impl !marker::Sync for Weak {} + + #[unstable = "Weak pointers may not belong in this module."] impl Weak { /// Upgrades a weak reference to a strong reference. @@ -663,6 +773,7 @@ impl Weak { /// /// let strong_five: Option> = weak_five.upgrade(); /// ``` + #[cfg(stage0)] // NOTE remove after next snapshot pub fn upgrade(&self) -> Option> { if self.strong() == 0 { None @@ -671,6 +782,33 @@ pub fn upgrade(&self) -> Option> { Some(Rc { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoSync }) } } + + /// Upgrades a weak reference to a strong reference. + /// + /// Upgrades the `Weak` reference to an `Rc`, if possible. + /// + /// Returns `None` if there were no strong references and the data was destroyed. + /// + /// # Examples + /// + /// ``` + /// use std::rc::Rc; + /// + /// let five = Rc::new(5i); + /// + /// let weak_five = five.downgrade(); + /// + /// let strong_five: Option> = weak_five.upgrade(); + /// ``` + #[cfg(not(stage0))] // NOTE remove cfg after next snapshot + pub fn upgrade(&self) -> Option> { + if self.strong() == 0 { + None + } else { + self.inc_strong(); + Some(Rc { _ptr: self._ptr }) + } + } } #[unsafe_destructor] @@ -733,10 +871,31 @@ impl Clone for Weak { /// weak_five.clone(); /// ``` #[inline] + #[cfg(stage0)] // NOTE remove after next snapshot fn clone(&self) -> Weak { self.inc_weak(); Weak { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoSync } } + + /// Makes a clone of the `Weak`. + /// + /// This increases the weak reference count. + /// + /// # Examples + /// + /// ``` + /// use std::rc::Rc; + /// + /// let weak_five = Rc::new(5i).downgrade(); + /// + /// weak_five.clone(); + /// ``` + #[inline] + #[cfg(not(stage0))] // NOTE remove cfg after next snapshot + fn clone(&self) -> Weak { + self.inc_weak(); + Weak { _ptr: self._ptr } + } } #[unstable = "Show is experimental."]