-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Add long description and test for E0311 #100747
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
fa91980
08fa70e
63de1ec
a9cefd0
dbcc409
231e3a0
dd7c48e
fc02eee
4f194a7
de3e95b
deadf07
4a443df
eda2a40
24aab52
0d9c014
c0d32fd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for the contributions! This explanation could be a bit confusing, I don't know how it should be reworded into, cc @compiler-errors any ideas? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point -- it would be great to have a better description here. I'm still pretty new to rust, so this was my initial attempt at reverse engineering why the fix worked. |
||
|
||
Erroneous code example: | ||
|
||
```compile_fail, E0311 | ||
MatthewPeterKelly marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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 | ||
MatthewPeterKelly marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
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. | ||
MatthewPeterKelly marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
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, | ||
MatthewPeterKelly marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
fn nested_borrow_mut(&'a mut self) -> &'a mut V { | ||
self.borrow_mut().borrow_mut() | ||
} | ||
} | ||
``` |
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() {} |
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`. |
Uh oh!
There was an error while loading. Please reload this page.