Stabilize arc_new_cyclic
This commit is contained in:
parent
6d6d0899c8
commit
ef472f1dc9
2 changed files with 58 additions and 25 deletions
|
@ -374,32 +374,47 @@ impl<T> Rc<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a new `Rc<T>` using a weak reference to itself. Attempting
|
/// Constructs a new `Rc<T>` using a closure `data_fn` that has access to a
|
||||||
/// to upgrade the weak reference before this function returns will result
|
/// weak reference to the constructing `Rc<T>`.
|
||||||
/// in a `None` value. However, the weak reference may be cloned freely and
|
///
|
||||||
/// stored for use at a later time.
|
/// Generally, a structure circularly referencing itself, either directly or
|
||||||
|
/// indirectly, should not hold a strong reference to prevent a memory leak.
|
||||||
|
/// In `data_fn`, initialization of `T` can make use of the weak reference
|
||||||
|
/// by cloning and storing it inside `T` for use at a later time.
|
||||||
|
///
|
||||||
|
/// Since the new `Rc<T>` is not fully-constructed until `Rc<T>::new_cyclic`
|
||||||
|
/// returns, calling [`upgrade`] on the weak reference inside `data_fn` will
|
||||||
|
/// fail and result in a `None` value.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
/// If `data_fn` panics, the panic is propagated to the caller, and the
|
||||||
|
/// temporary [`Weak<T>`] is dropped normally.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(arc_new_cyclic)]
|
|
||||||
/// #![allow(dead_code)]
|
/// #![allow(dead_code)]
|
||||||
/// use std::rc::{Rc, Weak};
|
/// use std::rc::{Rc, Weak};
|
||||||
///
|
///
|
||||||
/// struct Gadget {
|
/// struct Gadget {
|
||||||
/// self_weak: Weak<Self>,
|
/// me: Weak<Gadget>,
|
||||||
/// // ... more fields
|
|
||||||
/// }
|
/// }
|
||||||
|
///
|
||||||
/// impl Gadget {
|
/// impl Gadget {
|
||||||
/// pub fn new() -> Rc<Self> {
|
/// /// Construct a reference counted Gadget.
|
||||||
/// Rc::new_cyclic(|self_weak| {
|
/// fn new() -> Rc<Self> {
|
||||||
/// Gadget { self_weak: self_weak.clone(), /* ... */ }
|
/// Rc::new_cyclic(|me| Gadget { me: me.clone() })
|
||||||
/// })
|
/// }
|
||||||
|
///
|
||||||
|
/// /// Return a reference counted pointer to Self.
|
||||||
|
/// fn me(&self) -> Rc<Self> {
|
||||||
|
/// self.me.upgrade().unwrap()
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
/// [`upgrade`]: Weak::upgrade
|
||||||
#[cfg(not(no_global_oom_handling))]
|
#[cfg(not(no_global_oom_handling))]
|
||||||
#[unstable(feature = "arc_new_cyclic", issue = "75861")]
|
#[stable(feature = "arc_new_cyclic", since = "1.59.0")]
|
||||||
pub fn new_cyclic(data_fn: impl FnOnce(&Weak<T>) -> T) -> Rc<T> {
|
pub fn new_cyclic(data_fn: impl FnOnce(&Weak<T>) -> T) -> Rc<T> {
|
||||||
// Construct the inner in the "uninitialized" state with a single
|
// Construct the inner in the "uninitialized" state with a single
|
||||||
// weak reference.
|
// weak reference.
|
||||||
|
|
|
@ -351,29 +351,47 @@ impl<T> Arc<T> {
|
||||||
unsafe { Self::from_inner(Box::leak(x).into()) }
|
unsafe { Self::from_inner(Box::leak(x).into()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a new `Arc<T>` using a weak reference to itself. Attempting
|
/// Constructs a new `Arc<T>` using a closure `data_fn` that has access to
|
||||||
/// to upgrade the weak reference before this function returns will result
|
/// a weak reference to the constructing `Arc<T>`.
|
||||||
/// in a `None` value. However, the weak reference may be cloned freely and
|
|
||||||
/// stored for use at a later time.
|
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// Generally, a structure circularly referencing itself, either directly or
|
||||||
|
/// indirectly, should not hold a strong reference to prevent a memory leak.
|
||||||
|
/// In `data_fn`, initialization of `T` can make use of the weak reference
|
||||||
|
/// by cloning and storing it inside `T` for use at a later time.
|
||||||
|
///
|
||||||
|
/// Since the new `Arc<T>` is not fully-constructed until
|
||||||
|
/// `Arc<T>::new_cyclic` returns, calling [`upgrade`] on the weak
|
||||||
|
/// reference inside `data_fn` will fail and result in a `None` value.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
/// If `data_fn` panics, the panic is propagated to the caller, and the
|
||||||
|
/// temporary [`Weak<T>`] is dropped normally.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(arc_new_cyclic)]
|
|
||||||
/// #![allow(dead_code)]
|
/// #![allow(dead_code)]
|
||||||
///
|
|
||||||
/// use std::sync::{Arc, Weak};
|
/// use std::sync::{Arc, Weak};
|
||||||
///
|
///
|
||||||
/// struct Foo {
|
/// struct Gadget {
|
||||||
/// me: Weak<Foo>,
|
/// me: Weak<Gadget>,
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// let foo = Arc::new_cyclic(|me| Foo {
|
/// impl Gadget {
|
||||||
/// me: me.clone(),
|
/// /// Construct a reference counted Gadget.
|
||||||
/// });
|
/// fn new() -> Arc<Self> {
|
||||||
|
/// Arc::new_cyclic(|me| Gadget { me: me.clone() })
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// /// Return a reference counted pointer to Self.
|
||||||
|
/// fn me(&self) -> Arc<Self> {
|
||||||
|
/// self.me.upgrade().unwrap()
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
/// [`upgrade`]: Weak::upgrade
|
||||||
#[cfg(not(no_global_oom_handling))]
|
#[cfg(not(no_global_oom_handling))]
|
||||||
#[inline]
|
#[inline]
|
||||||
#[unstable(feature = "arc_new_cyclic", issue = "75861")]
|
#[stable(feature = "arc_new_cyclic", since = "1.59.0")]
|
||||||
pub fn new_cyclic(data_fn: impl FnOnce(&Weak<T>) -> T) -> Arc<T> {
|
pub fn new_cyclic(data_fn: impl FnOnce(&Weak<T>) -> T) -> Arc<T> {
|
||||||
// Construct the inner in the "uninitialized" state with a single
|
// Construct the inner in the "uninitialized" state with a single
|
||||||
// weak reference.
|
// weak reference.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue