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?
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.
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…
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.
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.