Skip to content

Commit 682cfc5

Browse files
committed
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.
2 parents efb5a9a + 5b3bdaf commit 682cfc5

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed

src/liballoc/arc.rs

+36
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ use core::cmp::Ordering;
7979
use core::mem::{align_of_val, size_of_val};
8080
use core::intrinsics::abort;
8181
use core::mem;
82+
use core::mem::uninitialized;
8283
use core::ops::Deref;
8384
use core::ops::CoerceUnsized;
8485
use core::ptr::{self, Shared};
@@ -904,6 +905,35 @@ impl<T> From<T> for Arc<T> {
904905
}
905906
}
906907

908+
impl<T> Weak<T> {
909+
/// Constructs a new `Weak<T>` without an accompanying instance of T.
910+
///
911+
/// This allocates memory for T, but does not initialize it. Calling
912+
/// Weak<T>::upgrade() on the return value always gives None.
913+
///
914+
/// # Examples
915+
///
916+
/// ```
917+
/// #![feature(downgraded_weak)]
918+
///
919+
/// use std::sync::Weak;
920+
///
921+
/// let empty: Weak<i64> = Weak::new();
922+
/// ```
923+
#[unstable(feature = "downgraded_weak",
924+
reason = "recently added",
925+
issue = "30425")]
926+
pub fn new() -> Weak<T> {
927+
unsafe {
928+
Weak { _ptr: Shared::new(Box::into_raw(box ArcInner {
929+
strong: atomic::AtomicUsize::new(0),
930+
weak: atomic::AtomicUsize::new(1),
931+
data: uninitialized(),
932+
}))}
933+
}
934+
}
935+
}
936+
907937
#[cfg(test)]
908938
mod tests {
909939
use std::clone::Clone;
@@ -1154,6 +1184,12 @@ mod tests {
11541184
let foo_arc = Arc::from(foo);
11551185
assert!(123 == *foo_arc);
11561186
}
1187+
1188+
#[test]
1189+
fn test_new_weak() {
1190+
let foo: Weak<usize> = Weak::new();
1191+
assert!(foo.upgrade().is_none());
1192+
}
11571193
}
11581194

11591195
#[stable(feature = "rust1", since = "1.0.0")]

src/liballoc/rc.rs

+38-1
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ use core::hash::{Hasher, Hash};
163163
use core::intrinsics::{assume, abort};
164164
use core::marker;
165165
use core::marker::Unsize;
166-
use core::mem::{self, align_of_val, size_of_val, forget};
166+
use core::mem::{self, align_of_val, size_of_val, forget, uninitialized};
167167
use core::ops::Deref;
168168
use core::ops::CoerceUnsized;
169169
use core::ptr::{self, Shared};
@@ -824,6 +824,37 @@ impl<T: ?Sized + fmt::Debug> fmt::Debug for Weak<T> {
824824
}
825825
}
826826

827+
impl<T> Weak<T> {
828+
/// Constructs a new `Weak<T>` without an accompanying instance of T.
829+
///
830+
/// This allocates memory for T, but does not initialize it. Calling
831+
/// Weak<T>::upgrade() on the return value always gives None.
832+
///
833+
/// # Examples
834+
///
835+
/// ```
836+
/// #![feature(downgraded_weak)]
837+
///
838+
/// use std::rc::Weak;
839+
///
840+
/// let empty: Weak<i64> = Weak::new();
841+
/// ```
842+
#[unstable(feature = "downgraded_weak",
843+
reason = "recently added",
844+
issue="30425")]
845+
pub fn new() -> Weak<T> {
846+
unsafe {
847+
Weak {
848+
_ptr: Shared::new(Box::into_raw(box RcBox {
849+
strong: Cell::new(0),
850+
weak: Cell::new(1),
851+
value: uninitialized(),
852+
})),
853+
}
854+
}
855+
}
856+
}
857+
827858
// NOTE: We checked_add here to deal with mem::forget safety. In particular
828859
// if you mem::forget Rcs (or Weaks), the ref-count can overflow, and then
829860
// you can free the allocation while outstanding Rcs (or Weaks) exist.
@@ -1116,6 +1147,12 @@ mod tests {
11161147
let foo_rc = Rc::from(foo);
11171148
assert!(123 == *foo_rc);
11181149
}
1150+
1151+
#[test]
1152+
fn test_new_weak() {
1153+
let foo: Weak<usize> = Weak::new();
1154+
assert!(foo.upgrade().is_none());
1155+
}
11191156
}
11201157

11211158
#[stable(feature = "rust1", since = "1.0.0")]

0 commit comments

Comments
 (0)