I'm struggling with a lifetime problem recently. There goes the problem:
I have a struct A
and struct B
in some library, and an A
object contains a reference to a B
object like this:
#[derive(Debug)]
struct B {}
#[derive(Debug)]
struct A<'a> {
b: &'a B
}
And the library provides a function that receives a lambda invoked with a reference to some A
object constructed within the function scope:
fn lib_func<F: 'static + Sized + Fn(&A)>(f: F) {
let b = B {};
let a = A { b: &b };
f(&a);
}
Based on that function, I make a new function which receives a user-provided lambda which returns a new A
object referring the same B
object with the input A
reference, like Fn(&A<'a>) -> A<'a>
. My function looks like:
fn test<'a, F>(f: F)
where F: 'static + Fn(&A<'a>) -> A<'a>
{
lib_func(|a| {
let x = f(a);
println!("lib_func give a ref, user func produce: {:?}", x);
});
}
fn main() {
test(|a| A {b: a.b});
}
But I got E0308
when compiling saying that the lifetime defined in lambda of test
's body doesn't outlive lifetime 'a
.
Execution
Share
Close
Standard Error
Compiling playground v0.0.1 (file:///playground)
error[E0308]: mismatched types
--> src/main.rs:19:19
|
19 | let x = f(a);
| ^ lifetime mismatch
|
= note: expected type `&A<'a>`
found type `&A<'_>`
note: the anonymous lifetime #3 defined on the body at 18:14...
--> src/main.rs:18:14
|
18 | lib_func(|a| {
| ______________^
19 | | let x = f(a);
20 | | println!("Get result: {:?}", x);
21 | | });
| |_____^
note: ...does not necessarily outlive the lifetime 'a as defined on the function body at 15:1
--> src/main.rs:15:1
|
15 | / fn test<'a, F>(f: F)
16 | | where F: 'static + Fn(&A<'a>) -> A<'a>,
17 | | {
18 | | lib_func(|a| {
... |
21 | | });
22 | | }
| |_^
I'm confused about this. I specify the lifetime 'a
to input and output of the user-provided lambda is just to limit them to reference the same B
object. And expecting the returned A
object only live within the lambda scope, why does the compiler required the lambda lifetime scope outlive 'a
??
Full code can be found here: Rust Playground
Thanks in advance.