Skip to content

Bounds on <F as AsyncFnOnce>::CallOnceFuture make the compiler assume CallOnceFuture = () (?) #134015

Closed
@zachs18

Description

@zachs18

I tried this code:

#![allow(warnings)]
#![feature(async_closure, async_fn_traits, unboxed_closures)]
use std::ops::AsyncFnOnce;
use std::future::Future;

trait Anything {}
impl<T: ?Sized> Anything for T {}

fn bar<F>(f: F)
where
    F: AsyncFnOnce() + 'static,
    <F as AsyncFnOnce<()>>::CallOnceFuture: Anything, // comment out this bound for no error
{
    // body not relevant, but this proves that `F::CallOnceFuture` does implement `Future`.
    let _ = async { f().await; };
}

fn main() {
    // error only occurs if `bar` is called
    bar(async move || {});
}

playground link

I expected to see this happen: This should compile successfully; AsyncFnOnce::CallOnceFuture is guaranteed to implement Anything (since there is a blanket impl).

Instead, this happened: The bound appears to cause the compiler to think that F::CallOnceFuture = (), see error message:

error[E0271]: type mismatch resolving `<{async closure@main.rs:19:9} as AsyncFnOnce<()>>::CallOnceFuture == ()`
  --> src/main.rs:19:5
   |
19 |     bar(async move || {});
   |     ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `async` closure body
   |
   = note:         expected unit type `()`
           found `async` closure body `{async closure body@src/main.rs:19:23: 19:25}`

For more information about this error, try `rustc --explain E0271`.
error: could not compile `asyncfnonce-thing` (bin "asyncfnonce-thing") due to 1 previous error

It compiles with no error if:

  • bar is never called
  • or we have an empty bound <F as AsyncFnOnce<()>>::CallOnceFuture: instead of : Anything

It doesn't compile if we have any non-empty bound, e.g. <F as AsyncFnOnce<()>>::CallOnceFuture: Future. (The original issue was someone on discord trying to have a : 'static bound, but I used : Anything in the issue here since it should always be satisfied, and any bound appears to cause the issue).

Meta

rustc --version --verbose:

rustc 1.85.0-nightly (8dc83770f 2024-12-06)
binary: rustc
commit-hash: 8dc83770f748c6cd16b342889ca2240397c19534
commit-date: 2024-12-06
host: x86_64-unknown-linux-gnu
release: 1.85.0-nightly
LLVM version: 19.1.5

(no ICE, so no backtrace)

@rustbot label +F-async_closure +requires-nightly

Metadata

Metadata

Labels

A-async-closures`async || {}`C-bugCategory: This is a bug.T-typesRelevant to the types team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions