diff options
| author | bdbai <bdbaiapp@163.com> | 2021-12-13 21:41:21 +0800 |
|---|---|---|
| committer | bdbai <bdbaiapp@163.com> | 2021-12-13 21:41:21 +0800 |
| commit | ef472f1dc93ee4c953e296e7316ead7f3de4c09f (patch) | |
| tree | 1c72896cb0a5926edfd9caf57fa5372af186abd1 /library/alloc/src | |
| parent | 6d6d0899c8bf9d321ffa12426ca7ae7e3e15478a (diff) | |
| download | rust-ef472f1dc93ee4c953e296e7316ead7f3de4c09f.tar.gz rust-ef472f1dc93ee4c953e296e7316ead7f3de4c09f.zip | |
Stabilize arc_new_cyclic
Diffstat (limited to 'library/alloc/src')
| -rw-r--r-- | library/alloc/src/rc.rs | 39 | ||||
| -rw-r--r-- | library/alloc/src/sync.rs | 44 |
2 files changed, 58 insertions, 25 deletions
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 33bee4324fd..b92fbac36d9 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -374,32 +374,47 @@ impl<T> Rc<T> { } } - /// Constructs a new `Rc<T>` using a weak reference to itself. Attempting - /// to upgrade the weak reference before this function returns will result - /// in a `None` value. However, the weak reference may be cloned freely and - /// stored for use at a later time. + /// Constructs a new `Rc<T>` using a closure `data_fn` that has access to a + /// weak reference to the constructing `Rc<T>`. + /// + /// 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 /// /// ``` - /// #![feature(arc_new_cyclic)] /// #![allow(dead_code)] /// use std::rc::{Rc, Weak}; /// /// struct Gadget { - /// self_weak: Weak<Self>, - /// // ... more fields + /// me: Weak<Gadget>, /// } + /// /// impl Gadget { - /// pub fn new() -> Rc<Self> { - /// Rc::new_cyclic(|self_weak| { - /// Gadget { self_weak: self_weak.clone(), /* ... */ } - /// }) + /// /// Construct a reference counted Gadget. + /// fn new() -> Rc<Self> { + /// 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))] - #[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> { // Construct the inner in the "uninitialized" state with a single // weak reference. diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 7c065f37d1f..4deec0146e4 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -351,29 +351,47 @@ impl<T> Arc<T> { unsafe { Self::from_inner(Box::leak(x).into()) } } - /// Constructs a new `Arc<T>` using a weak reference to itself. Attempting - /// to upgrade the weak reference before this function returns will result - /// in a `None` value. However, the weak reference may be cloned freely and - /// stored for use at a later time. + /// Constructs a new `Arc<T>` using a closure `data_fn` that has access to + /// a weak reference to the constructing `Arc<T>`. /// - /// # 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)] - /// /// use std::sync::{Arc, Weak}; /// - /// struct Foo { - /// me: Weak<Foo>, + /// struct Gadget { + /// me: Weak<Gadget>, /// } /// - /// let foo = Arc::new_cyclic(|me| Foo { - /// me: me.clone(), - /// }); + /// impl Gadget { + /// /// 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))] #[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> { // Construct the inner in the "uninitialized" state with a single // weak reference. |
