error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
--> src/main.rs:36:19
|
36 | data: &mut data,
| ^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime '_ as defined on the body at 34:17...
--> src/main.rs:34:17
|
34 | let mut c = || {
| ^^
note: ...so that closure can access `data`
--> src/main.rs:36:19
|
36 | data: &mut data,
| ^^^^^^^^^
note: but, the lifetime must be valid for the call at 39:18...
--> src/main.rs:39:18
|
39 | let server = c();
| ^^^
note: ...so type `Server<'_>` of expression is valid during the expression
--> src/main.rs:39:18
|
39 | let server = c();
| ^^^
error: aborting due to previous error
Update:
I found this post answered the question, but I could not understand some parts of it:
It turns out that, returning &'a mut i32 is not feasible for the shorter-live invocation of call_mut. What we’ve really wanted for the return type of call_mut, was something like:
The issue here is that the function cannot be FnMut, but has to be FnOnce: to be FnMut, the captured environment &'a mut Vec<i32> is only &'_ mut borrowed for a lifetime '_ that can be smaller than 'a, thus the resulting Server will not be a Server<'a> but a Server<'_>, and that function signature cannot be described by the current FnMut interface (it is the same issue as the one with iterators vs.streaming iterators, which you can look up).
To be able to return a Server<'a>, you need to take the captured environment (i.e., &'a mut Vec<i32>) by value (self: Self), at which point your closure will only be a FnOnce.
The surprising thing is that Rust itself gets lured into trying to define a FnMut that reborrows for some '_, and thus afterwards fails. So it has to be told that it not make a FnMut, but try to make a FnOnce directly:
struct Server<'a> {
data: &'a mut Vec<i32>,
}
fn make_closure<'a> (data: &'a mut Vec<i32>)
-> impl FnOnce() -> Server<'a> // the only place where we can currently tell Rust the kind of closure we are looking for
{
move || Server { data }
}
fn main() {
let mut data = vec![1, 2, 3];
let mut c = make_closure(&mut data);/*|| -> Server {
Server {
data: &mut data,
}
};*/
let server = c();
}