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?