Skip to content

Async function leads to a "more general type" error #71723

Open
@stephaneyfx

Description

@stephaneyfx

Rustc complains about a type being more general than the other when testing if the Future returned by an async function is Send. The same code without async sugar is accepted by the compiler.

This might be related to #60658.

I tried to minimize further, but removing .flatten(), the boxing with a trait object or even the mapping to an empty stream makes the code compile.

Playground

use futures::{
    future::ready,
    stream::{empty, iter},
    Stream, StreamExt,
};
use std::future::Future;
use std::pin::Pin;

fn is_send<T: Send>(_: T) {}

pub fn test() {
    let _ = is_send(make_future()); // Ok
    let _ = is_send(make_future_2());
}

fn make_future() -> impl Future<Output = ()> {
    iter(Some({
        let s = empty::<()>();
        Box::pin(s) as Pin<Box<dyn Stream<Item = ()> + Send + 'static>>
    }))
    .map(|_| empty::<()>())
    .flatten()
    .for_each(|_| ready(()))
}

// Same as make_future, just async
async fn make_future_2() {
    iter(Some({
        let s = empty::<()>();
        Box::pin(s) as Pin<Box<dyn Stream<Item = ()> + Send + 'static>>
    }))
    .map(|_| empty::<()>())
    .flatten()
    .for_each(|_| ready(()))
    .await
}

Expected result

It compiles successfully -- is_send(make_future()) and is_send(make_future_2()) are both accepted by the compiler.

Actual result

is_send(make_future_2()) is rejected with the following error:

error[E0308]: mismatched types
  --> src/lib.rs:13:13
   |
13 |     let _ = is_send(make_future_2());
   |             ^^^^^^^ one type is more general than the other
   |
   = note: expected type `std::ops::FnOnce<(std::pin::Pin<std::boxed::Box<dyn futures_core::stream::Stream<Item = ()> + std::marker::Send>>,)>`
              found type `std::ops::FnOnce<(std::pin::Pin<std::boxed::Box<dyn futures_core::stream::Stream<Item = ()> + std::marker::Send>>,)>`

Metadata

Metadata

Assignees

Labels

A-async-awaitArea: Async & AwaitA-type-systemArea: Type systemAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.C-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-typesRelevant to the types team, which will review and decide on the PR/issue.

Type

No type

Projects

Status

In progress (current sprint)

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions