It means that whatever type you pass, it was expected to be Send (i.e., thread safe by-value), but it wasn't.
That part of your code is pretty complicated; it probably tripped up type inference and the compiler simply gave up trying to figure out the correct coercions.
Compiling playground v0.1.0 (/home/explorer/playground)
error: captured variable cannot escape `FnMut` closure body
--> src/main.rs:70:13
|
66 | let mut tx = pool.begin().await.unwrap();
| ------ variable defined here
...
69 | Box::new(|model: &str| -> Pin<Box<dyn Future<Output = Result<i64, String>> + Send>> {
| --------------------------------------------------------- inferred to be a `FnMut` closure
70 | Box::pin(shirt_get_next_and_increase(&mut tx, model))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--^^^^^^^^^
| | |
| | variable captured here
| returns a reference to a captured variable which escapes the closure body
|
= note: `FnMut` closures only have access to their captured variables while they are executing...
= note: ...therefore, they cannot allow references to captured variables to escape
error: lifetime may not live long enough
--> src/main.rs:70:13
|
69 | Box::new(|model: &str| -> Pin<Box<dyn Future<Output = Result<i64, String>> + Send>> {
| - --------------------------------------------------------- return type of closure is Pin<Box<(dyn Future<Output = Result<i64, std::string::String>> + Send + '1)>>
| |
| let's call the lifetime of this reference `'2`
70 | Box::pin(shirt_get_next_and_increase(&mut tx, model))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'2` must outlive `'1`
error: could not compile `playground` due to 2 previous errors
You can try by modifying the code from line 68 on in the original OPs post:
I wonder if some more lifetime annotations are necessary, maybe with for<'lt>, which is experimental yet?
I guess you could use the first version that works, or is there a specific reason you want/need to
write it in the second way?
I don't really understand the lifetime problem above, but I wondered if it's a similar issue like this one that came up in another thread:
But I might be totally wrong.
I tried to use Box::leak to figure out if I can get the code to compile at least (it would not work, but that might help to find out what's the issue), but unfortunately, I cannot clone the tx or create a new one from within the non-async closure easily.
Hmmm, I see.
What I mean is, I believe that the type Pin<Box<dyn Future<Output = Result<i64, String>> + Send>>, which I used in my example, doesn't work because dyn without lifetime means dyn + 'static, I think. But the pinned boxed dyn Future has a lifetime that depends on the transaction and the string slice, and I don't know how to express that.
Wow. Not even you can. It is in these cases that I regret the simplicity of Go and other languages. I love Rust too much to throw it all away and switch back to that, but the temptation is strong.
Need to specify type. Inference or type conversion later can't deal with it.
Second error the variable is Drop. Making it use Lexical lifetimes. It captures tx but you use it later. Adding the block expression restricts the life.