Skip to content

Commit 4a443df

Browse files
review updates to E0311 description
1 parent deadf07 commit 4a443df

File tree

1 file changed

+15
-23
lines changed
  • compiler/rustc_error_codes/src/error_codes

1 file changed

+15
-23
lines changed

compiler/rustc_error_codes/src/error_codes/E0311.md

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,33 +14,25 @@ fn with_restriction<'a, T: 'a>(x: &'a ()) -> &'a () {
1414
```
1515

1616
Why doesn't this code compile? It helps to look at the lifetime bounds that are
17-
automatically adding by the compiler. For more details see the Rust
18-
Documentation for Lifetime Elision:
19-
https://doc.rust-lang.org/reference/lifetime-elision.html.
17+
automatically added by the compiler. For more details see the documentation for
18+
[lifetime elision]( https://doc.rust-lang.org/reference/lifetime-elision.html).
2019

21-
There are two lifetimes being passed into the `no_restriction()` function: one
22-
associated with the generic type `T` parameter and the other with the input
23-
argument `x`. The compiler does not know which of these lifetimes can be
24-
assigned to the output reference, so we get an error.
20+
The compiler elides the lifetime of `x` and the return type to some arbitrary
21+
lifetime `'anon` in `no_restriction()`. The only information available to the
22+
compiler is that `'anon` is valid for the duration of the function. When
23+
calling `with_restriction()`, the compiler requires the completely unrelated
24+
type parameter `T` to outlive `'anon` because of the `T: 'a bound` in
25+
`with_restriction()`. This causes an error because `T` is not required to
26+
outlive `'anon` in `no_restriction()`.
2527

26-
One way to "fix" this code would be to remove the generic type argument `T`.
27-
In this case, the lifetime elision works because there is a single input
28-
lifetime, which is associated with `x`.
28+
If `no_restriction()` were to use `&T` instead of `&()` as an argument, the
29+
compiler would have added an implied bound [implied
30+
bound](https://rust-lang.github.io/rfcs/2089-implied-bounds.html), causing this
31+
to compile.
2932

30-
```
31-
fn no_restriction(x: &()) -> &() {
32-
with_restriction(x)
33-
}
34-
35-
fn with_restriction<'a>(x: &'a ()) -> &'a () {
36-
x
37-
}
38-
```
33+
This error can be resolved by explicitly naming the elided lifetime for `x` and
34+
then explicily requiring that the generic parameter `T` outlives that lifetime:
3935

40-
The "correct" way to resolve this error is to explicitly tell the compiler
41-
which input lifetime should be assigned to the output. In this case we give
42-
both the generic type `T` parameter and the argument `x` the same lifetime
43-
requirement as the output reference, producing a working version of the code:
4436
```
4537
fn no_restriction<'a, T: 'a>(x: &'a ()) -> &'a () {
4638
with_restriction::<T>(x)

0 commit comments

Comments
 (0)