So I know that the _
pattern (in)famously does not bind. As explained in this helpful comment, that means that let _ = x();
is equivalent to x();
. We can see this in action:
#[derive(Debug)]
struct Foo;
impl Drop for Foo {
fn drop(&mut self) {
println!("Dropped!");
}
}
fn main() {
let _ = Foo; // prints "Dropped!"
println!("Was it dropped yet?");
Foo; // prints "Dropped!"
println!("Was it dropped yet?");
}
If instead I bind Foo
to a variable, I see that it gets dropped at the end of the scope which is expected:
fn main() {
let foo = Foo;
let _ = foo; // doesn't print "Dropped!"
println!("Still in scope: {foo:?}");
// prints "Dropped!"
}
By the "let _ = x();
is equivalent to x();
" rule I expect the following code to behave the same but instead I get a compilation error:
fn main() {
let foo = Foo;
foo; // shouldn't print "Dropped!" // đ value moved here
println!("Still in scope: {foo:?}"); // đ value borrowed here after move
// should print "Dropped!"
}
It looks like let _ = foo;
isn't just not binding to _
, it's also not even moving foo
into the let
statement (so it's still alive afterward). But it seems like foo;
is moving foo
in and subsequently dropping it. Why is it that let _ = foo;
doesn't move foo
into the statement but foo;
does?