The editorial frames these features as prerequisites for fixing long-standing pain: mem::forget being safe means no library can rely on Drop for safety invariants, a 2015 'leakpocalypse' decision that has shaped async, scoped threads, and every intrusive data structure since. Pin is described as a library-level workaround built on a language that fundamentally believes everything is movable, producing one of stdlib's most confusing APIs and a steady stream of soundness patches.
By submitting the Rust project goal document to HN and driving it to 156 points, paavohtl surfaces the position that these two capabilities are worth formalizing at the language level in 2026. The framing treats immobile types and guaranteed destructors as related foundational work rather than niche features.
The editorial argues that letting the compiler reject programs that leak a value without explicitly consuming it would close the loophole where mem::forget, Rc cycles, or panic-in-drop silently skip cleanup. This would let library authors finally rely on Drop to uphold safety invariants — enabling patterns that today require unsafe or elaborate workarounds like pin-project.
The Rust project has published a 2026 goal titled *Immobile types and guaranteed destructors*, laying out design work for two long-requested capabilities: types that cannot be moved after construction, and types whose destructors are guaranteed to run. The document lives in the `rust-lang/rust-project-goals` repo under `src/2026/move-trait.md` and frames the work as foundational — a prerequisite for a cluster of features the language has been dancing around for years.
The two pieces are related but distinct. Immobile types would formalize what `Pin` has been approximating with library machinery since 2018: a value that, once it exists at an address, is guaranteed to stay there. Guaranteed destructors (sometimes called *linear types* or *must-move types*) would let the compiler reject programs that leak a value without explicitly consuming it — closing the loophole where `mem::forget`, `Rc` cycles, or a panic-in-drop can silently skip cleanup.
Together, they'd fix a quiet embarrassment in Rust's story: today, `std::mem::forget` is a safe function, which means no library author can rely on `Drop` actually running to uphold a safety invariant. That was a deliberate 2015 decision (the *leakpocalypse*), and it has shaped the shape of async, scoped threads, and every intrusive data structure in the ecosystem ever since.
If you've written non-trivial async Rust, you've felt the shadow of this problem. `Pin<&mut Self>` exists because self-referential futures can't be moved once they've been polled — the internal pointers would dangle. But `Pin` is a library-level workaround built on top of a language that fundamentally believes everything is movable by default. The result is one of the most confusing APIs in the standard library, a `pin-project` crate that exists purely to paper over ergonomics, and a steady stream of bug reports where soundness holes get patched with more `unsafe`.
Guaranteed destructors would unlock a different category of features. Scoped threads (`std::thread::scope`) currently work only because the API takes a closure — you can't hand someone a `ScopeGuard` and trust they'll drop it, because they might `forget` it and turn a borrowed reference into a dangling one. The same constraint bites `io_uring`-style APIs where a buffer must outlive an in-flight kernel operation, database transactions that must commit or roll back, and any FFI where a foreign resource needs deterministic cleanup. Every one of these has a workaround, and every workaround costs ergonomics.
The design space isn't small. Do you introduce a new `Move` auto-trait that types can opt out of? A `Leak` trait that gates `forget` and `Rc`? A separate `?Move`-style relaxed bound like `?Sized`? The project goal is explicit that it isn't picking a winner yet — it's carving out the space and shipping experimental support so the eventual RFC has real data behind it. Niko Matsakis and the language team have been circling this for years; the goal document acknowledges prior art from Swift's move-only types, C++'s move semantics, and the linear-types work in Haskell.
The community reaction on Hacker News split predictably: async-heavy shops treat this as overdue, embedded developers worry about complexity creep, and the peanut gallery asks whether Rust is turning into C++. The honest answer is that Rust already has this complexity — it's just spread across `Pin`, `PhantomPinned`, `pin-project`, `MaybeUninit`, and a folk understanding that some `Drop` impls are load-bearing. Bringing it into the type system is arguably a *simplification*, in the same way that `?` was simpler than `try!`.
If you're shipping Rust in production today, this doesn't change anything soon — project goals are aspirational, and "2026 goal" means design work in 2026, not stable in 2026. But it's worth watching for two reasons.
First, if you maintain a library that uses `Pin`, the eventual immobile-types feature is likely to give you a cleaner migration path. Expect the `pin-project` maintainers and the async ecosystem to weigh in heavily during the RFC phase; if your library exposes `Pin` in its public API, subscribe to the tracking issue. The transition story matters more than the end state — a beautiful new feature that forces every async crate to break its API in the same release is worse than the status quo.
Second, if you've been avoiding Rust for systems where deterministic cleanup is non-negotiable — databases, kernel-adjacent code, resource-constrained embedded — this is the language moving toward you rather than away. Guaranteed destructors are what would make Rust competitive with C++ RAII in domains where "probably runs" isn't good enough. The `io_uring` crowd in particular has been vocal that current Rust makes safe wrappers nearly impossible without leaking abstractions.
The near-term practical advice is boring: keep writing the workarounds. Use closure-based scoped APIs when you need drop guarantees. Use `pin-project-lite` instead of hand-rolling pin projections. Don't build a public API that assumes `Drop` runs — because today, it doesn't have to.
Rust project goals have a mixed track record — some ship on schedule, some get quietly rolled forward, and a few (const generics, GATs) took the better part of a decade from proposal to stable. Immobile types and guaranteed destructors are in the ambitious bucket: they touch the type system, the standard library, and every async runtime. But the fact that the language team is willing to reopen the 2015 leakpocalypse decision suggests the accumulated pain has finally outweighed the compatibility risk. If it lands, Rust in 2028 will feel meaningfully different to write — less `Pin` boilerplate, safer scoped APIs, and one fewer footgun to explain to newcomers.
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
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' immo
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.
More algebraic effects being retrofitted onto Rust.
Top 10 dev stories every morning at 8am UTC. AI-curated. Retro terminal HTML email.
For everybody who doesn't have the context, just note that this is not an accepted langauge change. It's a just project goal, which means it's accepted as something people will work on, but the design might change significantly or it can even be abandoned completely (which is pretty u