1
Fork 0

review updates to E0311 description

This commit is contained in:
Matthew Kelly 2022-08-29 06:05:01 -04:00
parent deadf071ed
commit 4a443dfb82

View file

@ -14,33 +14,25 @@ fn with_restriction<'a, T: 'a>(x: &'a ()) -> &'a () {
``` ```
Why doesn't this code compile? It helps to look at the lifetime bounds that are Why doesn't this code compile? It helps to look at the lifetime bounds that are
automatically adding by the compiler. For more details see the Rust automatically added by the compiler. For more details see the documentation for
Documentation for Lifetime Elision: [lifetime elision]( https://doc.rust-lang.org/reference/lifetime-elision.html).
https://doc.rust-lang.org/reference/lifetime-elision.html.
There are two lifetimes being passed into the `no_restriction()` function: one The compiler elides the lifetime of `x` and the return type to some arbitrary
associated with the generic type `T` parameter and the other with the input lifetime `'anon` in `no_restriction()`. The only information available to the
argument `x`. The compiler does not know which of these lifetimes can be compiler is that `'anon` is valid for the duration of the function. When
assigned to the output reference, so we get an error. calling `with_restriction()`, the compiler requires the completely unrelated
type parameter `T` to outlive `'anon` because of the `T: 'a bound` in
`with_restriction()`. This causes an error because `T` is not required to
outlive `'anon` in `no_restriction()`.
One way to "fix" this code would be to remove the generic type argument `T`. If `no_restriction()` were to use `&T` instead of `&()` as an argument, the
In this case, the lifetime elision works because there is a single input compiler would have added an implied bound [implied
lifetime, which is associated with `x`. bound](https://rust-lang.github.io/rfcs/2089-implied-bounds.html), causing this
to compile.
``` This error can be resolved by explicitly naming the elided lifetime for `x` and
fn no_restriction(x: &()) -> &() { then explicily requiring that the generic parameter `T` outlives that lifetime:
with_restriction(x)
}
fn with_restriction<'a>(x: &'a ()) -> &'a () {
x
}
```
The "correct" way to resolve this error is to explicitly tell the compiler
which input lifetime should be assigned to the output. In this case we give
both the generic type `T` parameter and the argument `x` the same lifetime
requirement as the output reference, producing a working version of the code:
``` ```
fn no_restriction<'a, T: 'a>(x: &'a ()) -> &'a () { fn no_restriction<'a, T: 'a>(x: &'a ()) -> &'a () {
with_restriction::<T>(x) with_restriction::<T>(x)