|  | 
|  | 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