diff options
| author | sireliah <sajuukk@gmail.com> | 2021-10-09 21:27:06 +0200 |
|---|---|---|
| committer | sireliah <sajuukk@gmail.com> | 2021-10-09 21:49:09 +0200 |
| commit | a94e39e7f440deb408637150b226f39e0d62ee11 (patch) | |
| tree | f99c585ed2381d2cb4aedbcf477e700822faf90c | |
| parent | 69eb996b2617621c7088e567089a86a6657f2a0f (diff) | |
| download | rust-a94e39e7f440deb408637150b226f39e0d62ee11.tar.gz rust-a94e39e7f440deb408637150b226f39e0d62ee11.zip | |
Add long explanation for error E0482
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0482.md | 68 |
2 files changed, 69 insertions, 1 deletions
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<Item = &'a str> +) -> impl Iterator<Item = String> { + words.map(|v| format!("foo-{}", v)) +} +``` + +To fix this error, make the lifetime of the returned value explicit. + +``` +fn prefix<'a>( + words: impl Iterator<Item = &'a str> + 'a +) -> impl Iterator<Item = String> + '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<Item = &'static str> +) -> impl Iterator<Item = String> { + 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<i32>) -> impl FnMut(&mut Vec<i32>) -> &[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<i32>) -> impl FnMut(&mut Vec<i32>) -> &[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 |
