Rollup merge of #89710 - sireliah:e0482, r=GuillaumeGomez
Add long explanation for error E0482 This is longer explanation for error E0482 in the #61137. Please take a look and leave some feedback!
This commit is contained in:
commit
57504aafe8
3 changed files with 75 additions and 2 deletions
73
compiler/rustc_error_codes/src/error_codes/E0482.md
Normal file
73
compiler/rustc_error_codes/src/error_codes/E0482.md
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
A lifetime of a returned 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> { // error!
|
||||
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 { // ok!
|
||||
words.map(|v| format!("foo-{}", v))
|
||||
}
|
||||
```
|
||||
|
||||
The [`impl Trait`] feature in this example uses an implicit `'static` lifetime
|
||||
restriction in the returned type. However the type implementing the `Iterator`
|
||||
passed to the function lives just as long as `'a`, which is not long enough.
|
||||
|
||||
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.
|
||||
|
||||
An 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> { // ok!
|
||||
words.map(|v| format!("foo-{}", v))
|
||||
}
|
||||
```
|
||||
|
||||
A similar lifetime problem might arise when returning closures:
|
||||
|
||||
```compile_fail,E0482
|
||||
fn foo(
|
||||
x: &mut Vec<i32>
|
||||
) -> impl FnMut(&mut Vec<i32>) -> &[i32] { // error!
|
||||
|y| {
|
||||
y.append(x);
|
||||
y
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Analogically, a 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 { // ok!
|
||||
move |y| {
|
||||
y.append(x);
|
||||
y
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To better understand the lifetime treatment in the [`impl Trait`],
|
||||
please see the [RFC 1951].
|
||||
|
||||
[`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
|
||||
Loading…
Add table
Add a link
Reference in a new issue