Skip to content

Commit

Permalink
Add regression test for issue 232
Browse files Browse the repository at this point in the history
Currently fails to compile:

    error: future cannot be sent between threads safely
        --> tests/test.rs:1506:41
         |
    1506 |         async fn take_ref(&self, _: &T) {}
         |                                         ^^ future created by async block is not `Send`
         |
    note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
        --> tests/test.rs:1506:34
         |
    1504 |     #[async_trait]
         |     -------------- in this procedural macro expansion
    1505 |     impl<T> Generic<T> for One {
    1506 |         async fn take_ref(&self, _: &T) {}
         |                                  ^ has type `&T` which is not `Send`, because `T` is not `Sync`
         = note: required for the cast from `[async block@tests/test.rs:1506:41: 1506:43]` to the object type `dyn futures::Future<Output = ()> + std::marker::Send`
         = note: this error originates in the attribute macro `async_trait` (in Nightly builds, run with -Z macro-backtrace for more info)
    help: consider restricting type parameter `T`
         |
    1505 |     impl<T: std::marker::Sync> Generic<T> for One {
         |           +++++++++++++++++++

    error[E0277]: `T` cannot be shared between threads safely
        --> tests/test.rs:1523:60
         |
    1523 |         async fn take_ref(&self, (_a, _b, _c): &(T, T, T)) {}
         |                                                            ^^ `T` cannot be shared between threads safely
         |
         = note: required because it appears within the type `(T, T, T)`
         = note: required for `&(T, T, T)` to implement `std::marker::Send`
    note: required because it's used within this `async` block
        --> tests/test.rs:1523:60
         |
    1523 |         async fn take_ref(&self, (_a, _b, _c): &(T, T, T)) {}
         |                                                            ^^
         = note: required for the cast from `[async block@tests/test.rs:1523:60: 1523:62]` to the object type `dyn futures::Future<Output = ()> + std::marker::Send`
    help: consider restricting type parameter `T`
         |
    1522 |     impl<T: std::marker::Sync> Generic<(T, T, T)> for Three {
         |           +++++++++++++++++++
  • Loading branch information
dtolnay committed Jan 22, 2023
1 parent d71c74d commit 70bf4b0
Showing 1 changed file with 34 additions and 0 deletions.
34 changes: 34 additions & 0 deletions tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1489,3 +1489,37 @@ pub mod issue226 {
}
}
}

// https://github.com/dtolnay/async-trait/issues/232
pub mod issue232 {
use async_trait::async_trait;

#[async_trait]
pub trait Generic<T> {
async fn take_ref(&self, thing: &T);
}

pub struct One;

#[async_trait]
impl<T> Generic<T> for One {
async fn take_ref(&self, _: &T) {}
}

pub struct Two;

#[async_trait]
impl<T: Sync> Generic<(T, T)> for Two {
async fn take_ref(&self, (a, b): &(T, T)) {
let _ = a;
let _ = b;
}
}

pub struct Three;

#[async_trait]
impl<T> Generic<(T, T, T)> for Three {
async fn take_ref(&self, (_a, _b, _c): &(T, T, T)) {}
}
}

0 comments on commit 70bf4b0

Please sign in to comment.