Skip to content

Weak::from_raw is practically unusable #73840

Closed
@CAD97

Description

@CAD97

... 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 by new).

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 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions