Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_error_codes/src/error_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand Down Expand Up @@ -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
Expand Down
48 changes: 48 additions & 0 deletions compiler/rustc_error_codes/src/error_codes/E0311.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
This error 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>, // error: missing lifetime specifier
{
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. To fix the
issue we can explicitly add lifetime specifiers to the `NestedBorrowMut` 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, // Adding lifetime specifier
{
fn nested_borrow_mut(&'a mut self) -> &'a mut V {
self.borrow_mut().borrow_mut()
}
}
```
18 changes: 18 additions & 0 deletions src/test/ui/error-codes/E0311.rs
Original file line number Diff line number Diff line change
@@ -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() {}
45 changes: 45 additions & 0 deletions src/test/ui/error-codes/E0311.stderr
Original file line number Diff line number Diff line change
@@ -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`.
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ LL | fn func<T: Test + 'a>(foo: &Foo, t: T) {

error: aborting due to previous error

For more information about this error, try `rustc --explain E0311`.
Original file line number Diff line number Diff line change
Expand Up @@ -162,5 +162,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`.