Skip to content

suggestion that &T requires Sync to be Send could be clearer #86507

Closed

Description

@nikomatsakis

Given the following code: playground

use async_trait::async_trait; // 0.1.50
use serde::Serialize;

#[async_trait]
trait Foo {
    async fn bar(x: &(impl Serialize + Send));
}

#[async_trait]
impl Foo for () {
    async fn bar(x: &(impl Serialize + Send)) {
    }
}

fn main() { }

The current output is:

error: future cannot be sent between threads safely
  --> src/main.rs:11:47
   |
11 |       async fn bar(x: &(impl Serialize + Send)) {
   |  _______________________________________________^
12 | |     }
   | |_____^ future created by async block is not `Send`
   |
note: captured value is not `Send`
  --> src/main.rs:11:18
   |
11 |     async fn bar(x: &(impl Serialize + Send)) {
   |                  ^ has type `&impl Serialize + Send` which is not `Send`
   = note: required for the cast to the object type `dyn Future<Output = ()> + Send`
help: consider further restricting this bound
   |
11 |     async fn bar(x: &(impl Serialize + Send + std::marker::Sync)) {
   |                                             ^^^^^^^^^^^^^^^^^^^

The compiler helpfully points out that Sync is required, but nonetheless @chazkiker2 and I both got confused by this error for some time before we noticed it. The suggestion was kind of buried by all the other details.

Activity

  1. added
    A-diagnosticsArea: Messages for errors, warnings, and lints
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Jun 21, 2021
  2. nikomatsakis commented on Jun 21, 2021

    @nikomatsakis
    ContributorAuthor

    I'm not sure the ideal output, but it might be something like this:

    error: future cannot be sent between threads safely
      --> src/main.rs:11:47
       |
    11 |       async fn bar(x: &(impl Serialize + Send)) {
       |  _______________________________________________^
    12 | |     }
       | |_____^ future created by async block is not `Send`
       |
    note: `&` references cannot be sent unless their referent is `Sync`
      --> src/main.rs:11:18
       |
    11 |     async fn bar(x: &(impl Serialize + Send)) {
       |                  ^ refers to `impl Serialize + Send` which is not `Sync`
       = note: required for the cast to the object type `dyn Future<Output = ()> + Send`
    help: consider further restricting this bound
       |
    11 |     async fn bar(x: &(impl Serialize + Send + std::marker::Sync)) {
       |                                             ^^^^^^^^^^^^^^^^^^^
    
  3. added
    C-enhancementCategory: An issue proposing an enhancement or a PR with one.
    D-confusingDiagnostics: Confusing error or lint that should be reworked.
    on Jun 21, 2021
  4. added
    AsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.
    on Jun 25, 2021
  5. chazkiker2 commented on Jul 20, 2021

    @chazkiker2
    Contributor

    This error can be replicated without any external crates (i.e., without #[async_trait]) like so:

    Link to Playground

    use ::core::pin::Pin;
    use ::core::future::Future;
    use ::core::marker::Send;
    
    trait Foo {
        fn bar<'me, 'async_trait, T: Send>(x: &'me T)
            -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
            where 'me: 'async_trait;
    }
    
    impl Foo for () {
        fn bar<'me, 'async_trait, T: Send>(x: &'me T)
            -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
            where 'me: 'async_trait {
                Box::pin(
                    async move {
                        let x = x;
                    }
                )
             }
    }
    
    fn main() { }
  6. added 2 commits that reference this issue on Jul 23, 2021
    d089e27
    3fc79fd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-async-awaitArea: Async & AwaitA-diagnosticsArea: Messages for errors, warnings, and lintsAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.C-enhancementCategory: An issue proposing an enhancement or a PR with one.D-confusingDiagnostics: Confusing error or lint that should be reworked.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions