use core::ptr::{self, PtrExt};
use core::result::Result;
use core::result::Result::{Ok, Err};
+use core::intrinsics::assume;
use heap::deallocate;
// FIXME #12808: strange names to try to avoid interfering with field accesses of the contained
// type via Deref
_ptr: NonZero<*mut RcBox<T>>,
- _nosend: marker::NoSend,
- _noshare: marker::NoSync
}
+impl<T> !marker::Send for Rc<T> {}
+
+impl<T> !marker::Sync for Rc<T> {}
+
impl<T> Rc<T> {
+
/// Constructs a new `Rc<T>`.
///
/// # Examples
strong: Cell::new(1),
weak: Cell::new(1)
})),
- _nosend: marker::NoSend,
- _noshare: marker::NoSync
}
}
}
///
/// let weak_five = five.downgrade();
/// ```
- #[experimental = "Weak pointers may not belong in this module"]
+ #[unstable = "Weak pointers may not belong in this module"]
pub fn downgrade(&self) -> Weak<T> {
self.inc_weak();
- Weak {
- _ptr: self._ptr,
- _nosend: marker::NoSend,
- _noshare: marker::NoSync
- }
+ Weak { _ptr: self._ptr }
}
}
/// Get the number of weak references to this value.
#[inline]
-#[experimental]
+#[unstable]
pub fn weak_count<T>(this: &Rc<T>) -> uint { this.weak() - 1 }
/// Get the number of strong references to this value.
#[inline]
-#[experimental]
+#[unstable]
pub fn strong_count<T>(this: &Rc<T>) -> uint { this.strong() }
/// Returns true if there are no other `Rc` or `Weak<T>` values that share the same inner value.
/// rc::is_unique(&five);
/// ```
#[inline]
-#[experimental]
+#[unstable]
pub fn is_unique<T>(rc: &Rc<T>) -> bool {
weak_count(rc) == 0 && strong_count(rc) == 1
}
/// assert_eq!(rc::try_unwrap(x), Err(Rc::new(4u)));
/// ```
#[inline]
-#[experimental]
+#[unstable]
pub fn try_unwrap<T>(rc: Rc<T>) -> Result<T, Rc<T>> {
if is_unique(&rc) {
unsafe {
/// assert!(rc::get_mut(&mut x).is_none());
/// ```
#[inline]
-#[experimental]
+#[unstable]
pub fn get_mut<'a, T>(rc: &'a mut Rc<T>) -> Option<&'a mut T> {
if is_unique(rc) {
let inner = unsafe { &mut **rc._ptr };
/// let mut_five = five.make_unique();
/// ```
#[inline]
- #[experimental]
+ #[unstable]
pub fn make_unique(&mut self) -> &mut T {
if !is_unique(self) {
*self = Rc::new((**self).clone())
#[stable]
impl<T> Clone for Rc<T> {
+
/// Makes a clone of the `Rc<T>`.
///
/// This increases the strong reference count.
#[inline]
fn clone(&self) -> Rc<T> {
self.inc_strong();
- Rc { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoSync }
+ Rc { _ptr: self._ptr }
}
}
}
// FIXME (#18248) Make `T` `Sized?`
-#[cfg(stage0)]
-impl<S: hash::Writer, T: Hash<S>> Hash<S> for Rc<T> {
- #[inline]
- fn hash(&self, state: &mut S) {
- (**self).hash(state);
- }
-}
-#[cfg(not(stage0))]
impl<S: hash::Hasher, T: Hash<S>> Hash<S> for Rc<T> {
#[inline]
fn hash(&self, state: &mut S) {
}
}
-#[experimental = "Show is experimental."]
+#[unstable = "Show is experimental."]
impl<T: fmt::Show> fmt::Show for Rc<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Rc({:?})", **self)
///
/// See the [module level documentation](../index.html) for more.
#[unsafe_no_drop_flag]
-#[experimental = "Weak pointers may not belong in this module."]
+#[unstable = "Weak pointers may not belong in this module."]
pub struct Weak<T> {
// FIXME #12808: strange names to try to avoid interfering with
// field accesses of the contained type via Deref
_ptr: NonZero<*mut RcBox<T>>,
- _nosend: marker::NoSend,
- _noshare: marker::NoSync
}
-#[experimental = "Weak pointers may not belong in this module."]
+#[allow(unstable)]
+impl<T> !marker::Send for Weak<T> {}
+
+#[allow(unstable)]
+impl<T> !marker::Sync for Weak<T> {}
+
+
+#[unstable = "Weak pointers may not belong in this module."]
impl<T> Weak<T> {
+
/// Upgrades a weak reference to a strong reference.
///
/// Upgrades the `Weak<T>` reference to an `Rc<T>`, if possible.
None
} else {
self.inc_strong();
- Some(Rc { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoSync })
+ Some(Rc { _ptr: self._ptr })
}
}
}
}
}
-#[experimental = "Weak pointers may not belong in this module."]
+#[unstable = "Weak pointers may not belong in this module."]
impl<T> Clone for Weak<T> {
+
/// Makes a clone of the `Weak<T>`.
///
/// This increases the weak reference count.
#[inline]
fn clone(&self) -> Weak<T> {
self.inc_weak();
- Weak { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoSync }
+ Weak { _ptr: self._ptr }
}
}
-#[experimental = "Show is experimental."]
+#[unstable = "Show is experimental."]
impl<T: fmt::Show> fmt::Show for Weak<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "(Weak)")
fn strong(&self) -> uint { self.inner().strong.get() }
#[inline]
- fn inc_strong(&self) { self.inner().strong.set(self.strong() + 1); }
+ fn inc_strong(&self) {
+ let strong = self.strong();
+ // The reference count is always at least one unless we're about to drop the type
+ // This allows the bulk of the destructor to be omitted in cases where we know that
+ // the reference count must be > 0.
+ unsafe { assume(strong > 0); }
+ self.inner().strong.set(strong + 1);
+ }
#[inline]
- fn dec_strong(&self) { self.inner().strong.set(self.strong() - 1); }
+ fn dec_strong(&self) {
+ let strong = self.strong();
+ // The reference count is always at least one unless we're about to drop the type
+ // This allows the bulk of the destructor to be omitted in cases where we know that
+ // the reference count must be > 0
+ unsafe { assume(strong > 0); }
+ self.inner().strong.set(strong - 1);
+ }
#[inline]
fn weak(&self) -> uint { self.inner().weak.get() }
impl<T> RcBoxPtr<T> for Rc<T> {
#[inline(always)]
- fn inner(&self) -> &RcBox<T> { unsafe { &(**self._ptr) } }
+ fn inner(&self) -> &RcBox<T> {
+ unsafe {
+ // Safe to assume this here, as if it weren't true, we'd be breaking
+ // the contract anyway.
+ // This allows the null check to be elided in the destructor if we
+ // manipulated the reference count in the same function.
+ assume(!self._ptr.is_null());
+ &(**self._ptr)
+ }
+ }
}
impl<T> RcBoxPtr<T> for Weak<T> {
#[inline(always)]
- fn inner(&self) -> &RcBox<T> { unsafe { &(**self._ptr) } }
+ fn inner(&self) -> &RcBox<T> {
+ unsafe {
+ // Safe to assume this here, as if it weren't true, we'd be breaking
+ // the contract anyway
+ // This allows the null check to be elided in the destructor if we
+ // manipulated the reference count in the same function.
+ assume(!self._ptr.is_null());
+ &(**self._ptr)
+ }
+ }
}
#[cfg(test)]
-#[allow(experimental)]
+#[allow(unstable)]
mod tests {
use super::{Rc, Weak, weak_count, strong_count};
use std::cell::RefCell;