Closed kaimast closed 3 years ago
This is a rustc bug, and not related to async-trait. You can work around by putting a wrapper struct between the trait object and DashMap.
@@ -7,7 +7,8 @@ trait MyTrait: Send + Sync {
async fn func(&self);
}
-type MapType = DashMap<u64, Arc<dyn MyTrait>>;
+struct ArcMyTrait(Arc<dyn MyTrait>);
+type MapType = DashMap<u64, ArcMyTrait>;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
@@ -15,7 +16,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let fut = tokio::spawn(async move {
for e in mymap.iter() {
- e.value().func().await;
+ e.value().0.func().await;
}
});
For the benefit of anyone searching, I think I've hit the same thing with a rather different error, after upgrading from async-trait
0.1.42 (works fine) to 0.1.43+ (has error below).
I can confirm that the above suggestion of a wrapper type around the Box
works in this case also.
Minimal example:
#[async_trait]
trait AsyncTrait {
async fn trait_fn() -> Result<Box<dyn Deref<Target = [u8]>>, anyhow::Error>;
}
struct S;
#[async_trait]
impl AsyncTrait for S {
async fn trait_fn() -> Result<Box<dyn Deref<Target = [u8]>>, anyhow::Error> {
let _f = std::fs::File::open("/tmp/foo")?;
return Ok(Box::new(&b""[..]));
}
}
Errors:
error[E0308]: mismatched types
--> src/main.rs:12:81
|
12 | async fn trait_fn() -> Result<Box<dyn Deref<Target = [u8]>>, anyhow::Error> {
| _________________________________________________________________________________^
13 | | let _f = std::fs::File::open("/tmp/foo")?;
14 | | return Ok(Box::new(&b""[..]));
15 | | }
| |_____^ expected `&[u8]`, found trait object `dyn std::ops::Deref`
|
= note: expected type `std::result::Result<std::boxed::Box<&[u8]>, _>`
found enum `std::result::Result<std::boxed::Box<dyn std::ops::Deref<Target = [u8]>>, anyhow::Error>`
error[E0271]: type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == std::result::Result<std::boxed::Box<(dyn std::ops::Deref<Target = [u8]> + 'static)>, anyhow::Error>`
--> src/main.rs:12:81
|
12 | async fn trait_fn() -> Result<Box<dyn Deref<Target = [u8]>>, anyhow::Error> {
| _________________________________________________________________________________^
13 | | let _f = std::fs::File::open("/tmp/foo")?;
14 | | return Ok(Box::new(&b""[..]));
15 | | }
| |_____^ expected trait object `dyn std::ops::Deref`, found `&[u8]`
|
= note: expected enum `std::result::Result<std::boxed::Box<(dyn std::ops::Deref<Target = [u8]> + 'static)>, anyhow::Error>`
found enum `std::result::Result<std::boxed::Box<&[u8]>, _>`
= note: required for the cast to the object type `dyn std::future::Future<Output = std::result::Result<std::boxed::Box<(dyn std::ops::Deref<Target = [u8]> + 'static)>, anyhow::Error>> + std::marker::Send`
error: aborting due to 2 previous errors
Hi,
I am trying to store an async trait in a dashmap and get a very cryptic error message. The example below compiles fine with a regular trait but fails to compile with async_trait.
I already filed a bug with dashmap (https://github.com/xacrimon/dashmap/issues/131) but the author is somewhat clueless to what the cause of this could be.
Any help is highly appreciated!
The error message I get is the following: