Prompted by discussion in this thread.
There’s probably some problem that I’m missing that makes this not work, but:
Redefine Drop
to be
trait Drop: !Copy {
fn drop(self);
}
(Compatibility with current impls is provided with a magic legacy_drop(&mut self)
.)
The magic of this definition is that you may move out of self
even though Self: Drop
, and that Drop
is not called on self
at the end of scope. (It’s still called on any members that aren’t moved.)
We no longer require the magic that you can’t refer to this fn directly.
Calling any function that takes Self
is handled by the unconditional_recursion
lint. (As it would unconditionally recurse back into Drop::drop
.)
Pre-1.0 issue about by-value drop.
I think this trait definition, modulo supporting current trait impls, is less magic than the current. (Though I accept if changing this definition like this is undesirable or impossible.)
Current Drop:
- Cannot refer to
Drop::drop
directly - Cannot move out of
Drop
types- Semantically moving out of
self
inDrop::drop
requiresunsafe
and wrapping members inmem::ManuallyDrop
- Semantically moving out of
- Calls to drop glue emitted at the end of every block that has types by-value
This Drop:
- Support for two ways of implementing the trait
- Can move out of
Drop
types inDrop::drop
(but not elsewhere) - Drop glue in
Drop::drop
skips coveringself
, other by-value scopes emit full drop glue -
unconditional_recursion
lint has to learn aboutdrop
recursion
(Implementation note: this drop glue behavior can be implemented by handling drop glue for Self
as if it were not Drop
. Rather than the recursion lint, you could also consider Self
to be a distinct type here only, so you cannot recurse (but also cannot mem::forget
).)
The other proposal in the linked topic was to have a Drop
version that required pattern matching self
in the drop
fn declaration. This seems like more magic than this formulation, but would also work.
Both ideas could also be applied to using a new DropMove
type instead, and having magic interop instead of magic translation.