Skip to content

Conversion of generated future fails, although it should succeed #92929

Description

@oribenshir

I've encountered a weird behavior around generated futures, and the trait bounds it satisfied.
The resulting behavior seems inconsistent.

I tried this code:

let _f1: Pin<Box<dyn Future<Output = bool> + Send + 'static>> = Box::new(async { true }).into();

I expected to see this happen: compilation succeeded.

Instead, this happened: compilation failed due to unsatisfied trait bound.

error[E0277]: the trait bound `Pin<Box<dyn Future<Output = bool> + Send>>: From<Box<impl Future<Output = [async output]>>>` is not satisfied
  --> src\main.rs:55:94
   |
55 |     let _f1: Pin<Box<dyn Future<Output = bool> + Send + 'static>> = Box::new(async { true }).into();
   |                                                                                              ^^^^ the trait `From<Box<impl Future<Output = [async output]>>>` is not implemented for `Pin<Box<dyn Future<Output = bool> + Send>>`
   |
   = help: the following implementations were found:
             <Pin<Box<T, A>> as From<Box<T, A>>>
   = note: required because of the requirements on the impl of `Into<Pin<Box<dyn Future<Output = bool> + Send>>>` for `Box<impl Future<Output = [async output]>>`

I've continued with several other tests, the following two tests compiled successfully:

let _f2: Pin<Box<_>> = Box::<_>::new(async { true }).into();
pub fn pin<T>(x: T) -> Pin<Box<T>>
    where T : Future<Output = bool> + Send + 'static {
    Box::new(x).into()
}

fn main() {
    let _f3: Pin<Box<dyn Future<Output = bool> + Send + 'static>> = pin(async { true });
}

The next test failed again:

let _f4: Box<dyn Future<Output = bool> + Send + 'static> = Box::<dyn Future<Output = bool> + Send + 'static>::new(async { true });

With the following compilation error

error[E0599]: the function or associated item `new` exists for struct `Box<(dyn Future<Output = bool> + Send + 'static)>`, but its trait bounds were not satisfied
  --> src\main.rs:60:115
   |
60 |     let _f4: Box<dyn Future<Output = bool> + Send + 'static> = Box::<dyn Future<Output = bool> + Send + 'static>::new(async { true });
   |                                                                                                                   ^^^ function or associated item cannot be called on `Box<(dyn Future<Output = bool> + Send + 'static)>` due to unsatisfied trait bounds
   |
  ::: C:\Users\oribe\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\future\future.rs:36:1
   |
36 | pub trait Future {
   | ---------------- doesn't satisfy `dyn Future<Output = bool> + Send: Sized`
   |
   = note: the following trait bounds were not satisfied:
           `dyn Future<Output = bool> + Send: Sized`

Background:
I got to this situation while trying to see if I could improve the diagnostic around unpinned futures.

Meta

rustc --version --verbose:

rustc 1.59.0-nightly (cfa3fe5af 2021-12-31)
binary: rustc
commit-hash: cfa3fe5af339e724209b25715282adae0c61628f
commit-date: 2021-12-31
host: x86_64-pc-windows-msvc
release: 1.59.0-nightly
LLVM version: 13.0.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions