I am aware of a similar question that was once asked, but I am still rather perplexed after reading the accepted answer (to be clear, I do not see why the compiler does not have a special case for Drop::drop, as mentioned in the comments, since it already disallows moving out of an object that implements Drop). So let me please try to reiterate on this.
Suppose we have a struct Foo that owns some resources; say, a thread that has to be joined when the object goes out of scope (this situation can happen if we are writing an asynchronous runtime):
struct Foo {
    t: JoinHandle<()>,
}
Since std::ops::Drop::drop takes &mut self, with this definition we cannot really hope to join this thread in drop, because JoinHandle::join takes self by value. Therefore, we have to resort to making this field optional:
struct Foo {
    t: Option<JoinHandle<()>>,
}
And then we can go with if let Some(t) = self.t.take() { t.join(); }. But there still seem to be some unanswered questions here:
Is the
dropsignature hinting us that thedropmethod may get called several times on some objects, or thatdropmay not be the last method that is called on an object during its lifetime? If yes, in which scenarios can this happen? Is it correct to writeself.t.unwrap()in the example above?How to achieve similar semantics without introducing the overhead of
Option(which may not in all cases get covered by niche optimisation and is anyway rather verbose)?