From 79d0235439630cd70c4f966db0b2445da1e56393 Mon Sep 17 00:00:00 2001 From: Sebastian Hahn Date: Fri, 18 Dec 2015 20:40:17 +0100 Subject: [PATCH 1/7] 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 8f00605d33b37..15debf2683d1f 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -160,7 +160,7 @@ use core::cell::Cell; 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 @@ impl fmt::Debug for Weak { } } +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 @@ mod tests { 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")] From 8bed2acf92761b53ef96e5a6d60f1c725dd566bd Mon Sep 17 00:00:00 2001 From: Sebastian Hahn Date: Fri, 18 Dec 2015 22:44:53 +0100 Subject: [PATCH 2/7] Fix doctest failure --- src/liballoc/rc.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 15debf2683d1f..26eb8bbe0e14f 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -839,9 +839,11 @@ impl Weak { /// # Examples /// /// ``` + /// #![feature(downgraded_weak)] + /// /// use std::rc::Weak; /// - /// let five = Weak::new_downgraded(); + /// let empty:Weak = Weak::new_downgraded(); /// ``` #[unstable(feature = "downgraded_weak", From 0e043862bf810dd849efd7f6a8ce04ad1dc9cf54 Mon Sep 17 00:00:00 2001 From: Sebastian Hahn Date: Fri, 18 Dec 2015 22:56:09 +0100 Subject: [PATCH 3/7] use core::mem::unintialized instead of uninit intrinsic --- src/liballoc/rc.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 26eb8bbe0e14f..8e649bfbee055 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -160,11 +160,11 @@ use core::cell::Cell; use core::cmp::Ordering; use core::fmt; use core::hash::{Hasher, Hash}; -use core::intrinsics::{assume, abort, uninit}; +use core::intrinsics::{assume, abort}; use core::marker; #[cfg(not(stage0))] use core::marker::Unsize; -use core::mem::{self, align_of_val, size_of_val, forget}; +use core::mem::{self, align_of_val, size_of_val, forget, uninitialized}; use core::ops::Deref; #[cfg(not(stage0))] use core::ops::CoerceUnsized; @@ -855,7 +855,7 @@ impl Weak { _ptr: Shared::new(Box::into_raw(box RcBox { strong: Cell::new(0), weak: Cell::new(1), - value: uninit(), + value: uninitialized(), })), } } From 4741ad38b59d633144ccdfefd3398ec7cf85b3cc Mon Sep 17 00:00:00 2001 From: Sebastian Hahn Date: Fri, 18 Dec 2015 22:56:29 +0100 Subject: [PATCH 4/7] Rename Weak::new_downgraded to Weak::new --- src/liballoc/rc.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 8e649bfbee055..36de9db3493b0 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -843,13 +843,13 @@ impl Weak { /// /// use std::rc::Weak; /// - /// let empty:Weak = Weak::new_downgraded(); + /// let empty:Weak = Weak::new(); /// ``` #[unstable(feature = "downgraded_weak", reason = "recently added", issue="30425")] - pub fn new_downgraded() -> Weak { + pub fn new() -> Weak { unsafe { Weak { _ptr: Shared::new(Box::into_raw(box RcBox { @@ -1156,8 +1156,8 @@ mod tests { } #[test] - fn test_new_downgraded() { - let foo: Weak = Weak::new_downgraded(); + fn test_new_weak() { + let foo: Weak = Weak::new(); assert!(foo.upgrade().is_none()); } } From 9697076b62553fe8ca3dc23d5cc067a94d9e4570 Mon Sep 17 00:00:00 2001 From: Sebastian Hahn Date: Fri, 18 Dec 2015 23:32:16 +0100 Subject: [PATCH 5/7] Implement arc::Weak::new() --- src/liballoc/arc.rs | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 9479d47943eab..377dfb11f9255 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -79,6 +79,7 @@ use core::cmp::Ordering; use core::mem::{align_of_val, size_of_val}; use core::intrinsics::abort; use core::mem; +use core::mem::uninitialized; use core::ops::Deref; #[cfg(not(stage0))] use core::ops::CoerceUnsized; @@ -910,6 +911,36 @@ impl From for Arc { } } +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 + /// + /// ``` + /// #![feature(downgraded_weak)] + /// + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// ``` + #[unstable(feature = "downgraded_weak", + reason = "recently added", + issue = "30425")] + pub fn new() -> Weak { + unsafe { + let x: Box<_> = box ArcInner { + strong: atomic::AtomicUsize::new(0), + weak: atomic::AtomicUsize::new(1), + data: uninitialized(), + }; + Weak { _ptr: Shared::new(Box::into_raw(x)) } + } + } +} + #[cfg(test)] mod tests { use std::clone::Clone; @@ -1160,6 +1191,12 @@ mod tests { let foo_arc = Arc::from(foo); assert!(123 == *foo_arc); } + + #[test] + fn test_new_weak() { + let foo: Weak = Weak::new(); + assert!(foo.upgrade().is_none()); + } } #[stable(feature = "rust1", since = "1.0.0")] From 7dd618fd23db19cef9c20711aafb760efd00420f Mon Sep 17 00:00:00 2001 From: Sebastian Hahn Date: Sat, 19 Dec 2015 01:31:21 +0100 Subject: [PATCH 6/7] Address review comments --- src/liballoc/arc.rs | 7 +++---- src/liballoc/rc.rs | 3 +-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 377dfb11f9255..b4c3d26ef9f07 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -924,19 +924,18 @@ impl Weak { /// /// use std::sync::Arc; /// - /// let five = Arc::new(5); + /// let empty: Weak = Weak::new(); /// ``` #[unstable(feature = "downgraded_weak", reason = "recently added", issue = "30425")] pub fn new() -> Weak { unsafe { - let x: Box<_> = box ArcInner { + Weak { _ptr: Shared::new(Box::into_raw(box ArcInner { strong: atomic::AtomicUsize::new(0), weak: atomic::AtomicUsize::new(1), data: uninitialized(), - }; - Weak { _ptr: Shared::new(Box::into_raw(x)) } + }))} } } } diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 36de9db3493b0..bf4ed8065e696 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -843,9 +843,8 @@ impl Weak { /// /// use std::rc::Weak; /// - /// let empty:Weak = Weak::new(); + /// let empty: Weak = Weak::new(); /// ``` - #[unstable(feature = "downgraded_weak", reason = "recently added", issue="30425")] From 5b3bdafb9649b8cbaf62535c12dbfee6e9e073be Mon Sep 17 00:00:00 2001 From: Sebastian Hahn Date: Sat, 19 Dec 2015 01:49:36 +0100 Subject: [PATCH 7/7] Have to use Weak instead of Arc in Weak::new() example --- src/liballoc/arc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index b4c3d26ef9f07..9b6b74f3b7b91 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -922,7 +922,7 @@ impl Weak { /// ``` /// #![feature(downgraded_weak)] /// - /// use std::sync::Arc; + /// use std::sync::Weak; /// /// let empty: Weak = Weak::new(); /// ```