I have a function foo
defined as follows:
fn foo<'a>(a: &'a i32, b: &i32) -> &'a i32 { a }
I want to store a pointer to that function in a struct:
struct S {
f: fn(a: &i32, b: &i32) -> &i32,
}
Because there are two input lifetimes, the result lifetime cannot be inferred:
error[E0106]: missing lifetime specifier
|
2 | f: fn(a: &i32, b: &i32) -> &i32,
| ^ expected lifetime parameter
|
= help: this function's return type contains a borrowed value,
but the signature does not say whether it is borrowed from a or b
When I ask the compiler for foo
's type, it's not very helpful either:
let () = foo;
gives me
expected type `fn(&'a i32, &i32) -> &'a i32 {foo}`
which obviously doesn't work because 'a
is not defined anywhere.
So how do I declare a lifetime in this context? Trying one of
f: fn<'a>(a: &'a i32, b: &i32) -> &'a i32
f<'a>: fn(a: &'a i32, b: &i32) -> &'a i32
results in a syntax error, and I could not find documentation covering this specific situation.
Define the lifetimes on the struct:
fn foo<'a>(a: &'a i32, b: &i32) -> &'a i32 { a }
struct S<'b, 'c> {
f: fn(a: &'b i32, b: &'c i32) -> &'b i32,
}
fn main() {
S {
f: foo,
};
}
Note that you cannot elide the second lifetime in this context.
But that would mean that a call to
(s.f)(&x, &y)
would not be generic over the lifetimes ofa
andb
anymore, unlikefoo(&x, &y)
Then you want higher-rank trait bounds (HRTBs):
fn foo<'a>(a: &'a i32, _b: &i32) -> &'a i32 { a }
struct S<F>
where for <'b, 'c> F: Fn(&'b i32, &'c i32) -> &'b i32,
{
f: F,
}
fn main() {
S {
f: foo,
};
}
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