With the code
fn foo<'a, 'b>(
state: &'b mut i32,
) -> impl FnMut(&'a str) -> &'static str + 'b {
|s| "hi"
}
I get an error
error[E0482]: lifetime of return value does not outlive the function call
112 | ) -> impl FnMut(&'a str) -> &'static str + 'b {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: the return value is only valid for the lifetime `'a` as defined on the function body at 110:9
110 | fn foo1<'a, 'b>(
| ^^
But somehow the code
fn foo2<'a, 'b>(
state: &'b mut Option<&'a i32>,
) -> impl FnMut(&'a str) -> &'static str + 'b {
|s| "hi"
}
compiles without errors. Why does the type of state
change the lifetime of the closure?
With type &'b mut Option<&'a i32>
, Rust infers the lifetime bound 'a: 'b
('a
outlives 'b
). This bound is required for the function signature to be well-formed. You can add this bound explicitly to avoid the error:
fn foo<'a, 'b>(
state: &'b mut i32,
) -> impl FnMut(&'a str) -> &'static str + 'b
where
'a: 'b,
{
|s| "hi"
}
However, if no parameter uses 'a
, then 'a
should be a higher-rank trait bound instead:
fn foo<'b>(
state: &'b mut i32,
) -> impl for<'a> FnMut(&'a str) -> &'static str + 'b {
|s| "hi"
}
The Fn
family of traits are special in that they allow you to omit the lifetime entirely (following the same elision rules as fn
signatures), so this is equivalent:
fn foo<'b>(
state: &'b mut i32,
) -> impl FnMut(&str) -> &'static str + 'b {
|s| "hi"
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With