Skip to content

Commit

Permalink
Implement Weak::new_downgraded() (rust-lang#30425)
Browse files Browse the repository at this point in the history
This adds a constructor for a Weak that can never be upgraded. These are
mostly useless, but for example are required when deserializing.
  • Loading branch information
shahn committed Dec 18, 2015
1 parent de62f9d commit 79d0235
Showing 1 changed file with 37 additions and 1 deletion.
38 changes: 37 additions & 1 deletion src/liballoc/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -830,6 +830,36 @@ 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

This comment has been minimized.

Copy link
@sfackler

sfackler Dec 19, 2015

Not sure how valuable an example that does nothing but call the method is.

///
/// ```
/// use std::rc::Weak;
///
/// let five = Weak::new_downgraded();

This comment has been minimized.

Copy link
@sfackler

sfackler Dec 19, 2015

five?

/// ```
#[unstable(feature = "downgraded_weak",
reason = "recently added",
issue="30425")]
pub fn new_downgraded() -> Weak<T> {
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.
Expand Down Expand Up @@ -1122,6 +1152,12 @@ mod tests {
let foo_rc = Rc::from(foo);
assert!(123 == *foo_rc);
}

#[test]
fn test_new_downgraded() {
let foo: Weak<usize> = Weak::new_downgraded();
assert!(foo.upgrade().is_none());
}
}

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

0 comments on commit 79d0235

Please sign in to comment.