mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Rollup merge of #109026 - joshtriplett:rc-into-inner, r=dtolnay
Introduce `Rc::into_inner`, as a parallel to `Arc::into_inner` Unlike `Arc`, `Rc` doesn't have the same race condition to avoid, but maintaining an equivalent API still makes it easier to work with both `Rc` and `Arc`.
This commit is contained in:
commit
b28775cdcb
@ -681,6 +681,24 @@ impl<T> Rc<T> {
|
||||
Err(this)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the inner value, if the `Rc` has exactly one strong reference.
|
||||
///
|
||||
/// Otherwise, [`None`] is returned and the `Rc` is dropped.
|
||||
///
|
||||
/// This will succeed even if there are outstanding weak references.
|
||||
///
|
||||
/// If `Rc::into_inner` is called on every clone of this `Rc`,
|
||||
/// it is guaranteed that exactly one of the calls returns the inner value.
|
||||
/// This means in particular that the inner value is not dropped.
|
||||
///
|
||||
/// This is equivalent to `Rc::try_unwrap(...).ok()`. (Note that these are not equivalent for
|
||||
/// `Arc`, due to race conditions that do not apply to `Rc`.)
|
||||
#[inline]
|
||||
#[unstable(feature = "rc_into_inner", issue = "106894")]
|
||||
pub fn into_inner(this: Self) -> Option<T> {
|
||||
Rc::try_unwrap(this).ok()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Rc<[T]> {
|
||||
|
@ -151,6 +151,21 @@ fn try_unwrap() {
|
||||
assert_eq!(Rc::try_unwrap(x), Ok(5));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn into_inner() {
|
||||
let x = Rc::new(3);
|
||||
assert_eq!(Rc::into_inner(x), Some(3));
|
||||
|
||||
let x = Rc::new(4);
|
||||
let y = Rc::clone(&x);
|
||||
assert_eq!(Rc::into_inner(x), None);
|
||||
assert_eq!(Rc::into_inner(y), Some(4));
|
||||
|
||||
let x = Rc::new(5);
|
||||
let _w = Rc::downgrade(&x);
|
||||
assert_eq!(Rc::into_inner(x), Some(5));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn into_from_raw() {
|
||||
let x = Rc::new(Box::new("hello"));
|
||||
|
Loading…
Reference in New Issue
Block a user