Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
zachs18 opened this issue Dec 7, 2024 · 2 comments · Fixed by #134017
Closed
Assignees
Labels
C-bug Category: This is a bug. F-async_closure `#![feature(async_closure)]` requires-nightly This issue requires a nightly compiler in some way. T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@zachs18
Copy link
Contributor

zachs18 commented Dec 7, 2024

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

@zachs18 zachs18 added the C-bug Category: This is a bug. label Dec 7, 2024
@rustbot rustbot added needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. F-async_closure `#![feature(async_closure)]` requires-nightly This issue requires a nightly compiler in some way. labels Dec 7, 2024
@compiler-errors
Copy link
Member

ill look into it, but ofc it doesn't block stabilizing async closures

@compiler-errors compiler-errors self-assigned this Dec 7, 2024
@compiler-errors
Copy link
Member

This has something to do with fallback and the way that the AsyncFn* traits are implemented in the old trait solver, since this doesn't manifest itself in the new trait solver.

GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this issue Dec 9, 2024
…n, r=jieyouxu

Don't use `AsyncFnOnce::CallOnceFuture` bounds for signature deduction

We shouldn't be using `AsyncFnOnce::CallOnceFuture` projection bounds to deduce anything about the return type of an async closure, **only** `AsyncFnOnce::Output`. This was accidental b/c all we were looking at was the def id of the trait, rather than the projection. This PR fixes that.

This doesn't affect stable code, since `CallOnceFuture` bounds cannot be written on stable.

Fixes rust-lang#134015
jieyouxu added a commit to jieyouxu/rust that referenced this issue Dec 9, 2024
…n, r=jieyouxu

Don't use `AsyncFnOnce::CallOnceFuture` bounds for signature deduction

We shouldn't be using `AsyncFnOnce::CallOnceFuture` projection bounds to deduce anything about the return type of an async closure, **only** `AsyncFnOnce::Output`. This was accidental b/c all we were looking at was the def id of the trait, rather than the projection. This PR fixes that.

This doesn't affect stable code, since `CallOnceFuture` bounds cannot be written on stable.

Fixes rust-lang#134015
jieyouxu added a commit to jieyouxu/rust that referenced this issue Dec 9, 2024
…n, r=jieyouxu

Don't use `AsyncFnOnce::CallOnceFuture` bounds for signature deduction

We shouldn't be using `AsyncFnOnce::CallOnceFuture` projection bounds to deduce anything about the return type of an async closure, **only** `AsyncFnOnce::Output`. This was accidental b/c all we were looking at was the def id of the trait, rather than the projection. This PR fixes that.

This doesn't affect stable code, since `CallOnceFuture` bounds cannot be written on stable.

Fixes rust-lang#134015
fmease added a commit to fmease/rust that referenced this issue Dec 9, 2024
…n, r=jieyouxu

Don't use `AsyncFnOnce::CallOnceFuture` bounds for signature deduction

We shouldn't be using `AsyncFnOnce::CallOnceFuture` projection bounds to deduce anything about the return type of an async closure, **only** `AsyncFnOnce::Output`. This was accidental b/c all we were looking at was the def id of the trait, rather than the projection. This PR fixes that.

This doesn't affect stable code, since `CallOnceFuture` bounds cannot be written on stable.

Fixes rust-lang#134015
fmease added a commit to fmease/rust that referenced this issue Dec 10, 2024
…n, r=jieyouxu

Don't use `AsyncFnOnce::CallOnceFuture` bounds for signature deduction

We shouldn't be using `AsyncFnOnce::CallOnceFuture` projection bounds to deduce anything about the return type of an async closure, **only** `AsyncFnOnce::Output`. This was accidental b/c all we were looking at was the def id of the trait, rather than the projection. This PR fixes that.

This doesn't affect stable code, since `CallOnceFuture` bounds cannot be written on stable.

Fixes rust-lang#134015
@saethlin saethlin added T-types Relevant to the types team, which will review and decide on the PR/issue. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Dec 10, 2024
@bors bors closed this as completed in 193a95d Dec 10, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Dec 10, 2024
Rollup merge of rust-lang#134017 - compiler-errors:call-once-deduction, r=jieyouxu

Don't use `AsyncFnOnce::CallOnceFuture` bounds for signature deduction

We shouldn't be using `AsyncFnOnce::CallOnceFuture` projection bounds to deduce anything about the return type of an async closure, **only** `AsyncFnOnce::Output`. This was accidental b/c all we were looking at was the def id of the trait, rather than the projection. This PR fixes that.

This doesn't affect stable code, since `CallOnceFuture` bounds cannot be written on stable.

Fixes rust-lang#134015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. F-async_closure `#![feature(async_closure)]` requires-nightly This issue requires a nightly compiler in some way. T-types Relevant to the types team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants