diff options
| author | bors <bors@rust-lang.org> | 2021-10-12 00:20:34 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-10-12 00:20:34 +0000 |
| commit | 97e3b30285af8526f8d21072a0c6d3f231e74876 (patch) | |
| tree | 4ac047b9f4927369c428718b86c233ab4830c505 /compiler/rustc_error_codes/src | |
| parent | 7cc8c44871b6e789d29fc0d42dacad9804c3a41c (diff) | |
| parent | f94a325496a475ec866f41a8036d4a418832522c (diff) | |
| download | rust-97e3b30285af8526f8d21072a0c6d3f231e74876.tar.gz rust-97e3b30285af8526f8d21072a0c6d3f231e74876.zip | |
Auto merge of #89791 - matthiaskrgr:rollup-1lhxh5b, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #89471 (Use Ancestory to check default fn in const impl instead of comparing idents) - #89643 (Fix inherent impl overlap check.) - #89651 (Add `Poll::ready` and revert stabilization of `task::ready!`) - #89675 (Re-use TypeChecker instead of passing around some of its fields ) - #89710 (Add long explanation for error E0482) - #89756 (Greatly reduce amount of debuginfo compiled for bootstrap itself) - #89760 (Remove hack ignoring unused attributes for stage 0 std) - #89772 (Fix function-names test for GDB 10.1) - #89785 (Fix ICE when compiling nightly std/rustc on beta compiler) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_error_codes/src')
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0482.md | 73 |
2 files changed, 74 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..58ebf43cc98 --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0482.md @@ -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 |
