Skip to content

implementation of Debug is not general enough when making async block into &dyn Future + Send #87425

Open
@Veetaha

Description

@Veetaha

I tried this code:

use std::{any::Any, fmt, future::Future};

pub trait Foo {
    type Item;
}

impl<F, I> Foo for F
where
    Self: FnOnce() -> I,
    I: fmt::Debug,
{
    type Item = I;
}

async fn foo_item<F: Foo>(_: F) -> F::Item {
    unimplemented!()
}

pub fn foo() {
    let fut = async {
        let callback = || -> Box<dyn Any> { unimplemented!() };

        // Using plain fn instead of a closure fixes the error, 
        // though you obviously can't capture any state...
        // fn callback() -> Box<dyn Any> {
        //     todo!()
        // }

        foo_item(callback).await;
    };

    // Removing `+ Send` bound also fixes the error,
    // though at the cost of loosing `Send`ability...
    let fut: &(dyn Future<Output = ()> + Send) = &fut as _;
}

Link to playground

I expected to see this compile.

Instead, this happened:

I've hit the "implementation of Debug is not general enough" when trying to make the async block into a trait object with Send bound.

Compile error output
   Compiling playground v0.0.1 (/playground)
error: implementation of `Debug` is not general enough
  --> src/lib.rs:34:50
   |
34 |     let fut: &(dyn Future<Output = ()> + Send) = &fut as _;
   |                                                  ^^^^ implementation of `Debug` is not general enough
   |
   = note: `(dyn Any + '0)` must implement `Debug`, for any lifetime `'0`...
   = note: ...but `Debug` is actually implemented for the type `(dyn Any + 'static)`

One interesting detail is that this works only with closure syntax, if you use vanilla fn, then there is no error, also removing + Send bound on the resulting trait object removes the error.

Meta

rustc --version --verbose:

rustc 1.53.0 (53cb7b09b 2021-06-17)
binary: rustc
commit-hash: 53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b
commit-date: 2021-06-17
host: x86_64-unknown-linux-gnu
release: 1.53.0
LLVM version: 12.0.1

This is also reproducible in playground with beta and nightly channels:

  • 1.54.0-beta.3 (2021-07-20 3a5d335d1192975c94fc)
  • 1.55.0-nightly (2021-07-22 027187094ee05011d660)

Sorry, I couldn't come up with a more descriptive issue name, if anyone can improve it, I'd be grateful for your edits.

Potentially related issues:

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-async-awaitArea: Async & AwaitA-lifetimesArea: Lifetimes / regionsAsyncAwait-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.WG-asyncWorking group: Async & awaitfixed-by-next-solverFixed by the next-generation trait solver, `-Znext-solver`.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions