Description
... as documented.
The problem: this line from the documentation:
It is allowed for the strong count to be 0 at the time of calling this, but the weak count must be non-zero or the pointer must have originated from a dangling
Weak<T>
(one created bynew
).
The weak count as reported by Weak::weak_count
is 0 when the strong count is 0, even if there are still outstanding weak references:
pub fn weak_count(&self) -> usize
Gets the number of Weak pointers pointing to this allocation.
If no strong pointers remain, this will return zero.
The combination of these two means that getting a pointer from Weak::into_raw
is not enough to guarantee that it's safe to use in Weak::from_raw
. Instead, you have to know that (if it originated from a strong reference) you still have an outstanding strong reference to the allocation, because otherwise the (exposed) weak count is 0, and thus calling from_raw
is "documented UB".
To properly document when this is intuitively allowed (i.e. it's allowed because I got the pointer from into_raw
and have called into_raw
more than from_raw
, so there are still "unowned" raw weak references to claim) (which lines up with what the implementation allows), we need to expose (probably docs only) the fact that there is still being a weak reference count behind the hood being tracked until all of the Weak
s have been dropped.
This will probably also require guaranteeing that Weak
doesn't drop its weak reference and become dangling "early" (e.g. note that upgrade
failed, decrement the (real) weak count (potentially deallocating the place), and become a dangling weak via internal mutability) and that Weak::clone
on a "zombie" Weak
increments the (real) weak count and creates a new "zombie" Weak
, not a dangling Weak
.