dtolnay / async-trait

Type erasure for async trait methods
Apache License 2.0
1.81k stars 84 forks source link

Forgetting "dyn" before Fn() + Trait causes panic #89

Closed thanatos closed 4 years ago

thanatos commented 4 years ago

In non-async-trait code, this is currently legal, though it emits a warning that it should have the dyn keyword:

impl<F> Foo for Fn(i8) -> F + Send + Sync
  where F: ... {}

In async-trait code, this causes a panic:

#[async_trait::async_trait]
impl<F> RequestHandler for Fn(&Request) -> F + Send + Sync
  where F: ... {}
error: custom attribute panicked
  --> src/lib.rs:15:1
   |
15 | #[async_trait::async_trait]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = help: message: unexpected token

A full example in the Playground

I'm not sure whether the code should be accepted, given that the current compiler warns that the impl w/o the dyn is deprecated, but I figure async_trait might want to either accept w/ a similar warning, or at the very least reject with a clearer error message.

(I mostly stumbled into this; I do not think the impl is anything close to what I actually want in my real-world use case. The compiler's insistence on dyn is nice though, since it clued me in that I'm barking up the wrong syntactical tree.)

dtolnay commented 4 years ago

Minimized:

use async_trait::async_trait;

#[async_trait]
trait Trait {
    async fn f(&self);
}

#[async_trait]
impl Trait for Send + Sync {
    async fn f(&self) {}
}
dtolnay commented 4 years ago

Fixed in 0.1.30.

thanatos commented 4 years ago

Wow that was fast! Also, thank you for an excellent library!