Because you annotate 'tr
on the function, which means the variable tr
in the body needs to live for that long. So a HRTB, i.e. Fun: for<'tr> FnOnce(&'tr mut Db::Transaction) -> Fut
, is required to express we want a tr with any lifetime in the body instead of one with a specified lifetime outside the function. Rust Playground
Then you'll run into another problem
error: lifetime may not live long enough
--> src/main.rs:9:24
|
9 | transact(&db, |tx| tx.calculation()).await.unwrap();
| --- ^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
| | |
| | return type of closure `impl Future<Output = Result<i32, anyhow::Error>>` contains a lifetime `'2`
| has type `&'1 mut TestTransaction`
It's derived from the lifetime in async fn. Like
async fn calculation(&mut self) -> Result<i32> {
Ok(42)
}
// desugar to
fn calculation<'1>(&'1 mut self) -> impl '1 + Future<Output = Result<i32>> {
async move { Ok(42) }
}
So to change the default behaviour, you can do this Rust Playground
fn calculation(&mut self) -> impl /* 'static + */ Future<Output = Result<i32>> { // lifetime elision :)
async move { Ok(42) }
}
But most of the time, you indeed need the default behaviour, since you use self there Rust Playground
fn calculation(&mut self) -> impl /* 'static + */ Future<Output = Result<i32>> {
async move { self; Ok(42) }
}
// error :(
error[E0700]: hidden type for `impl Future<Output = Result<i32, anyhow::Error>>` captures lifetime that does not appear in bounds
--> src/main.rs:60:9
|
59 | fn calculation(&mut self) -> impl /* 'static + */ Future<Output = Result<i32>> {
| --------- hidden type `[async block@src/main.rs:60:9: 60:36]` captures the anonymous lifetime defined here
60 | async move { self; Ok(42) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: to declare that `impl Future<Output = Result<i32, anyhow::Error>>` captures `'_`, you can add an explicit `'_` lifetime bound
|
59 | fn calculation(&mut self) -> impl /* 'static + */ Future<Output = Result<i32>> + '_ {
| ++++
Then this is a common issue with async callbacks. Search in this forum [1] and you'll find many similar solution. Rust Playground
I won't repeat explaning here and there. If one is really curious about things, there are enough excellent explanations given by other masters.
e.g. this recent one ↩︎