rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
96.42k stars 12.46k forks source link

Async code causes error "implementation of `FnOnce` is not general enough" when demanding an `impl Send` #126551

Open theemathas opened 2 months ago

theemathas commented 2 months ago

Credit to @Ciel-MC for discovering this.

I tried this code:

use futures::prelude::future::{join_all, FutureExt};

fn foo_is_send() -> impl Send {
    foo()
}

static THING: () = ();

async fn foo() {
    let updates = [async { &THING }.then(|_| async {})];
    join_all(updates).await;
}

I expected the code to compile without errors. Instead, I got the following compile error:

   Compiling playground v0.0.1 (/playground)
error: implementation of `FnOnce` is not general enough
 --> src/lib.rs:4:5
  |
4 |     foo()
  |     ^^^^^ implementation of `FnOnce` is not general enough
  |
  = note: closure with signature `fn(&'0 ()) -> {async block@src/lib.rs:10:46: 10:54}` must implement `FnOnce<(&'1 (),)>`, for any two lifetimes `'0` and `'1`...
  = note: ...but it actually implements `FnOnce<(&(),)>`

error: could not compile `playground` (lib) due to 1 previous error

Possibly related to #126044

See also #126550, which has similar reproduction code.

Meta

Tested on the playground with stable (1.79.0) and nightly (1.81.0-nightly (2024-06-15 3cf924b934322fd7b514))

traviscross commented 1 month ago

@rustbot labels +AsyncAwait-Triaged

We discussed this in the async meeting today. We think this is probably related to: