Reputation: 4156
This code works:
async fn player_create<'a>(
&'a self,
team_id: &'a str,
_input: &'a PlayerInput,
lambda: &'a Lambda<'_, PlayerCreateLambdaArgs<'a>, DomainPlayer>,
) -> Result<DomainPlayer> {
let tx = Arc::new(Mutex::new(self.pool.begin().await.unwrap()));
let shirt_next_value = Box::new({
let tx = tx.clone();
move |model: &'a str,
name: &'a str| -> Pin<Box<dyn Future<Output = Result<i64>> + Send>> {
let tx = tx.clone();
Box::pin(async move {
self::Shirt::shirt_get_next_and_increase(
self,
&mut *tx.lock().await,
team_id,
model,
name,
)
.await
})
}
});
let domain_player = lambda(PlayerCreateLambdaArgs {
shirt_next_value,
})
.await?;
let mut res = PgPlayer::insert(&mut *tx.lock().await, team_id, &domain_player).await?;
Arc::try_unwrap(tx).unwrap().into_inner().commit().await?;
Ok(res.into())
}
but I would like to remove the -> Pin<Box<dyn Future<Output = Result<i64>> + Send>>
line, so I did:
async fn player_create<'a>(
&'a self,
team_id: &'a str,
_input: &'a PlayerInput,
lambda: &'a Lambda<'_, PlayerCreateLambdaArgs<'a>, DomainPlayer>,
) -> Result<DomainPlayer> {
let tx = Arc::new(Mutex::new(self.pool.begin().await.unwrap()));
let shirt_next_value = Box::new({
let tx = tx.clone();
move |model: &'a str, name: &'a str| {
let tx = tx.clone();
Box::pin(async move {
self::Shirt::shirt_get_next_and_increase(
self,
&mut *tx.lock().await,
team_id,
model,
name,
)
.await
})
}
});
let domain_player = lambda(PlayerCreateLambdaArgs {
shirt_next_value,
})
.await?;
let mut res = PgPlayer::insert(&mut *tx.lock().await, team_id, &domain_player).await?;
Arc::try_unwrap(tx).unwrap().into_inner().commit().await?;
Ok(res.into())
}
but if I remove it the error is:
error[E0271]: expected `[closure@src\main.rs:40:13: 41:33]` to be a closure that returns `Pin<Box<dyn std::future::Future<Output = Result<i64, common::error::Error>> + std::marker::Send>>`, but it returns `Pin<Box<impl std::future::Future<Output = Result<i64, common::error::Error>>>>`
|
46 | Box::pin(async move {
| _____________________________________-
47 | | self::Shirt::shirt_get_next_and_increase(
48 | | self,
49 | | &mut *tx.lock().await,
... |
54 | | .await
55 | | })
| |_________________- the found `async` block
...
63 | shirt_next_value,
| ^^^^^^^^^^^^^^^^^^^ expected trait object `dyn std::future::Future`, found opaque type
|
72 | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
| ------------------------------- the found opaque type
|
= note: expected struct `Pin<Box<dyn std::future::Future<Output = Result<i64, common::error::Error>> + std::marker::Send>>`
found struct `Pin<Box<impl std::future::Future<Output = Result<i64, common::error::Error>>>>`
= note: required for the cast from `[closure@src\main.rs:40:13: 41:33]` to the object type `dyn FnOnce(&str, &str) -> Pin<Box<dyn std::future::Future<Output = Result<i64, common::error::Error>> + std::marker::Send>> + Sync + std::marker::Send`
Why?
Upvotes: 0
Views: 67
Reputation: 834
The problem can be simplied to the following:
use std::any::Any;
fn test(a: &Box<dyn Any>) {}
fn main() {
let a = Box::new(5);
test(&a);
}
This is due to the fact that the type won't implicitly convert to dynamic dispatch.
You can solve it by specifying the conversion to the type you want.
use std::any::Any;
fn test(a: &Box<dyn Any>) {}
fn main() {
let a = Box::new(5) as _;
test(&a);
}
Upvotes: 1