New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement Weak::new_downgraded() (#30425) #30467
Changes from 5 commits
79d0235
8bed2ac
0e04386
4741ad3
9697076
7dd618f
5b3bdaf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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<T> From<T> for Arc<T> { | |
} | ||
} | ||
|
||
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 | ||
/// | ||
/// ``` | ||
/// #![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<T> { | ||
unsafe { | ||
let x: Box<_> = box ArcInner { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I mirrored Arc::new(). But I can remove it. |
||
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<usize> = Weak::new(); | ||
assert!(foo.upgrade().is_none()); | ||
} | ||
} | ||
|
||
#[stable(feature = "rust1", since = "1.0.0")] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -164,7 +164,7 @@ 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; | ||
|
@@ -830,6 +830,38 @@ impl<T: ?Sized + fmt::Debug> fmt::Debug for Weak<T> { | |
} | ||
} | ||
|
||
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 | ||
/// | ||
/// ``` | ||
/// #![feature(downgraded_weak)] | ||
/// | ||
/// use std::rc::Weak; | ||
/// | ||
/// let empty:Weak<i64> = Weak::new(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There should be a space before |
||
/// ``` | ||
|
||
#[unstable(feature = "downgraded_weak", | ||
reason = "recently added", | ||
issue="30425")] | ||
pub fn new() -> Weak<T> { | ||
unsafe { | ||
Weak { | ||
_ptr: Shared::new(Box::into_raw(box RcBox { | ||
strong: Cell::new(0), | ||
weak: Cell::new(1), | ||
value: uninitialized(), | ||
})), | ||
} | ||
} | ||
} | ||
} | ||
|
||
// 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 +1154,12 @@ mod tests { | |
let foo_rc = Rc::from(foo); | ||
assert!(123 == *foo_rc); | ||
} | ||
|
||
#[test] | ||
fn test_new_weak() { | ||
let foo: Weak<usize> = Weak::new(); | ||
assert!(foo.upgrade().is_none()); | ||
} | ||
} | ||
|
||
#[stable(feature = "rust1", since = "1.0.0")] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be
Weak::new
.