Live data from Hacker News

Rust project goals: Immobile types and guaranteed destructors

github.com

21–30 of 112 posts

Re: Rust project goals: Immobile types and guaranteed destructors

#21
post #14
post #11

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?

> # How does this relate to the "pin ergonomics" initiative? > This work is an alternative to Project Goal 2025H2: Continue Experimentation with Pin Ergonomics, which includes the following extensions: > A new item family pin in lvalues, e.g. &pin x, &pin mut x, &pin const x. > A one-off overload of Rust's Drop trait, e.g. fn drop(&pin mut self). > A new item kind pin in patterns, e.g. &pin . > Notably, this work doe…

Ah, thanks, I didn't realize "pin ergonomics" was the Rust Project name for @withoutboats' pinned places.

Re: Rust project goals: Immobile types and guaranteed destructors

#22

Could someone explain this to me as someone who's never touched async Rust? What kind of useful patterns would this allow for?

Things you'd expect to work already.

It doesn't really add anything new and flashy, but removes some annoying warts.

Sync code has scoped threads that enable multi-threaded execution within a function, without having to ensure the data outlives the function call. Async can't do that while guaranteeing safety. This makes tokio::spawn awkward and annoying, and is a major source why people dislike Rust's async.

Low-level async code that polls Futures requires using the Pin wrapper type, which is unergonomic, and doesn't really guarantee safety, but it's more like a "be careful here" sign. Proposed changes would make that code look more like normal Rust and work without unsafe escape hatches.

Re: Rust project goals: Immobile types and guaranteed destructors

#23
post #20

Earlier quoted context omitted.

For context, the reason this would be really nice is that it would enable API designs that catch certain kinds of errors. let txn = create_transaction(); // do something with the transaction txn.commit(); // consume the txn Right now, you can't implement this API without choosing between either silently rolling back unless the user calls `commit()`, or panicking in the Drop impl for the transaction if the user didn't…

> If instead the transaction is a must-move type, you would get a compiler error if you fail to call exactly one of either commit or rollback Can you elaborate how it may work? I mean if I create a function: fn fail_silently(txn: Transaction) {} then the calling code would pass the compiler, but this function presumably isn't, ok. But what can make these functions to pass: impl Transaction { pub fn commit(self) { ...…

Exactly - fail_silently is illegal and you have to actually destructure the type to explicitly implement the destructor

> How would you handle destructors with arguments?

https://smallcultfollowing.com/babysteps/blog/2025/10/21/mov...

Re: Rust project goals: Immobile types and guaranteed destructors

#24
post #20

Earlier quoted context omitted.

For context, the reason this would be really nice is that it would enable API designs that catch certain kinds of errors. let txn = create_transaction(); // do something with the transaction txn.commit(); // consume the txn Right now, you can't implement this API without choosing between either silently rolling back unless the user calls `commit()`, or panicking in the Drop impl for the transaction if the user didn't…

> If instead the transaction is a must-move type, you would get a compiler error if you fail to call exactly one of either commit or rollback Can you elaborate how it may work? I mean if I create a function: fn fail_silently(txn: Transaction) {} then the calling code would pass the compiler, but this function presumably isn't, ok. But what can make these functions to pass: impl Transaction { pub fn commit(self) { ...…

Yes, destructuring is typically the only allowed way to get rid of linear/indestructible values. If the type has private fields, this is only possible in the same module, so commit(txn) and rollback(txn) would have to be implemented in the same module as the Transaction type.

Re: Rust project goals: Immobile types and guaranteed destructors

#25

Earlier quoted context omitted.

Linear types requires significant work to incorporate into the core built-in collections and types. I've been following the work on Mojo to enable Linear type support for built-in types and collections, I don't think Rust's language semantics will allow for the same level of integration (Rust is already stable).

But Rust has editions. That is a big lever language designers can use if they painted themselves into a corner.

Yes, editions are a great mechanism. It still has its limits, especially if you want easy edition migrations. All existing Rust code assumes it can drop any type whenever it wants, and that is not something you can just change across editions. You have to be very careful with defaults if you don't want conflicts when crossing edition boundaries.

Re: Rust project goals: Immobile types and guaranteed destructors

#26

More algebraic effects being retrofitted onto Rust.

How so? This feel distinct from the "algebraic effects"-like features like constness, async, can-panic, can-unwind, etc., since this is a property of the types themselves rather than of functions.

Re: Rust project goals: Immobile types and guaranteed destructors

#27
post #9

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.

Linear types requires significant work to incorporate into the core built-in collections and types. I've been following the work on Mojo to enable Linear type support for built-in types and collections, I don't think Rust's language semantics will allow for the same level of integration (Rust is already stable).

Which stdlib collections and types should become `!Move`?

Re: Rust project goals: Immobile types and guaranteed destructors

#28
post #19
post #16

Earlier quoted context omitted.

> I'm very glad they found a way to add it eventually Will this integrate with existing code that uses Pin ? If not this will split the ecosystem even further...

I don't see why it may fail to integrate. Declare Pin as !Move and... thats all? I mean, there will be issues, edge-cases because it is just how these things happen, but still I don't see any fundamental issues with continuing to use Pin.

Pin applies to the pointer, !Move applies to the pointee.

Re: Rust project goals: Immobile types and guaranteed destructors

#30
post #19

Earlier quoted context omitted.

I don't see why it may fail to integrate. Declare Pin as !Move and... thats all? I mean, there will be issues, edge-cases because it is just how these things happen, but still I don't see any fundamental issues with continuing to use Pin.

Pin applies to the point er , !Move applies to the point ee .

So... Pin should be defined as Pin?
Post reply on HN