Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions library/alloc/src/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]> {
Expand Down
16 changes: 16 additions & 0 deletions library/alloc/src/rc/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,22 @@ 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));
}


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

One less newline will make the formatting tidy check happy :-)

#[test]
fn into_from_raw() {
let x = Rc::new(Box::new("hello"));
Expand Down