dtolnay / async-trait

Type erasure for async trait methods
Apache License 2.0
1.84k stars 85 forks source link

Unsize coercion fails if end of method is unreachable #149

Closed dtolnay closed 3 years ago

dtolnay commented 3 years ago

The following async trait fails to compile. Notice that the same method body is fine in an ordinary async fn outside of an async trait.

This worked prior to #143.

use async_trait::async_trait;

struct Thing;
trait Ret {}
impl Ret for Thing {}

async fn ok() -> &'static dyn Ret {
    return &Thing;
}

#[async_trait]
trait Trait {
    async fn fail() -> &'static dyn Ret {
        return &Thing;
    }
}
error[E0308]: mismatched types
  --> src/main.rs:13:41
   |
13 |       async fn fail() -> &'static dyn Ret {
   |  _________________________________________^
14 | |         return &Thing;
15 | |     }
   | |_____^ expected struct `Thing`, found trait object `dyn Ret`
   |
   = note:   expected type `&Thing`
           found reference `&'static (dyn Ret + 'static)`
note: return type inferred to be `&Thing` here
  --> src/main.rs:14:16
   |
14 |         return &Thing;
   |                ^^^^^^

error[E0271]: type mismatch resolving `<impl Future as Future>::Output == &'static (dyn Ret + 'static)`
  --> src/main.rs:13:41
   |
13 |       async fn fail() -> &'static dyn Ret {
   |  _________________________________________^
14 | |         return &Thing;
15 | |     }
   | |_____^ expected trait object `dyn Ret`, found struct `Thing`
   |
   = note: expected reference `&'static (dyn Ret + 'static)`
              found reference `&Thing`
   = note: required for the cast to the object type `dyn Future<Output = &'static (dyn Ret + 'static)> + Send`