I’ve thought about this more, and have a new idea to achieve the same ends, while possibly addressing some of the raised objections:
Define two drop traits (tentatively called DropMain
and DropExc
). DropMain
defines the function to be called in normal-path drop, DropExc
defines the function to be called in exceptional-path drop. Define blanket impls against DropMain
and DropExc
for Drop
-types. Pre-linear-types, have a compiler lint that will complain if only one of DropMain
or DropExc
are defined for a type; post-linear-types, the lint will allow DropExc
to be defined without DropMain
if the type is linear.
Rationale is that, if we agree that exceptional-case drop can have different requirements than scope-based drop, then the existing Drop
API represents two concerns, instead of one. The underlying concerns should be separated, and in the (common) case that we don’t actually care about why the resources need to be cleaned up, then we use the blanket-impl mechanism to deliberately obscure which cleanup-path is being used.
The APIs for DropMain
and DropExc
probably want to take @eddyb’s Interior<Self>
, instead of &mut self
, or otherwise use a better self
argument (allowing partial moves out), in which case the revised proposal would also block on solving the move-from-self-during-drop problem… Which is a larger-scale problem than I was hoping to address immediately, but sometimes things go like that.