From a94e39e7f440deb408637150b226f39e0d62ee11 Mon Sep 17 00:00:00 2001 From: sireliah Date: Sat, 9 Oct 2021 21:27:06 +0200 Subject: [PATCH] Add long explanation for error E0482 --- compiler/rustc_error_codes/src/error_codes.rs | 2 +- .../src/error_codes/E0482.md | 68 +++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 compiler/rustc_error_codes/src/error_codes/E0482.md diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index 45d91c2047d..1b4b58314b3 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -242,6 +242,7 @@ E0468: include_str!("./error_codes/E0468.md"), E0469: include_str!("./error_codes/E0469.md"), E0477: include_str!("./error_codes/E0477.md"), E0478: include_str!("./error_codes/E0478.md"), +E0482: include_str!("./error_codes/E0482.md"), E0491: include_str!("./error_codes/E0491.md"), E0492: include_str!("./error_codes/E0492.md"), E0493: include_str!("./error_codes/E0493.md"), @@ -599,7 +600,6 @@ E0785: include_str!("./error_codes/E0785.md"), // E0479, // the type `..` (provided as the value of a type parameter) is... // E0480, // lifetime of method receiver does not outlive the method call // E0481, // lifetime of function argument does not outlive the function call - E0482, // lifetime of return value does not outlive the function call // E0483, // lifetime of operand does not outlive the operation // E0484, // reference is not valid at the time of borrow // E0485, // automatically reference is not valid at the time of borrow diff --git a/compiler/rustc_error_codes/src/error_codes/E0482.md b/compiler/rustc_error_codes/src/error_codes/E0482.md new file mode 100644 index 00000000000..5ae754b8252 --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0482.md @@ -0,0 +1,68 @@ +A lifetime of return value does not outlive the function call. + +Erroneous code example: + +```compile_fail,E0482 +fn prefix<'a>( + words: impl Iterator +) -> impl Iterator { + words.map(|v| format!("foo-{}", v)) +} +``` + +To fix this error, make the lifetime of the returned value explicit. + +``` +fn prefix<'a>( + words: impl Iterator + 'a +) -> impl Iterator + 'a { + words.map(|v| format!("foo-{}", v)) +} +``` + +[`impl Trait`] feature in return type have implicit `'static` lifetime +restriction and the type implementing the `Iterator` passed to the function +lives just `'a`, so shorter time. + +The solution involves adding lifetime bound to both function argument and +the return value to make sure that the values inside the iterator +are not dropped when the function goes out of the scope. + +Alternative solution would be to guarantee that the `Item` references +in the iterator are alive for the whole lifetime of the program. + +``` +fn prefix( + words: impl Iterator +) -> impl Iterator { + words.map(|v| format!("foo-{}", v)) +} +``` + +Similar lifetime problem might arise when returning closures. + +Erroneous code example: + +```compile_fail,E0482 +fn foo(x: &mut Vec) -> impl FnMut(&mut Vec) -> &[i32] { + |y| { + y.append(x); + y + } +} +``` + +Analogically, solution here is to use explicit return lifetime +and move the ownership of the variable to the closure. + +``` +fn foo<'a>(x: &'a mut Vec) -> impl FnMut(&mut Vec) -> &[i32] + 'a { + move |y| { + y.append(x); + y + } +} +``` + +- [`impl Trait`]: https://doc.rust-lang.org/reference/types/impl-trait.html +- [RFC 1951]: https://rust-lang.github.io/rfcs/1951-expand-impl-trait.html