This error indicates that a temporary value is being dropped
while a borrow is still in active use.
Erroneous code example:
```compile_fail,E0716
fn foo() -> i32 { 22 }
fn bar(x: &i32) -> &i32 { x }
let p = bar(&foo());
// ------ creates a temporary
let q = *p;
```
Here, the expression `&foo()` is borrowing the expression
`foo()`. As `foo()` is a call to a function, and not the name of
a variable, this creates a **temporary** -- that temporary stores
the return value from `foo()` so that it can be borrowed.
You could imagine that `let p = bar(&foo());` is equivalent
to this:
```compile_fail,E0597
# fn foo() -> i32 { 22 }
# fn bar(x: &i32) -> &i32 { x }
let p = {
let tmp = foo(); // the temporary
bar(&tmp)
}; // <-- tmp is freed as we exit this block
let q = p;
```
Whenever a temporary is created, it is automatically dropped (freed)
according to fixed rules. Ordinarily, the temporary is dropped
at the end of the enclosing statement -- in this case, after the `let`.
This is illustrated in the example above by showing that `tmp` would
be freed as we exit the block.
To fix this problem, you need to create a local variable
to store the value in rather than relying on a temporary.
For example, you might change the original program to
the following:
```
fn foo() -> i32 { 22 }
fn bar(x: &i32) -> &i32 { x }
let value = foo(); // dropped at the end of the enclosing block
let p = bar(&value);
let q = *p;
```
By introducing the explicit `let value`, we allocate storage
that will last until the end of the enclosing block (when `value`
goes out of scope). When we borrow `&value`, we are borrowing a
local variable that already exists, and hence no temporary is created.
Temporaries are not always dropped at the end of the enclosing
statement. In simple cases where the `&` expression is immediately
stored into a variable, the compiler will automatically extend
the lifetime of the temporary until the end of the enclosing
block. Therefore, an alternative way to fix the original
program is to write `let tmp = &foo()` and not `let tmp = foo()`:
```
fn foo() -> i32 { 22 }
fn bar(x: &i32) -> &i32 { x }
let value = &foo();
let p = bar(value);
let q = *p;
```
Here, we are still borrowing `foo()`, but as the borrow is assigned
directly into a variable, the temporary will not be dropped until
the end of the enclosing block. Similar rules apply when temporaries
are stored into aggregate structures like a tuple or struct:
```
// Here, two temporaries are created, but
// as they are stored directly into `value`,
// they are not dropped until the end of the
// enclosing block.
fn foo() -> i32 { 22 }
let value = (&foo(), &foo());
```