Skip to content

Commit

Permalink
Clean up E0716 explanation
Browse files Browse the repository at this point in the history
  • Loading branch information
GuillaumeGomez committed Jul 2, 2020
1 parent c86039b commit 818aaa7
Showing 1 changed file with 25 additions and 30 deletions.
55 changes: 25 additions & 30 deletions src/librustc_error_codes/error_codes/E0716.md
@@ -1,5 +1,4 @@
This error indicates that a temporary value is being dropped
while a borrow is still in active use.
A temporary value is being dropped while a borrow is still in active use.

Erroneous code example:

Expand All @@ -11,12 +10,11 @@ let p = bar(&foo());
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:
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 }
Expand All @@ -28,16 +26,14 @@ let p = {
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.
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:
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 }
Expand All @@ -47,16 +43,15 @@ 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.
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
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()`:

```
Expand All @@ -67,10 +62,10 @@ 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, 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
Expand Down

0 comments on commit 818aaa7

Please sign in to comment.