From 79d0235439630cd70c4f966db0b2445da1e56393 Mon Sep 17 00:00:00 2001 From: Sebastian Hahn Date: Fri, 18 Dec 2015 20:40:17 +0100 Subject: [PATCH] Implement Weak::new_downgraded() (#30425) This adds a constructor for a Weak that can never be upgraded. These are mostly useless, but for example are required when deserializing. --- src/liballoc/rc.rs | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 8f00605d33b..15debf2683d 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -160,7 +160,7 @@ 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; @@ -830,6 +830,36 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } +impl Weak { + /// Constructs a new `Weak` without an accompanying instance of T. + /// + /// This allocates memory for T, but does not initialize it. Calling + /// Weak::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 { + 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. @@ -1122,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 = Weak::new_downgraded(); + assert!(foo.upgrade().is_none()); + } } #[stable(feature = "rust1", since = "1.0.0")] -- 2.44.0