Skip to content

Commit fa91980

Browse files
Add long description and test for E0311
Adds a long description and unit test for the E0311 compiler error.
1 parent 6c943ba commit fa91980

File tree

4 files changed

+113
-1
lines changed

4 files changed

+113
-1
lines changed

compiler/rustc_error_codes/src/error_codes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ E0307: include_str!("./error_codes/E0307.md"),
159159
E0308: include_str!("./error_codes/E0308.md"),
160160
E0309: include_str!("./error_codes/E0309.md"),
161161
E0310: include_str!("./error_codes/E0310.md"),
162+
E0311: include_str!("./error_codes/E0311.md"),
162163
E0312: include_str!("./error_codes/E0312.md"),
163164
E0316: include_str!("./error_codes/E0316.md"),
164165
E0317: include_str!("./error_codes/E0317.md"),
@@ -568,7 +569,6 @@ E0790: include_str!("./error_codes/E0790.md"),
568569
// E0300, // unexpanded macro
569570
// E0304, // expected signed integer constant
570571
// E0305, // expected constant
571-
E0311, // thing may not live long enough
572572
E0313, // lifetime of borrowed pointer outlives lifetime of captured
573573
// variable
574574
// E0314, // closure outlives stack frame
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
E0311 occurs when there is insufficient information for the rust compiler to
2+
prove that some time has a long enough lifetime.
3+
4+
Erroneous code example:
5+
6+
```compile_fail, E0311
7+
use std::borrow::BorrowMut;
8+
9+
trait NestedBorrowMut<U, V> {
10+
fn nested_borrow_mut(&mut self) -> &mut V;
11+
}
12+
13+
impl<T, U, V> NestedBorrowMut<U, V> for T
14+
where
15+
T: BorrowMut<U>,
16+
U: BorrowMut<V>, // missing lifetime specifier here --> compile fail
17+
{
18+
fn nested_borrow_mut(&mut self) -> &mut V {
19+
self.borrow_mut().borrow_mut()
20+
}
21+
}
22+
```
23+
24+
In this example we have a trait that borrows some inner data element of type V
25+
from an outer type T, through an intermediate type U. The compiler is unable to
26+
prove that the livetime of U is long enough to support the reference, so it
27+
throws E0311. To fix the issue we can explicitly add lifetime specifiers to the
28+
trait, which link the lifetimes of the various data types and allow the code
29+
to compile.
30+
31+
Working implementation of the `NestedBorrowMut` trait:
32+
33+
```
34+
use std::borrow::BorrowMut;
35+
36+
trait NestedBorrowMut<'a, U, V> {
37+
fn nested_borrow_mut(& 'a mut self) -> &'a mut V;
38+
}
39+
40+
impl<'a, T, U, V> NestedBorrowMut<'a, U, V> for T
41+
where
42+
T: BorrowMut<U>,
43+
U: BorrowMut<V> + 'a,
44+
{
45+
fn nested_borrow_mut(&'a mut self) -> &'a mut V {
46+
self.borrow_mut().borrow_mut()
47+
}
48+
}
49+
```

src/test/ui/error-codes/E0311.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
use std::borrow::BorrowMut;
2+
3+
trait NestedBorrowMut<U, V> {
4+
fn nested_borrow_mut(&mut self) -> &mut V;
5+
}
6+
7+
impl<T, U, V> NestedBorrowMut<U, V> for T
8+
where
9+
T: BorrowMut<U>,
10+
U: BorrowMut<V>, // Error is caused by missing lifetime here
11+
{
12+
fn nested_borrow_mut(&mut self) -> &mut V {
13+
let u_ref = self.borrow_mut(); //~ ERROR E0311
14+
u_ref.borrow_mut() //~ ERROR E0311
15+
}
16+
}
17+
18+
fn main() {}

src/test/ui/error-codes/E0311.stderr

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
error[E0311]: the parameter type `U` may not live long enough
2+
--> $DIR/E0311.rs:13:21
3+
|
4+
LL | let u_ref = self.borrow_mut();
5+
| ^^^^^^^^^^^^^^^^^
6+
|
7+
note: the parameter type `U` must be valid for the anonymous lifetime defined here...
8+
--> $DIR/E0311.rs:12:26
9+
|
10+
LL | fn nested_borrow_mut(&mut self) -> &mut V {
11+
| ^^^^^^^^^
12+
note: ...so that the type `U` will meet its required lifetime bounds
13+
--> $DIR/E0311.rs:13:21
14+
|
15+
LL | let u_ref = self.borrow_mut();
16+
| ^^^^^^^^^^^^^^^^^
17+
help: consider adding an explicit lifetime bound...
18+
|
19+
LL | U: BorrowMut<V> + 'a, // Error is caused by missing lifetime here
20+
| ++++
21+
22+
error[E0311]: the parameter type `U` may not live long enough
23+
--> $DIR/E0311.rs:14:9
24+
|
25+
LL | u_ref.borrow_mut()
26+
| ^^^^^^^^^^^^^^^^^^
27+
|
28+
note: the parameter type `U` must be valid for the anonymous lifetime defined here...
29+
--> $DIR/E0311.rs:12:26
30+
|
31+
LL | fn nested_borrow_mut(&mut self) -> &mut V {
32+
| ^^^^^^^^^
33+
note: ...so that the type `U` will meet its required lifetime bounds
34+
--> $DIR/E0311.rs:14:9
35+
|
36+
LL | u_ref.borrow_mut()
37+
| ^^^^^^^^^^^^^^^^^^
38+
help: consider adding an explicit lifetime bound...
39+
|
40+
LL | U: BorrowMut<V> + 'a, // Error is caused by missing lifetime here
41+
| ++++
42+
43+
error: aborting due to 2 previous errors
44+
45+
For more information about this error, try `rustc --explain E0311`.

0 commit comments

Comments
 (0)