mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Auto merge of #30467 - shahn:master, r=brson
This adds a constructor for a Weak that can never be upgraded. These are mostly useless, but for example are required when deserializing.
This commit is contained in:
commit
682cfc5187
@ -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;
|
||||
use core::ops::CoerceUnsized;
|
||||
use core::ptr::{self, Shared};
|
||||
@ -904,6 +905,35 @@ 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::Weak;
|
||||
///
|
||||
/// let empty: Weak<i64> = Weak::new();
|
||||
/// ```
|
||||
#[unstable(feature = "downgraded_weak",
|
||||
reason = "recently added",
|
||||
issue = "30425")]
|
||||
pub fn new() -> Weak<T> {
|
||||
unsafe {
|
||||
Weak { _ptr: Shared::new(Box::into_raw(box ArcInner {
|
||||
strong: atomic::AtomicUsize::new(0),
|
||||
weak: atomic::AtomicUsize::new(1),
|
||||
data: uninitialized(),
|
||||
}))}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::clone::Clone;
|
||||
@ -1154,6 +1184,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")]
|
||||
|
@ -163,7 +163,7 @@ use core::hash::{Hasher, Hash};
|
||||
use core::intrinsics::{assume, abort};
|
||||
use core::marker;
|
||||
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;
|
||||
use core::ops::CoerceUnsized;
|
||||
use core::ptr::{self, Shared};
|
||||
@ -824,6 +824,37 @@ 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();
|
||||
/// ```
|
||||
#[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.
|
||||
@ -1116,6 +1147,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")]
|
||||
|
Loading…
Reference in New Issue
Block a user