Skip to content

"one type is more general than the other" and "implementation of FnOnce is not general enough" errors for !Send future #145094

@tyilo

Description

@tyilo

Code

// v7.6.3
use futures_concurrency::prelude::*;

async fn f() {
    async fn map_f(msg: &str) -> String {
        format!("hello {msg}")
    }

    let v: Vec<_> = vec!["chashu", "nori"]
        .into_co_stream()
        .map(|msg| map_f(msg))
        .collect()
        .await;
    println!("{v:?}");
}

const fn assert_send_future<T: Future + Send>(_: &T) {}

fn main() {
    assert_send_future(&f());
}

Current output

error[E0308]: mismatched types
  --> src/main.rs:19:5
   |
19 |     assert_send_future(&f());
   |     ^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
   |
   = note: expected reference `&_`
              found reference `&_`
note: the lifetime requirement is introduced here
  --> src/main.rs:16:41
   |
16 | const fn assert_send_future<T: Future + Send>(_: &T) {}
   |                                         ^^^^

error[E0308]: mismatched types
  --> src/main.rs:19:5
   |
19 |     assert_send_future(&f());
   |     ^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
   |
   = note: expected struct `std::future::Ready<&_>`
              found struct `std::future::Ready<&_>`
note: the lifetime requirement is introduced here
  --> src/main.rs:16:41
   |
16 | const fn assert_send_future<T: Future + Send>(_: &T) {}
   |                                         ^^^^

error: implementation of `FnOnce` is not general enough
  --> src/main.rs:19:5
   |
19 |     assert_send_future(&f());
   |     ^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
   |
   = note: closure with signature `fn(&'0 str) -> impl Future<Output = String>` must implement `FnOnce<(&'1 str,)>`, for any two lifetimes `'0` and `'1`...
   = note: ...but it actually implements `FnOnce<(&str,)>`

error[E0308]: mismatched types
  --> src/main.rs:19:5
   |
19 |     assert_send_future(&f());
   |     ^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
   |
   = note: expected opaque type `impl Future<Output = String>`
              found opaque type `impl Future<Output = String>`
   = note: distinct uses of `impl Trait` result in different opaque types
note: the lifetime requirement is introduced here
  --> src/main.rs:16:41
   |
16 | const fn assert_send_future<T: Future + Send>(_: &T) {}
   |                                         ^^^^

For more information about this error, try `rustc --explain E0308`.
error: could not compile `test-futures-concurrency` (bin "test-futures-concurrency") due to 4 previous errors

Desired output

future returned by `f` is not `Send`

Rationale and extra context

Should probably be part of #110338

Other cases

Rust Version

$ rustc --version --verbose
rustc 1.89.0 (29483883e 2025-08-04)
binary: rustc
commit-hash: 29483883eed69d5fb4db01964cdf2af4d86e9cb2
commit-date: 2025-08-04
host: x86_64-unknown-linux-gnu
release: 1.89.0
LLVM version: 20.1.7

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsT-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