I’m looking at Arc::make_mut
, in particular its documentation:
Makes a mutable reference into the given
Arc
.If there are other
Arc
orWeak
pointers to the same allocation, thenmake_mut
will create a new allocation and invokeclone
on the inner value to ensure unique ownership. This is also referred to as clone-on-write.Note that this differs from the behavior of
Rc::make_mut
which disassociates any remainingWeak
pointers.See also
get_mut
, which will fail rather than cloning.
The claim about “this differs from the behavior of Rc::make_mut
which disassociates any remaining Weak
pointers” is the part I don’t get. Now, comparing with the docs of Rc::make_mut
Makes a mutable reference into the given
Rc
.If there are other
Rc
pointers to the same allocation, thenmake_mut
willclone
the inner value to a new allocation to ensure unique ownership. This is also referred to as clone-on-write.If there are no other
Rc
pointers to this allocation, thenWeak
pointers to this allocation will be disassociated.See also
get_mut
, which will fail rather than cloning.
That one does mention this “disassociation” of Weak pointers. But now… assuming that “disassociating” a Weak
pointer means making it no longer upgradable, and assuming that “this differs from the behavior of Rc::make_mut
” implies that Arc::make_mut
doesn’t “diassociate” the Weak
pointers, so those are supposed to still be upgradable, how should this work? Certainly, even by modifying the strong Arc<T>
by merely “cloning” the inner value, the remaining Weak
pointers pointing to the old value would immediately be without any strong pointers so they are becoming disassociated (i.e. non-upgradable) after all, right?
Looking further in the docs of Rc::make_mut
… there’s an example that’s supposed to demonstrate the behavior with regards to Weak
pointers:
Weak
pointers will be disassociated:use std::rc::Rc; let mut data = Rc::new(75); let weak = Rc::downgrade(&data); assert!(75 == *data); assert!(75 == *weak.upgrade().unwrap()); *Rc::make_mut(&mut data) += 1; assert!(76 == *data); assert!(weak.upgrade().is_none());
I mean, sure, great thing…, the example actually works, but so does the same example with Arc
instead of Rc
!!
Lastly, looking at the source, it clearly doesn’t do any cloning at all (despite promising so in the docs) in case of only Weak
pointers existing next to the single strong Arc
we have. For good measure, compare with the source code for the Rc
variant. Looks like there’s a strong similarity between the two functions. I fail to see any difference at all regarding Weak
pointers.
In order to keep my sanity here, please anyone be so kind to either point out what I’m missing or that the docs are, in fact, inaccurate (i.e. wrong).