@@ -329,9 +329,10 @@ impl<T> Rc<T> {
329
329
/// to upgrade the weak reference before this function returns will result
330
330
/// in a `None` value. However, the weak reference may be cloned freely and
331
331
/// stored for use at a later time.
332
- #[ inline]
333
332
#[ unstable( feature = "arc_new_cyclic" , issue = "75861" ) ]
334
333
pub fn new_cyclic ( data_fn : impl FnOnce ( & Weak < T > ) -> T ) -> Rc < T > {
334
+ // Construct the inner in the "uninitialized" state with a single
335
+ // weak reference.
335
336
let uninit_ptr: NonNull < _ > = Box :: leak ( box RcBox {
336
337
strong : Cell :: new ( 0 ) ,
337
338
weak : Cell :: new ( 1 ) ,
@@ -343,6 +344,12 @@ impl<T> Rc<T> {
343
344
344
345
let weak = Weak { ptr : init_ptr } ;
345
346
347
+ // It's important we don't give up ownership of the weak pointer, or
348
+ // else the memory might be freed by the time `data_fn` returns. If
349
+ // we really wanted to pass ownership, we could create an additional
350
+ // weak pointer for ourselves, but this would result in additional
351
+ // updates to the weak reference count which might not be necessary
352
+ // otherwise.
346
353
let data = data_fn ( & weak) ;
347
354
348
355
unsafe {
@@ -355,6 +362,9 @@ impl<T> Rc<T> {
355
362
}
356
363
357
364
let strong = Rc :: from_inner ( init_ptr) ;
365
+
366
+ // Strong references should collectively own a shared weak reference,
367
+ // so don't run the destructor for our old weak reference.
358
368
mem:: forget ( weak) ;
359
369
strong
360
370
}
0 commit comments