Rust project goals: Immobile types and guaranteed destructors
Rust maintainers are exploring new type-level traits like `!Move` and `!Forget` to support immovable types and guaranteed destructors, aiming to fix long-standing issues around async, self-referential structures, and memory leaks. Commenters highlight how this could enable safer structured concurrency (e.g., scoped async tasks with guaranteed cleanup) and more expressive APIs such as linear “must-use” resources, while also noting serious backward-compatibility challenges with existing traits, collections, and the `Pin` model. There is broad enthusiasm for the capabilities these features could unlock, tempered by recognition that the design is complex, not yet finalized, and may force trade-offs with alternative proposals like “pin ergonomics.”
High-level idea
- Proposal introduces traits like
!Move,!Forget, and eventually!Destructto:- Make immovability a property of the type instead of the place (replacing much of
Pin). - Guarantee that destructors will run (or that leaking is impossible) for certain types.
- Lay groundwork for linear / must-move types.
- Make immovability a property of the type instead of the place (replacing much of
Async Rust & structured concurrency
- Major motivation is better async/structured concurrency:
- Today, async tasks can be cancelled arbitrarily, so destructors may never run.
- This blocks fully safe “scoped tasks” analogous to scoped threads.
- With
!Forget, task handles could be guaranteed to be dropped, making scoped async safe and ergonomic.
- Also helps:
- Recursive async functions (no hacks with
Box::pin). - Async functions borrowing from outer scopes instead of cloning.
- Recursive async functions (no hacks with
Immovable types vs Pin
Pinis widely seen as confusing and a “hack”:- It pins places and has tricky
Unpinsemantics and projection rules. - Low-level async code using
Pinis unergonomic and relies onunsafe.
- It pins places and has tricky
!Movewould make immobility intrinsic to the type:- Enables safe self-references and complex patterns that
Pincannot fully support.
- Enables safe self-references and complex patterns that
- There is an alternative “pinned places”/pin ergonomics path; this proposal is explicitly an alternative and aims to deprecate
Pinlong-term.
Leak control and !Forget
!Forgetaims to ensure a destructor runs before storage is reused.- Leaks via
mem::forgetor ref cycles:- Proposed to be constrained by requiring
T: ForgetforRc/Arcand similar types. - Infinite loops or sending values to other threads are not considered “forgetting,” as the scope never ends.
- Proposed to be constrained by requiring
Linear / must-move types (!Destruct)
- Would force explicit destruction paths:
- APIs like transactions could statically require exactly one of
commit/rollback. - “Silent rollback” or panic-in-
Droppatterns could be avoided.
- APIs like transactions could statically require exactly one of
- Destruction would typically require destructuring or dedicated consuming functions in the defining module.
Backwards compatibility and std impacts
- Backcompat is a major risk:
- Existing generics implicitly assume everything is movable and droppable.
- Traits like
Iterator::ItemandDeref::Targetbecome problematic when some types are!Move. - Collections like
Vec<T>inherently move elements; likely they cannot support!Movetypes, or only via restricted APIs.
- Editions help but cannot solve everything; careful design of defaults and bounds (
T: MovevsT: ?Move) is crucial and nontrivial.
Relation to algebraic effects and C++
- Some see these traits as effect-like:
drop<T>,move<T>,forget<T>behave like implicit effects attached to functions. - Others argue it’s mainly about type properties and potential future effect systems.
- Comparisons to C++:
- Rust is not adding implicit move/copy constructors.
- Immovability and guaranteed destructors make interop with C++ and certain patterns (self-references, complex object graphs) easier, but with stricter, explicit semantics.
Status and uncertainty
- This is a project goal, not an accepted language change.
- It competes with the pin-ergonomics goal; many expect immovable types to win if only one survives, but:
- The change is pervasive and complex.
- Semantics, backcompat, and std integration remain open and could still derail or significantly reshape the design.