Reputation: 1215
Assume you have a function returning a closure which works on a reference. Sure, the object behind the reference must life at least as long as the closure is called.
Here a very simple example, which demonstrates the problem.
fn get_cloned<'a>(obj: &'a MyStruct) -> impl Fn() -> MyStruct {
|| {obj.clone()}
}
The compiler states that the returned closure has lifetime static:
cannot infer an appropriate lifetime
...but this borrow...rustc
main.rs(60, 56): this return type evaluates to the'static
lifetime...
main.rs(61, 5): ...but this borrow...
How can I tell the compiler that I only use the result of the function (the closure) as long as the reference is valid?
Thanks!
[Edit]
Do you need a dummy struct which holds the reference as well as the closure?
struct Dummy<'a>{
reference: &'a MyStruct,
closure: Fn() -> MyStruct
}
?
Assume that cloning is very costly and the closure might never be called. -> lazy evaluation is a must.
Upvotes: 0
Views: 923
Reputation: 30111
The compiler tells you what to do:
error: cannot infer an appropriate lifetime
--> src/lib.rs:2:9
|
1 | fn get_cloned<'a>(obj: &'a MyStruct) -> impl Fn() -> MyStruct {
| --------------------- this return type evaluates to the `'static` lifetime...
2 | || {obj.clone()}
| ^^^^^^^^^^^^^^^^ ...but this borrow...
|
note: ...can't outlive the lifetime 'a as defined on the function body at 1:15
--> src/lib.rs:1:15
|
1 | fn get_cloned<'a>(obj: &'a MyStruct) -> impl Fn() -> MyStruct {
| ^^
help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime 'a as defined on the function body at 1:15
|
1 | fn get_cloned<'a>(obj: &'a MyStruct) -> impl Fn() -> MyStruct + 'a {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
You need to add + 'a
on the return type. The compiler will then tell you you're missing move
, but after fixing that, your code works:
fn get_cloned<'a>(obj: &'a MyStruct) -> impl Fn() -> MyStruct + 'a {
|| {obj.clone()}
}
Upvotes: 1