struct S;
impl Drop for S {
fn drop(&mut self) {
print!("1");
}
}
fn main() {
let s = S;
let _ = s;
print!("2");
}
Basically, the core question here is whether s in let _ = s; is moved or not. It turns out it does, but I can't figure why.
In my understanding, a type either implements Copy and then its instances are not moved when appear on the right side of = or it doesn't implement Copy and its instances ought to be moved.
My first theory of unit structs being Copy by default does not hold since this snipped fails to compile:
In my understanding, a type either implements Copy and then its instances are not moved when appear on the right side of = or it doesn't implement Copy and its instances ought to be moved.
It's confusing, because let _ = S (note: constructor) does destroy it immediately, unlike let _s = S. So it's easy to think of let _ as immediately-destroying construct (which was my assumption too!) rather than some kind of a do-nothing pattern.
Both dropping and moving require owning and no live references to the object, but I don't think destruction strictly speaking counts as a move (e.g. other than packed structs, it doesn't require copying anything. There's drop_in_place which doesn't perform any moves).
// move a to something
let something = a;
// don't do anything (noop)
//
// if a is _rvalue_ (or how Rust calls it?) than it'll be dropped right away
// because there are no other bindings to it and _ doesn't create one
// if a is _lvalue_ (place), _ doesn't do a thing because there are other bindings
// and no extra bindings are created
let _ = a;
So, _ is a very especial place that turns any let into "compute the rval but do not bind" noop, is that right?