Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is a temporary destructed?

Tags:

rust

Up until now, I assumed that a temporary was destructed at the end of the evaluation of the statement that had spawned it.

However, it appears that there is an exception made when using a temporary to initialize the field of a struct.

PeterHall helpfully provided a simple code sample illustrating the difference in a comment to his answer, which I've simplified complicated a bit:

struct Wrapper<'a> {
    cmd: &'a Cmd<'a>,
}

struct Cmd<'a> {
    args: &'a Option<String>,
}

impl <'a> Cmd<'a> {
    fn new(args: &'a Option<String>) -> Cmd<'a> {
        Cmd {
            args: args,
        }
    }
}

pub fn main() {
    // OK
    let cmd = Cmd {
        args: &None,
    };

    // OK
    let cmd = Wrapper {
        cmd: &Cmd {
            args: &None,
        }
    };

    // Lifetime error
    let cmd = Some(Cmd {
        args: &None,
    });

    // Lifetime error
    let cmd = Cmd::new(&None);
}

So, what is the exact rule for when a temporary is destructed?

like image 719
Matthieu M. Avatar asked Jun 26 '17 13:06

Matthieu M.


1 Answers

Let's look at the second failing line first:

let cmd = Cmd::new(&None);

&None creates a temporary with a lifetime of the single line. Cmd::new returns a Cmd that has the same lifetime. Then we have attempt to store that temporary in a variable with let.

The Rust reference states:

When a temporary rvalue is being created that is assigned into a let declaration, however, the temporary is created with the lifetime of the enclosing block instead...

It tries to increase the lifetime of the Cmd temporary, but that depends on the lifetime of the &None temporary, and since that temporary isn't actually stored in a let (the exception to the rule about temporaries lasting until the end of the statement), its lifetime is less than the lifetime of cmd and you get a lifetime error.

The direct struct statements work, because the let lifetime applies to the struct and its members.

The fact that it doesn't work for Some (an enum) seems like a bug to me (or at least a missing feature).

like image 175
Thayne Avatar answered Nov 07 '22 18:11

Thayne