Skip to content

let _ = foo() runs the destructor at the wrong time #16526

Closed
@nikomatsakis

Description

@nikomatsakis

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.

cc @pcwalton @pnkfelix

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions