Module moveit::drop_flag

source ·
Expand description

Drop flags.

The Pin<P> guarantees state that if we have a T allocated somewhere, and we construct a pinned reference to it such as a Pin<&'a mut T>, then before that “somewhere” in memory is reused by another Rust object, T’s destructor must run.

Normally, this isn’t a problem for Rust code, since the storage of an object is destroyed immediately after it is destroyed. DerefMove, however, breaks this expectation: it separates the destructors from its storage and contents into two separately destroyed objects: a AsMove::Storage and a MoveRef. If the MoveRef is mem::forget’ed, we lose: the storage will potentially be re-used.

Therefore, we must somehow detect that MoveRefs fail to be destroyed when the destructor for the corresponding storage is run, and remediate it, either by leaking heap storage or aborting if we would free stack storage (a panic is insufficient, since that location can be reused if the panic is caught).

A DropFlag allows us to achieve this. It is a generalized, library-level version of the Rust language’s drop flags, which it uses to dynamically determine whether to run destructors of stack-allocated values that might have been moved from. Unlike Rust language drop flags, a DropFlag is actually a counter, rather than a boolean. This allows storage that holds many objects, like a vector, ensure that all contents have been properly destroyed.

This module also provides two helper types simplify safe creation and management of drop flags.

See the Rustonomicon entry for the Rust language equivalent.

Safety

No function in this module is unsafe: instead, functions that construct MoveRefs out of DropFlags are unsafe, and their callers are responsible for ensuring that the passed-in DropFlag helps uphold the relevant invariants.

Structs