1
Fork 0

Rollup merge of #100747 - MatthewPeterKelly:mpk/add-long-error-message-for-E0311, r=MatthewPeterKelly

Add long description and test for E0311

Adds a long description and unit test for the E0311 compiler error.

Fixes one line-item in https://github.com/rust-lang/rust/issues/61137.
This commit is contained in:
Yuki Okushi 2022-09-28 13:07:16 +09:00 committed by GitHub
commit 49bc668493
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 79 additions and 2 deletions

View file

@ -159,6 +159,7 @@ E0307: include_str!("./error_codes/E0307.md"),
E0308: include_str!("./error_codes/E0308.md"),
E0309: include_str!("./error_codes/E0309.md"),
E0310: include_str!("./error_codes/E0310.md"),
E0311: include_str!("./error_codes/E0311.md"),
E0312: include_str!("./error_codes/E0312.md"),
E0316: include_str!("./error_codes/E0316.md"),
E0317: include_str!("./error_codes/E0317.md"),
@ -568,7 +569,6 @@ E0790: include_str!("./error_codes/E0790.md"),
// E0300, // unexpanded macro
// E0304, // expected signed integer constant
// E0305, // expected constant
E0311, // thing may not live long enough
E0313, // lifetime of borrowed pointer outlives lifetime of captured
// variable
// E0314, // closure outlives stack frame

View file

@ -0,0 +1,42 @@
This error occurs when there is an unsatisfied outlives bound involving an
elided region and a generic type parameter or associated type.
Erroneous code example:
```compile_fail,E0311
fn no_restriction<T>(x: &()) -> &() {
with_restriction::<T>(x)
}
fn with_restriction<'a, T: 'a>(x: &'a ()) -> &'a () {
x
}
```
Why doesn't this code compile? It helps to look at the lifetime bounds that are
automatically added by the compiler. For more details see the documentation for
[lifetime elision]( https://doc.rust-lang.org/reference/lifetime-elision.html).
The compiler elides the lifetime of `x` and the return type to some arbitrary
lifetime `'anon` in `no_restriction()`. The only information available to the
compiler is that `'anon` is valid for the duration of the function. When
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()`.
If `no_restriction()` were to use `&T` instead of `&()` as an argument, the
compiler would have added an implied bound, causing this to compile.
This error can be resolved by explicitly naming the elided lifetime for `x` and
then explicily requiring that the generic parameter `T` outlives that lifetime:
```
fn no_restriction<'a, T: 'a>(x: &'a ()) -> &'a () {
with_restriction::<T>(x)
}
fn with_restriction<'a, T: 'a>(x: &'a ()) -> &'a () {
x
}
```

View file

@ -0,0 +1,9 @@
fn no_restriction<T>(x: &()) -> &() {
with_restriction::<T>(x) //~ ERROR E0311
}
fn with_restriction<'a, T: 'a>(x: &'a ()) -> &'a () {
x
}
fn main() {}

View file

@ -0,0 +1,24 @@
error[E0311]: the parameter type `T` may not live long enough
--> $DIR/E0311.rs:2:5
|
LL | with_restriction::<T>(x)
| ^^^^^^^^^^^^^^^^^^^^^
|
note: the parameter type `T` must be valid for the anonymous lifetime defined here...
--> $DIR/E0311.rs:1:25
|
LL | fn no_restriction<T>(x: &()) -> &() {
| ^^^
note: ...so that the type `T` will meet its required lifetime bounds
--> $DIR/E0311.rs:2:5
|
LL | with_restriction::<T>(x)
| ^^^^^^^^^^^^^^^^^^^^^
help: consider adding an explicit lifetime bound...
|
LL | fn no_restriction<'a, T: 'a>(x: &()) -> &() {
| +++ ++++
error: aborting due to previous error
For more information about this error, try `rustc --explain E0311`.

View file

@ -21,3 +21,4 @@ LL | fn no_restriction<'a, T: 'a>(x: &()) -> &() {
error: aborting due to previous error
For more information about this error, try `rustc --explain E0311`.

View file

@ -27,3 +27,4 @@ LL | fn func<'a, T: Test + 'a>(foo: &Foo, t: T) {
error: aborting due to previous error
For more information about this error, try `rustc --explain E0311`.

View file

@ -164,5 +164,5 @@ LL | G: Get<T> + 'a,
error: aborting due to 8 previous errors
Some errors have detailed explanations: E0261, E0309, E0621, E0700.
Some errors have detailed explanations: E0261, E0309, E0311, E0621, E0700.
For more information about an error, try `rustc --explain E0261`.