Rust project goals: Immobile types and guaranteed destructors
Overview
The Rust project goals propose introducing Move and Forget auto‑traits that let types opt out of being relocated in memory and being forgotten via mem::forget, thereby enabling immobile types and guaranteed destructors.
Motivation
Rust currently assumes every type can be moved and forgotten, which blocks self‑referential types and prevents guarantees that destructors run; immobile types need a stable address for their whole lifetime and guaranteed destructors prevent mem::forget leaks that would leave resources uncleaned.
Proposal
New unsafe auto‑traits Move, Destruct, and Forget encode capabilities as type properties, with !Move for immovability and !Forget for guaranteed destructors.
Move trait
The Move trait marks types that can be relocated in memory; !Move types cannot be moved and must keep a stable address for their entire existence, making immovability a type property rather than a place property like Pin.
Forget trait
The Forget trait marks types that can be forgotten via mem::forget without running their destructor; !Forget types cannot be forgotten, ensuring their destructor runs and enabling patterns such as safe scoped spawn where a handle’s destructor joins a task.
Work items
Over the next year the team will:
- Implement compiler support for the Move trait (@lcnr and @nia-e).
- Write the Move RFC (@yoshuawuyts).
- Test Move in the Linux kernel (@BennoLossin).
- Test interactions between Iterator and !Move (@yoshuawsh? actually @yoshuawuyts).
- Explore design options for guaranteed destructors (@nikomatsakis).
Relation to other work
This effort follows the same pattern as the Sized hierarchy work, which relaxed the assumption that all types have compile‑time‑known size to support scalable vectors; here the assumptions “all types can be moved” and “all types can be forgotten” are relaxed. It is presented as an alternative to the Pin ergonomics initiative, aiming to eventually deprecate Pin by making immovability a type property instead of a place property.
Frequently asked questions
- How does this relate to the Sized hierarchy work? Both introduce trait hierarchies that let types opt out of previously universal assumptions; Sized relaxed compile‑time‑known size, while Move/Forget relax movability and forgettability.
- How does this relate to the Pin ergonomics initiative? The Pin ergonomics effort adds language‑level pin places and a special Drop overload; this project instead treats immovability as a type property, avoiding the need for Pin and its duplicate‑definition problems.
- What enables safe scoped spawn? A handle whose type implements !Forget cannot be mem::forgot, so its destructor is guaranteed to run and can join the spawned task, preventing the task from outliving the scope.
- Where can I read more about this design space? The goal links to several blog posts covering Move, Destruct, Leak, must‑move types, ergonomic self‑referential types, problems with Pin, and placing functions for !Move construction.
Community reaction
Commenters expressed enthusiasm for filling a long‑standing gap in the language:
"Great new! Since 2016 or so it became apparent that immovable types were a crucial missing part of Rust, but for a long time it was believed it wouldn't be possible to add them without breaking everything, which is why we ended up with the Pin hack. I'm very glad they found a way to add it eventually, as it's really filling a glaring hole in the language." — @stymaar
Some noted alternative approaches and questioned the direction:
"There's a different proposal by @withoutboats to make immovability a property of the place/reference instead of the type: https://without.boats/blog/pinned-places/ Does this project goal mean that the rust maintainers have decided to implement @yoshuawuyts' immovable types proposal in favor of pinned places?" — @yccs27
Concerns about backward compatibility and interaction with leaks were raised:
"Wouldn't this be fairly substantially backwards incompatible?" — @jerf "mem::forget isn’t the only way you can safely leak a value, you can do it with reference cycles too, right? And there is no way for the compiler to detect that? Isn’t that why mem::forget is safe, because you can always implement it yourself safely? How do you get around that?" — @OskarS
The connection to C++ models and linear types was highlighted:
"Ok, I guess somebody has to provide the youngsters/uninitiated with some context. What is going on here can be viewed as part of a process of Rust (potentially) incrementally adopting the C++ model, because the Rust model is limited in important ways. Specifically, Rust's "necessarily-trivial-destructive" moves make it possible for a memory location previously holding a valid object to become invalid without a destructor (or any other handler) being called." — @safercplusplus "Although not part of the goal, it also mentions
!Destruct/"must-move types", aka linear types: Instead of there always being a way to drop values without providing any arguments, if you wanna get rid of a value of a linear type you have to call a function that takes it by value." — @skitter
Enthusiasm about eventually removing Pin appeared:
"Intresting. Immovability becomes a property of the type (!Move) rather than the place (Pin), and the goal is to eventually deprecate Pin outright rather than paper over it with pin ergonomics. !Forge is what finally unblocks safe scoped spawn: handle that can't be mem::forgeten has a destructor that's guaranteed to run." — @_alphageek
Questions about useful patterns for newcomers and about other language features were also present or‑panic were noted:
"Could someone explain this to me as someone who's never touched async Rust? What kind of useful patterns would this allow for?" — @suddenlybananas "Does anyone know if there is any plan for no-panic to be a language feature? I think there was some discussion about this regarding Rust in the Linux kernel or embedded Rust but I don't know if there is any consensus or any plan regarding this." — @dorjoy "Guaranteed destructors is probably the most complex features ever added to C++, more than templates or move semantics." — @groundzeros2015
Overall, the feedback signals strong interest in the proposed traits while acknowledging design challenges and the need for careful evolution of the language.