Skip to content

Commit 3f07303

Browse files
authored
Rollup merge of #95843 - GuillaumeGomez:improve-new-cyclic-doc, r=m-ou-se
Improve Rc::new_cyclic and Arc::new_cyclic documentation Fixes #95672. cc `@CAD97` (since I used your explanations)
2 parents 4780141 + 67d1e7b commit 3f07303

File tree

2 files changed

+41
-16
lines changed

2 files changed

+41
-16
lines changed

library/alloc/src/rc.rs

+19-7
Original file line numberDiff line numberDiff line change
@@ -374,19 +374,26 @@ impl<T> Rc<T> {
374374
}
375375
}
376376

377-
/// Constructs a new `Rc<T>` using a closure `data_fn` that has access to a
378-
/// weak reference to the constructing `Rc<T>`.
377+
/// Constructs a new `Rc<T>` while giving you a `Weak<T>` to the allocation,
378+
/// to allow you to construct a `T` which holds a weak pointer to itself.
379379
///
380380
/// Generally, a structure circularly referencing itself, either directly or
381-
/// indirectly, should not hold a strong reference to prevent a memory leak.
382-
/// In `data_fn`, initialization of `T` can make use of the weak reference
383-
/// by cloning and storing it inside `T` for use at a later time.
381+
/// indirectly, should not hold a strong reference to itself to prevent a memory leak.
382+
/// Using this function, you get access to the weak pointer during the
383+
/// initialization of `T`, before the `Rc<T>` is created, such that you can
384+
/// clone and store it inside the `T`.
385+
///
386+
/// `new_cyclic` first allocates the managed allocation for the `Rc<T>`,
387+
/// then calls your closure, giving it a `Weak<T>` to this allocation,
388+
/// and only afterwards completes the construction of the `Rc<T>` by placing
389+
/// the `T` returned from your closure into the allocation.
384390
///
385391
/// Since the new `Rc<T>` is not fully-constructed until `Rc<T>::new_cyclic`
386-
/// returns, calling [`upgrade`] on the weak reference inside `data_fn` will
392+
/// returns, calling [`upgrade`] on the weak reference inside your closure will
387393
/// fail and result in a `None` value.
388394
///
389395
/// # Panics
396+
///
390397
/// If `data_fn` panics, the panic is propagated to the caller, and the
391398
/// temporary [`Weak<T>`] is dropped normally.
392399
///
@@ -403,7 +410,12 @@ impl<T> Rc<T> {
403410
/// impl Gadget {
404411
/// /// Construct a reference counted Gadget.
405412
/// fn new() -> Rc<Self> {
406-
/// Rc::new_cyclic(|me| Gadget { me: me.clone() })
413+
/// // `me` is a `Weak<Gadget>` pointing at the new allocation of the
414+
/// // `Rc` we're constructing.
415+
/// Rc::new_cyclic(|me| {
416+
/// // Create the actual struct here.
417+
/// Gadget { me: me.clone() }
418+
/// })
407419
/// }
408420
///
409421
/// /// Return a reference counted pointer to Self.

library/alloc/src/sync.rs

+22-9
Original file line numberDiff line numberDiff line change
@@ -351,23 +351,31 @@ impl<T> Arc<T> {
351351
unsafe { Self::from_inner(Box::leak(x).into()) }
352352
}
353353

354-
/// Constructs a new `Arc<T>` using a closure `data_fn` that has access to
355-
/// a weak reference to the constructing `Arc<T>`.
354+
/// Constructs a new `Arc<T>` while giving you a `Weak<T>` to the allocation,
355+
/// to allow you to construct a `T` which holds a weak pointer to itself.
356356
///
357357
/// Generally, a structure circularly referencing itself, either directly or
358-
/// indirectly, should not hold a strong reference to prevent a memory leak.
359-
/// In `data_fn`, initialization of `T` can make use of the weak reference
360-
/// by cloning and storing it inside `T` for use at a later time.
358+
/// indirectly, should not hold a strong reference to itself to prevent a memory leak.
359+
/// Using this function, you get access to the weak pointer during the
360+
/// initialization of `T`, before the `Arc<T>` is created, such that you can
361+
/// clone and store it inside the `T`.
361362
///
362-
/// Since the new `Arc<T>` is not fully-constructed until
363-
/// `Arc<T>::new_cyclic` returns, calling [`upgrade`] on the weak
364-
/// reference inside `data_fn` will fail and result in a `None` value.
363+
/// `new_cyclic` first allocates the managed allocation for the `Arc<T>`,
364+
/// then calls your closure, giving it a `Weak<T>` to this allocation,
365+
/// and only afterwards completes the construction of the `Arc<T>` by placing
366+
/// the `T` returned from your closure into the allocation.
367+
///
368+
/// Since the new `Arc<T>` is not fully-constructed until `Arc<T>::new_cyclic`
369+
/// returns, calling [`upgrade`] on the weak reference inside your closure will
370+
/// fail and result in a `None` value.
365371
///
366372
/// # Panics
373+
///
367374
/// If `data_fn` panics, the panic is propagated to the caller, and the
368375
/// temporary [`Weak<T>`] is dropped normally.
369376
///
370377
/// # Example
378+
///
371379
/// ```
372380
/// # #![allow(dead_code)]
373381
/// use std::sync::{Arc, Weak};
@@ -379,7 +387,12 @@ impl<T> Arc<T> {
379387
/// impl Gadget {
380388
/// /// Construct a reference counted Gadget.
381389
/// fn new() -> Arc<Self> {
382-
/// Arc::new_cyclic(|me| Gadget { me: me.clone() })
390+
/// // `me` is a `Weak<Gadget>` pointing at the new allocation of the
391+
/// // `Arc` we're constructing.
392+
/// Arc::new_cyclic(|me| {
393+
/// // Create the actual struct here.
394+
/// Gadget { me: me.clone() }
395+
/// })
383396
/// }
384397
///
385398
/// /// Return a reference counted pointer to Self.

0 commit comments

Comments
 (0)