about summary refs log tree commit diff
diff options
context:
space:
mode:
authorsireliah <sajuukk@gmail.com>2021-10-09 21:27:06 +0200
committersireliah <sajuukk@gmail.com>2021-10-09 21:49:09 +0200
commita94e39e7f440deb408637150b226f39e0d62ee11 (patch)
treef99c585ed2381d2cb4aedbcf477e700822faf90c
parent69eb996b2617621c7088e567089a86a6657f2a0f (diff)
downloadrust-a94e39e7f440deb408637150b226f39e0d62ee11.tar.gz
rust-a94e39e7f440deb408637150b226f39e0d62ee11.zip
Add long explanation for error E0482
-rw-r--r--compiler/rustc_error_codes/src/error_codes.rs2
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0482.md68
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