]> git.lizzy.rs Git - rust.git/blobdiff - src/liballoc/rc.rs
Implement Weak::new_downgraded() (#30425)
[rust.git] / src / liballoc / rc.rs
index 0ea5ecfda79e09a9f60538d2da7a62cc72bcf7d4..15debf2683d1f598d3ec36707849e2653dda780a 100644 (file)
 use core::cmp::Ordering;
 use core::fmt;
 use core::hash::{Hasher, Hash};
-use core::intrinsics::{assume, abort};
+use core::intrinsics::{assume, abort, uninit};
 use core::marker;
 #[cfg(not(stage0))]
 use core::marker::Unsize;
@@ -196,9 +196,10 @@ impl<T: ?Sized> !marker::Send for Rc<T> {}
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> !marker::Sync for Rc<T> {}
 
-#[cfg(not(stage0))] // remove cfg after new snapshot
+// remove cfg after new snapshot
+#[cfg(not(stage0))]
 #[unstable(feature = "coerce_unsized", issue = "27732")]
-impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<Rc<U>> for Rc<T> {}
+impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Rc<U>> for Rc<T> {}
 
 impl<T> Rc<T> {
     /// Constructs a new `Rc<T>`.
@@ -359,14 +360,6 @@ pub fn get_mut(this: &mut Self) -> Option<&mut T> {
 }
 
 impl<T: Clone> Rc<T> {
-    #[inline]
-    #[unstable(feature = "rc_make_unique", reason = "renamed to Rc::make_mut",
-               issue = "27718")]
-    #[rustc_deprecated(since = "1.4.0", reason = "renamed to Rc::make_mut")]
-    pub fn make_unique(&mut self) -> &mut T {
-        Rc::make_mut(self)
-    }
-
     /// Make a mutable reference into the given `Rc<T>` by cloning the inner
     /// data if the `Rc<T>` doesn't have one strong reference and no weak
     /// references.
@@ -482,7 +475,6 @@ fn drop(&mut self) {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> Clone for Rc<T> {
-
     /// Makes a clone of the `Rc<T>`.
     ///
     /// When you clone an `Rc<T>`, it will create another pointer to the data and
@@ -678,21 +670,21 @@ fn cmp(&self, other: &Rc<T>) -> Ordering {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized+Hash> Hash for Rc<T> {
+impl<T: ?Sized + Hash> Hash for Rc<T> {
     fn hash<H: Hasher>(&self, state: &mut H) {
         (**self).hash(state);
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized+fmt::Display> fmt::Display for Rc<T> {
+impl<T: ?Sized + fmt::Display> fmt::Display for Rc<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         fmt::Display::fmt(&**self, f)
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized+fmt::Debug> fmt::Debug for Rc<T> {
+impl<T: ?Sized + fmt::Debug> fmt::Debug for Rc<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         fmt::Debug::fmt(&**self, f)
     }
@@ -731,9 +723,10 @@ impl<T: ?Sized> !marker::Send for Weak<T> {}
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> !marker::Sync for Weak<T> {}
 
-#[cfg(not(stage0))] // remove cfg after new snapshot
+// remove cfg after new snapshot
+#[cfg(not(stage0))]
 #[unstable(feature = "coerce_unsized", issue = "27732")]
-impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<Weak<U>> for Weak<T> {}
+impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Weak<U>> for Weak<T> {}
 
 impl<T: ?Sized> Weak<T> {
     /// Upgrades a weak reference to a strong reference.
@@ -810,7 +803,6 @@ fn drop(&mut self) {
 
 #[stable(feature = "rc_weak", since = "1.4.0")]
 impl<T: ?Sized> Clone for Weak<T> {
-
     /// Makes a clone of the `Weak<T>`.
     ///
     /// This increases the weak reference count.
@@ -832,12 +824,42 @@ fn clone(&self) -> Weak<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized+fmt::Debug> fmt::Debug for Weak<T> {
+impl<T: ?Sized + fmt::Debug> fmt::Debug for Weak<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "(Weak)")
     }
 }
 
+impl<T> Weak<T> {
+    /// Constructs a new `Weak<T>` without an accompanying instance of T.
+    ///
+    /// This allocates memory for T, but does not initialize it. Calling
+    /// Weak<T>::upgrade() on the return value always gives None.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::rc::Weak;
+    ///
+    /// let five = Weak::new_downgraded();
+    /// ```
+
+    #[unstable(feature = "downgraded_weak",
+               reason = "recently added",
+               issue="30425")]
+    pub fn new_downgraded() -> Weak<T> {
+        unsafe {
+            Weak {
+                _ptr: Shared::new(Box::into_raw(box RcBox {
+                    strong: Cell::new(0),
+                    weak: Cell::new(1),
+                    value: uninit(),
+                })),
+            }
+        }
+    }
+}
+
 // NOTE: We checked_add here to deal with mem::forget safety. In particular
 // if you mem::forget Rcs (or Weaks), the ref-count can overflow, and then
 // you can free the allocation while outstanding Rcs (or Weaks) exist.
@@ -1130,6 +1152,12 @@ fn test_from_owned() {
         let foo_rc = Rc::from(foo);
         assert!(123 == *foo_rc);
     }
+
+    #[test]
+    fn test_new_downgraded() {
+        let foo: Weak<usize> = Weak::new_downgraded();
+        assert!(foo.upgrade().is_none());
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]