-
Notifications
You must be signed in to change notification settings - Fork 13.9k
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) -> usizeGets 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 Weaks 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.