Pre-Pre-RFC: Forget trait


#1

As we’re all probably aware, Drop is an anti-trait. Adding a Drop impl for a type actually removes functionality (rather than adding it) and further restricts where the type can be used. A solution to this that I don’t remember seeing proposed before would be to change the rules around Drop and add another trait which gives the behaviour we want.

The idea is to add another marker trait, let’s call it Forget which indicates that a type can be dropped without running any drop glue. Forget inherits from Drop, so we have Forget: Drop. What’s more, all types now implement Drop.

The relationship between Drop and Forget mirrors that between Clone and Copy. Clone indicates that a type can be copied. Copy indicates that a type can be copied trivially, without running any extra code. Likewise, Drop indicates that a type can be dropped. Forget indicates that a type can be dropped trivially, without running any extra code.

All the restrictions that current apply to types that implement Drop, now instead apply to types that don’t implement Forget.

Making this backwards-compatible would be a bit messy, but maybe not undoable. If a type doesn’t give an explicit impl for Drop then the default impl is derived, as is an impl for Forget so long as all of the type’s fields implement Forget. If a type does give an impl for Drop, then the Forget impl isn’t derived.

In the future we could add a way to opt-out of implementing Drop in order to support truly linear types.

So, would something like this be possible? Or is there a deal-breaker here I’m not seeing?


#2

That formulation doesn’t work 100%. Correct would be

If a type doesn’t give an explicit impl for Drop and all fields implement Forget, the type implements Forget.


#3

Ah yes, that’s the meaning I intended


#4

Could you explain the motivation in more detail? Just from your first paragraph I have absolutely no idea why Drop’s current behavior is a problem and what sort of code a Forget trait would enable.


#5

I keep linking this old reddit comment: https://www.reddit.com/r/rust/comments/4l4wjl/a_report_on_regions_and_linear_types/d3lygjn/

(your Forget is my DropIsForget - of course, that’s an extremely provisional name)


#6

I describe this proposal, its motivation, and its problems more in detail here: https://gankro.github.io/blah/linear-rust/

(this is specifically the “trait” section)

I stand by my analysis in the post: linear types really aren’t worth it. And certainly, making a move to introduce this distinction isn’t worth it without an actual proposal to introduce linear types.

The compiler team already has a good backlog of like three years of stuff to implement…


#7

Ah, I’m not surprised to see that ideas like this have come up before.

For example you can’t implement Drop for a static value. You also can’t implement both Copy and Drop for a type. With the Forget trait you could require that all statics implement Forget and also have Copy: Forget.

Well yeah, there’s that.


#8

I believe https://github.com/rust-lang/rfcs/pull/1440 allows static Drop types.

I don’t recall any RFCs for allowing Copy and Drop types, though it’s also not clear to me why we need a Forget trait to change that.


#9

This pre-pre-rfc isn’t proposing linear types. It’s basically asking for the ability to use specialization to pick different code for types that have no drop glue.