Description
The following code does not compile:
fn function(x: &i32) -> &i32 { x } // ok
let closure = |x: &i32| -> &i32 { x }; // fails
Output:
error: lifetime may not live long enough
--> src/main.rs:3:35
|
3 | let closure = |x: &i32| -> &i32 { x };
| - - ^ returning this value requires that `'1` must outlive `'2`
| | |
| | let's call the lifetime of this reference `'2`
| let's call the lifetime of this reference `'1`
For function
, the lifetime of the return type is properly inferred to be equal to the only input lifetime, as per the lifetime elision rules:
If there is exactly one lifetime used in the parameters (elided or not), that lifetime is assigned to all elided output lifetimes.
However, for closure
this is not done, and the return type is assigned a distinct lifetime from the input. AFAIK it is only an accident of history that closures do not have the same lifetime elision rules as functions. This would be a breaking change to fix, but should be able to be done over an edition.
Here's a simplified example of code that compiles today that might break if the function elision rules were applied to closures:
fn foo(s: &str) -> &str {
let bar = |_| { s };
bar(&String::new())
}
See #56537 for prior discussion.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status