Description
I believe that the semantics of let _ = foo()
should be that the destructor for the value returned by foo()
runs at the end of the block. The reason for this is a consequence of a couple of other rules that I worked out as part of the temporary lifetime stuff.
In general, let <pat> = <rvalue>
where <pat>
is not a single identifier is equivalent to:
let _tmp = <rvalue>;
let <path> = _tmp;
In this case, that means that let _ = <rvalue>
should be:
let _tmp = <rvalue>;
let _ = tmp;
and since the _
pattern just ignores the thing it matches against, this means that _tmp
is unaffected and drops at the end of the block.
However, the following test case suggests that this is not what we do today:
struct Foo;
impl Drop for Foo {
fn drop(&mut self) {
println!("Hi2!");
}
}
fn main() {
let _ = Foo;
println!("Hi1!");
}
This should print Hi1
and then Hi2
but in fact it prints the opposite. This is probably a hold-over from the special code that was in trans to special case the treatment of let _
vs other patterns, but I could be wrong.