Info
This post is auto-generated from RSS feed The Rust Programming Language Forum - Latest topics. Source: Converting FnOnce to AsyncFnOnce
I have the following async fn, see Playground
async fn transactional_save<F>(
db: DatabaseConnection,
callback: F,
) -> Result<User, TransactionError<DbErr>>
where
F: FnOnce(&User, &DatabaseTransaction) + Send + 'static,
{
db.transaction::<_, User, DbErr>(|txn| {
Box::pin(async move {
let user = User;
callback(&user, txn);
Ok(user)
})
})
.await
}
and I am trying to convert
F: FnOnce(&User, &DatabaseTransaction) + Send + 'static,
To
F: ASyncFnOnce(&User, &DatabaseTransaction) + Send + 'static,
So that callback(&user, txn);
becomes callback(&user, txn).await?;
This is what I have tried, see Playground
async fn transactional_save<F>(
db: DatabaseConnection,
callback: F,
) -> Result<User, TransactionError<DbErr>>
where
F: AsyncFnOnce(&User, &DatabaseTransaction) + Send + 'static,
{
db.transaction::<_, User, DbErr>(|txn| {
Box::pin(async move {
let user = User;
callback(&user, txn).await;
Ok(user)
})
})
.await
}
error: future cannot be sent between threads safely
--> src/lib.rs:45:9
|
45 | / Box::pin(async move {
46 | | let user = User;
47 | |
48 | | callback(&user, txn).await;
49 | |
50 | | Ok(user)
51 | | })
| |__________^ future created by async block is not `Send`
|
= help: within `{async block@src/lib.rs:45:18: 45:28}`, the trait `Send` is not implemented for `<F as AsyncFnOnce<(&User, &db::DatabaseTransaction)>>::CallOnceFuture`
note: future is not `Send` as it awaits another future which is not `Send`
--> src/lib.rs:48:13
|
48 | callback(&user, txn).await;
| ^^^^^^^^^^^^^^^^^^^^ await occurs here on type `<F as AsyncFnOnce<(&User, &db::DatabaseTransaction)>>::CallOnceFuture`, which is not `Send`
= note: required for the cast from `Pin<Box<{async block@src/lib.rs:45:18: 45:28}>>` to `Pin<Box<dyn Future<Output = Result<User, db::DbErr>> + Send>>`
What does the compiler try to tell me? I cannot comprehend the meaning. I thought I have marked F
to be Send
?
If I change the signature to the following then it compiles.
// F: AsyncFnOnce(&User, &DatabaseTransaction) + Send + 'static,
F: FnOnce(&User, &DatabaseTransaction) -> Fut + Send + 'static,
Fut: Future<Output = ()> + Send
2 posts - 2 participants
🏷️ Rust_feed