Skip to content

Commit a94e39e

Browse files
committed
Add long explanation for error E0482
1 parent 69eb996 commit a94e39e

File tree

2 files changed

+69
-1
lines changed

2 files changed

+69
-1
lines changed

compiler/rustc_error_codes/src/error_codes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ E0468: include_str!("./error_codes/E0468.md"),
242242
E0469: include_str!("./error_codes/E0469.md"),
243243
E0477: include_str!("./error_codes/E0477.md"),
244244
E0478: include_str!("./error_codes/E0478.md"),
245+
E0482: include_str!("./error_codes/E0482.md"),
245246
E0491: include_str!("./error_codes/E0491.md"),
246247
E0492: include_str!("./error_codes/E0492.md"),
247248
E0493: include_str!("./error_codes/E0493.md"),
@@ -599,7 +600,6 @@ E0785: include_str!("./error_codes/E0785.md"),
599600
// E0479, // the type `..` (provided as the value of a type parameter) is...
600601
// E0480, // lifetime of method receiver does not outlive the method call
601602
// E0481, // lifetime of function argument does not outlive the function call
602-
E0482, // lifetime of return value does not outlive the function call
603603
// E0483, // lifetime of operand does not outlive the operation
604604
// E0484, // reference is not valid at the time of borrow
605605
// E0485, // automatically reference is not valid at the time of borrow
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
A lifetime of return value does not outlive the function call.
2+
3+
Erroneous code example:
4+
5+
```compile_fail,E0482
6+
fn prefix<'a>(
7+
words: impl Iterator<Item = &'a str>
8+
) -> impl Iterator<Item = String> {
9+
words.map(|v| format!("foo-{}", v))
10+
}
11+
```
12+
13+
To fix this error, make the lifetime of the returned value explicit.
14+
15+
```
16+
fn prefix<'a>(
17+
words: impl Iterator<Item = &'a str> + 'a
18+
) -> impl Iterator<Item = String> + 'a {
19+
words.map(|v| format!("foo-{}", v))
20+
}
21+
```
22+
23+
[`impl Trait`] feature in return type have implicit `'static` lifetime
24+
restriction and the type implementing the `Iterator` passed to the function
25+
lives just `'a`, so shorter time.
26+
27+
The solution involves adding lifetime bound to both function argument and
28+
the return value to make sure that the values inside the iterator
29+
are not dropped when the function goes out of the scope.
30+
31+
Alternative solution would be to guarantee that the `Item` references
32+
in the iterator are alive for the whole lifetime of the program.
33+
34+
```
35+
fn prefix(
36+
words: impl Iterator<Item = &'static str>
37+
) -> impl Iterator<Item = String> {
38+
words.map(|v| format!("foo-{}", v))
39+
}
40+
```
41+
42+
Similar lifetime problem might arise when returning closures.
43+
44+
Erroneous code example:
45+
46+
```compile_fail,E0482
47+
fn foo(x: &mut Vec<i32>) -> impl FnMut(&mut Vec<i32>) -> &[i32] {
48+
|y| {
49+
y.append(x);
50+
y
51+
}
52+
}
53+
```
54+
55+
Analogically, solution here is to use explicit return lifetime
56+
and move the ownership of the variable to the closure.
57+
58+
```
59+
fn foo<'a>(x: &'a mut Vec<i32>) -> impl FnMut(&mut Vec<i32>) -> &[i32] + 'a {
60+
move |y| {
61+
y.append(x);
62+
y
63+
}
64+
}
65+
```
66+
67+
- [`impl Trait`]: https://doc.rust-lang.org/reference/types/impl-trait.html
68+
- [RFC 1951]: https://rust-lang.github.io/rfcs/1951-expand-impl-trait.html

0 commit comments

Comments
 (0)