Skip to content

Commit 79d0235

Browse files
committed
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.
1 parent de62f9d commit 79d0235

File tree

1 file changed

+37
-1
lines changed

1 file changed

+37
-1
lines changed

src/liballoc/rc.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ use core::cell::Cell;
160160
use core::cmp::Ordering;
161161
use core::fmt;
162162
use core::hash::{Hasher, Hash};
163-
use core::intrinsics::{assume, abort};
163+
use core::intrinsics::{assume, abort, uninit};
164164
use core::marker;
165165
#[cfg(not(stage0))]
166166
use core::marker::Unsize;
@@ -830,6 +830,36 @@ impl<T: ?Sized + fmt::Debug> fmt::Debug for Weak<T> {
830830
}
831831
}
832832

833+
impl<T> Weak<T> {
834+
/// Constructs a new `Weak<T>` without an accompanying instance of T.
835+
///
836+
/// This allocates memory for T, but does not initialize it. Calling
837+
/// Weak<T>::upgrade() on the return value always gives None.
838+
///
839+
/// # Examples
840+
///
841+
/// ```
842+
/// use std::rc::Weak;
843+
///
844+
/// let five = Weak::new_downgraded();
845+
/// ```
846+
847+
#[unstable(feature = "downgraded_weak",
848+
reason = "recently added",
849+
issue="30425")]
850+
pub fn new_downgraded() -> Weak<T> {
851+
unsafe {
852+
Weak {
853+
_ptr: Shared::new(Box::into_raw(box RcBox {
854+
strong: Cell::new(0),
855+
weak: Cell::new(1),
856+
value: uninit(),
857+
})),
858+
}
859+
}
860+
}
861+
}
862+
833863
// NOTE: We checked_add here to deal with mem::forget safety. In particular
834864
// if you mem::forget Rcs (or Weaks), the ref-count can overflow, and then
835865
// you can free the allocation while outstanding Rcs (or Weaks) exist.
@@ -1122,6 +1152,12 @@ mod tests {
11221152
let foo_rc = Rc::from(foo);
11231153
assert!(123 == *foo_rc);
11241154
}
1155+
1156+
#[test]
1157+
fn test_new_downgraded() {
1158+
let foo: Weak<usize> = Weak::new_downgraded();
1159+
assert!(foo.upgrade().is_none());
1160+
}
11251161
}
11261162

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

0 commit comments

Comments
 (0)