'Why does a reference to a temporary struct (`&Foo { … }`) live long enough, but a reference to a variable (`let foo = Foo { … }; &foo`) does not? [duplicate]

In the rust code below, I would expect both calls to pass_through to fail, since both a and b go out of scope at the end of the inner block. However, for some reason the following happens:

  • Creating a reference to an NC value and and storing that reference in a allows it to live long enough.
  • Creating an NC value and storing it in b, then taking a reference to b for the function parameter causes an error.
#[derive(Debug)]
struct NC(i32);

fn pass_through(x: &NC) -> &NC {
    x
}

fn main() {
    let a2: &NC;
    let b2: &NC;
    {
        let a = &NC(1);
        a2 = pass_through(a);  // Works fine

        let b = NC(2);
        b2 = pass_through(&b); // Error, borrowed value does not live long enough
    }
    println!("a2 - {:?}", a2);
    println!("b2 - {:?}", b2);
}

Why does the borrow checker treat these two cases differently?



Solution 1:[1]

Perhaps this is due to the way the compiler determines the lifetime of a reference.

In the case of the variable a, the compiler, analyzing the entire block, sees that the longest lifetime of the variable a2, which will be assigned a reference, extends its lifetime, because the variable does not own the data.

However, in the case of b, everything is different, the variable owns the data, which means that when you exit the block, the data will be deleted and the link will be valid.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Danila