about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_error_codes/src/error_codes.rs2
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0311.md49
-rw-r--r--src/test/ui/error-codes/E0311.rs18
-rw-r--r--src/test/ui/error-codes/E0311.stderr45
4 files changed, 113 insertions, 1 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs
index 854625579ee..1e86d159668 100644
--- a/compiler/rustc_error_codes/src/error_codes.rs
+++ b/compiler/rustc_error_codes/src/error_codes.rs
@@ -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
diff --git a/compiler/rustc_error_codes/src/error_codes/E0311.md b/compiler/rustc_error_codes/src/error_codes/E0311.md
new file mode 100644
index 00000000000..8b5daaaa178
--- /dev/null
+++ b/compiler/rustc_error_codes/src/error_codes/E0311.md
@@ -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()
+    }
+}
+```
diff --git a/src/test/ui/error-codes/E0311.rs b/src/test/ui/error-codes/E0311.rs
new file mode 100644
index 00000000000..eb9a473e9a2
--- /dev/null
+++ b/src/test/ui/error-codes/E0311.rs
@@ -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() {}
diff --git a/src/test/ui/error-codes/E0311.stderr b/src/test/ui/error-codes/E0311.stderr
new file mode 100644
index 00000000000..a219a6352ad
--- /dev/null
+++ b/src/test/ui/error-codes/E0311.stderr
@@ -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`.