1
Fork 0

Add long description and test for E0311

Adds a long description and unit test for the E0311 compiler error.
This commit is contained in:
Matthew Kelly 2022-08-19 06:27:31 -04:00
parent 6c943bad02
commit fa91980d2d
4 changed files with 113 additions and 1 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,49 @@
E0311 occurs when there is insufficient information for the rust compiler to
prove that some time has a long enough lifetime.
Erroneous code example:
```compile_fail, E0311
use std::borrow::BorrowMut;
trait NestedBorrowMut<U, V> {
fn nested_borrow_mut(&mut self) -> &mut V;
}
impl<T, U, V> NestedBorrowMut<U, V> for T
where
T: BorrowMut<U>,
U: BorrowMut<V>, // missing lifetime specifier here --> compile fail
{
fn nested_borrow_mut(&mut self) -> &mut V {
self.borrow_mut().borrow_mut()
}
}
```
In this example we have a trait that borrows some inner data element of type V
from an outer type T, through an intermediate type U. The compiler is unable to
prove that the livetime of U is long enough to support the reference, so it
throws E0311. To fix the issue we can explicitly add lifetime specifiers to the
trait, which link the lifetimes of the various data types and allow the code
to compile.
Working implementation of the `NestedBorrowMut` trait:
```
use std::borrow::BorrowMut;
trait NestedBorrowMut<'a, U, V> {
fn nested_borrow_mut(& 'a mut self) -> &'a mut V;
}
impl<'a, T, U, V> NestedBorrowMut<'a, U, V> for T
where
T: BorrowMut<U>,
U: BorrowMut<V> + 'a,
{
fn nested_borrow_mut(&'a mut self) -> &'a mut V {
self.borrow_mut().borrow_mut()
}
}
```

View file

@ -0,0 +1,18 @@
use std::borrow::BorrowMut;
trait NestedBorrowMut<U, V> {
fn nested_borrow_mut(&mut self) -> &mut V;
}
impl<T, U, V> NestedBorrowMut<U, V> for T
where
T: BorrowMut<U>,
U: BorrowMut<V>, // Error is caused by missing lifetime here
{
fn nested_borrow_mut(&mut self) -> &mut V {
let u_ref = self.borrow_mut(); //~ ERROR E0311
u_ref.borrow_mut() //~ ERROR E0311
}
}
fn main() {}

View file

@ -0,0 +1,45 @@
error[E0311]: the parameter type `U` may not live long enough
--> $DIR/E0311.rs:13:21
|
LL | let u_ref = self.borrow_mut();
| ^^^^^^^^^^^^^^^^^
|
note: the parameter type `U` must be valid for the anonymous lifetime defined here...
--> $DIR/E0311.rs:12:26
|
LL | fn nested_borrow_mut(&mut self) -> &mut V {
| ^^^^^^^^^
note: ...so that the type `U` will meet its required lifetime bounds
--> $DIR/E0311.rs:13:21
|
LL | let u_ref = self.borrow_mut();
| ^^^^^^^^^^^^^^^^^
help: consider adding an explicit lifetime bound...
|
LL | U: BorrowMut<V> + 'a, // Error is caused by missing lifetime here
| ++++
error[E0311]: the parameter type `U` may not live long enough
--> $DIR/E0311.rs:14:9
|
LL | u_ref.borrow_mut()
| ^^^^^^^^^^^^^^^^^^
|
note: the parameter type `U` must be valid for the anonymous lifetime defined here...
--> $DIR/E0311.rs:12:26
|
LL | fn nested_borrow_mut(&mut self) -> &mut V {
| ^^^^^^^^^
note: ...so that the type `U` will meet its required lifetime bounds
--> $DIR/E0311.rs:14:9
|
LL | u_ref.borrow_mut()
| ^^^^^^^^^^^^^^^^^^
help: consider adding an explicit lifetime bound...
|
LL | U: BorrowMut<V> + 'a, // Error is caused by missing lifetime here
| ++++
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0311`.