From fa91980d2d686d3f426a2cae1d0e8fd6825d2d94 Mon Sep 17 00:00:00 2001 From: Matthew Kelly Date: Fri, 19 Aug 2022 06:27:31 -0400 Subject: [PATCH] Add long description and test for E0311 Adds a long description and unit test for the E0311 compiler error. --- compiler/rustc_error_codes/src/error_codes.rs | 2 +- .../src/error_codes/E0311.md | 49 +++++++++++++++++++ src/test/ui/error-codes/E0311.rs | 18 +++++++ src/test/ui/error-codes/E0311.stderr | 45 +++++++++++++++++ 4 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 compiler/rustc_error_codes/src/error_codes/E0311.md create mode 100644 src/test/ui/error-codes/E0311.rs create mode 100644 src/test/ui/error-codes/E0311.stderr 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 @@ 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 @@ // 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 { + fn nested_borrow_mut(&mut self) -> &mut V; +} + +impl NestedBorrowMut for T +where + T: BorrowMut, + U: BorrowMut, // 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: BorrowMut + '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 { + fn nested_borrow_mut(&mut self) -> &mut V; +} + +impl NestedBorrowMut for T +where + T: BorrowMut, + U: BorrowMut, // 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 + '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 + '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`. -- 2.44.0