Skip to content

impl AsyncFn inference error leaks confusing internal_implementation_detail::AsyncFnKindHelper trait constraint requirement #137905

New issue

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

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

Already on GitHub? # to your account

Closed
parasyte opened this issue Mar 2, 2025 · 3 comments · Fixed by #137910
Assignees
Labels
C-bug Category: This is a bug.

Comments

@parasyte
Copy link

parasyte commented Mar 2, 2025

Minimal repro:

pub fn repro(foo: impl Into<bool>) -> impl AsyncFn() {
    let inner_fn = async move || {
        let _ = foo.into();
    };
    inner_fn
}

Error message:

error[E0277]: the trait bound `i32: ops::async_function::internal_implementation_detail::AsyncFnKindHelper<i8>` is not satisfied
 --> src/lib.rs:1:39
  |
1 | pub fn repro(foo: impl Into<bool>) -> impl AsyncFn() {
  |                                       ^^^^^^^^^^^^^^ the trait `ops::async_function::internal_implementation_detail::AsyncFnKindHelper<i8>` is not implemented for `i32`

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=1417c51240bb454a094b23c524191862

Changing the code to directly return the async closure instead of binding it to a variable produces a more reasonable (but still not ideal) error message:

error[E0507]: cannot move out of `foo` which is behind a shared reference
 --> src/lib.rs:2:5
  |
2 |     async move || {
  |     ^^^^^^^^^^^^^ `foo` is moved here
3 |         let _ = foo.into();
  |                 ---
  |                 |
  |                 variable moved due to use in coroutine
  |                 move occurs because `foo` has type `impl Into<bool>`, which does not implement the `Copy` trait
  |
help: if `impl Into<bool>` implemented `Clone`, you could clone the value
 --> src/lib.rs:1:19
  |
1 | pub fn repro(foo: impl Into<bool>) -> impl AsyncFn() {
  |                   ^^^^^^^^^^^^^^^ consider constraining this type parameter with `Clone`
2 |     async move || {
3 |         let _ = foo.into();
  |                 --- you could clone this value

This issue was originally reported on URLO: https://users.rust-lang.org/t/interesting-issue-with-new-async-closures-with-very-cryptic-error-message/126470

Meta

rustc --version --verbose:

rustc 1.85.0 (4d91de4e4 2025-02-17)
binary: rustc
commit-hash: 4d91de4e48198da2e33413efdcd9cd2cc0c46688
commit-date: 2025-02-17
host: x86_64-pc-windows-msvc
release: 1.85.0
LLVM version: 19.1.7
@parasyte parasyte added the C-bug Category: This is a bug. label Mar 2, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Mar 2, 2025
@traviscross
Copy link
Contributor

cc @compiler-errors

@compiler-errors compiler-errors self-assigned this Mar 3, 2025
jieyouxu added a commit to jieyouxu/rust that referenced this issue Mar 5, 2025
…r, r=oli-obk

Improve error message for `AsyncFn` trait failure for RPIT

Use a `WellFormedDerived` obligation cause to make sure we can turn an `AsyncFnKindHelper` trait goal into its parent `AsyncFn*` goal, then fix the logic for reporting `AsyncFn*` kind mismatches.

Best reviewed without whitespace.

Fixes rust-lang#137905

r? oli-obk
jieyouxu added a commit to jieyouxu/rust that referenced this issue Mar 5, 2025
…r, r=oli-obk

Improve error message for `AsyncFn` trait failure for RPIT

Use a `WellFormedDerived` obligation cause to make sure we can turn an `AsyncFnKindHelper` trait goal into its parent `AsyncFn*` goal, then fix the logic for reporting `AsyncFn*` kind mismatches.

Best reviewed without whitespace.

Fixes rust-lang#137905

r? oli-obk
compiler-errors added a commit to compiler-errors/rust that referenced this issue Mar 6, 2025
…r, r=oli-obk

Improve error message for `AsyncFn` trait failure for RPIT

Use a `WellFormedDerived` obligation cause to make sure we can turn an `AsyncFnKindHelper` trait goal into its parent `AsyncFn*` goal, then fix the logic for reporting `AsyncFn*` kind mismatches.

Best reviewed without whitespace.

Fixes rust-lang#137905

r? oli-obk
Noratrieb added a commit to Noratrieb/rust that referenced this issue Mar 6, 2025
…r, r=oli-obk

Improve error message for `AsyncFn` trait failure for RPIT

Use a `WellFormedDerived` obligation cause to make sure we can turn an `AsyncFnKindHelper` trait goal into its parent `AsyncFn*` goal, then fix the logic for reporting `AsyncFn*` kind mismatches.

Best reviewed without whitespace.

Fixes rust-lang#137905

r? oli-obk
compiler-errors added a commit to compiler-errors/rust that referenced this issue Mar 6, 2025
…r, r=oli-obk

Improve error message for `AsyncFn` trait failure for RPIT

Use a `WellFormedDerived` obligation cause to make sure we can turn an `AsyncFnKindHelper` trait goal into its parent `AsyncFn*` goal, then fix the logic for reporting `AsyncFn*` kind mismatches.

Best reviewed without whitespace.

Fixes rust-lang#137905

r? oli-obk
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Mar 7, 2025
Rollup merge of rust-lang#137910 - compiler-errors:async-fn-goal-error, r=oli-obk

Improve error message for `AsyncFn` trait failure for RPIT

Use a `WellFormedDerived` obligation cause to make sure we can turn an `AsyncFnKindHelper` trait goal into its parent `AsyncFn*` goal, then fix the logic for reporting `AsyncFn*` kind mismatches.

Best reviewed without whitespace.

Fixes rust-lang#137905

r? oli-obk
@traviscross traviscross removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Mar 7, 2025
@dvdsk
Copy link
Contributor

dvdsk commented Apr 25, 2025

I can still cause this (or something similar to it) on the current nightly:
playground: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=2d64a71b89c88ba09f90c4f7911f998c

struct Test;

impl Test {
    async fn an_async_fn(&mut self) {
        todo!()
    }

    pub async fn uses_takes_asyncfn(&mut self) {
        takes_asyncfn(Box::new(async || self.an_async_fn().await));
    }
}

async fn takes_asyncfn(_: impl AsyncFn()) {
    todo!()
}

output:

error[E0277]: the trait bound `i16: ops::async_function::internal_implementation_detail::AsyncFnKindHelper<i8>` is not satisfied in `{async closure@src/lib.rs:9:32: 9:40}`
  --> src/lib.rs:9:23
   |
9  |         takes_asyncfn(Box::new(async || self.an_async_fn().await));
   |         ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound
   |         |
   |         required by a bound introduced by this call
   |
   = help: within `{async closure@src/lib.rs:9:32: 9:40}`, the trait `ops::async_function::internal_implementation_detail::AsyncFnKindHelper<i8>` is not implemented for `i16`
   = note: required for `Box<{async closure@src/lib.rs:9:32: 9:40}>` to implement `AsyncFn()`
note: required by a bound in `takes_asyncfn`
  --> src/lib.rs:13:32
   |
13 | async fn takes_asyncfn(_: impl AsyncFn()) {
   |                                ^^^^^^^^^ required by this bound in `takes_asyncfn`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` (lib) due to 1 previous error

Should I open a new issue?

@compiler-errors
Copy link
Member

Yes, please open a new issue

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
C-bug Category: This is a bug.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants