Misleading error messages when `AsyncFnMut::CallRefFuture<'_>` mismatches `AsyncFnOnce::CallOnceFuture`
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
Code
fn main() {
let f = async || {};
let fut = if true { f() } else { call_fn_once(f) };
}
fn call_fn_once<Out>(f: impl FnOnce() -> Out) -> Out {
f()
}
Current output
error[E0308]: mismatched types
--> src/lib.rs:3:25
|
2 | let f = async || {};
| --
| |
| the expected `async` closure body
| the found `async` closure body
3 | let fut = if true { f() } else { call_fn_once(f) };
| ^^^ expected `i16`, found `i32`
|
= note: expected `async` closure body `{async closure body@src/lib.rs:2:22: 2:24}` (`i16`)
found `async` closure body `{async closure body@src/lib.rs:2:22: 2:24}` (`i32`)
= note: no two async blocks, even if identical, have the same type
= help: consider pinning your async block and casting it to a trait object
For more information about this error, try `rustc --explain E0308`.
Desired output
Unrelated `i16` or `i32` should not be mentioned. Instead, mentioning the same async closure's `CallRefFuture<'_>` mismatches its `CallOnceFuture`.
Rationale and extra context
No response
Other cases
Rust Version
rustc 1.85.0 (4d91de4e4 2025-02-17)
binary: rustc
commit-hash: 4d91de4e48198da2e33413efdcd9cd2cc0c46688
commit-date: 2025-02-17
host: aarch64-apple-darwin
release: 1.85.0
LLVM version: 19.1.7
Anything else?
For the async closures that doesn't actually lends anything to the returned future (eg. async || {} in the above example), for<'a> Self::CallRefFuture<'a> == Self:: CallOnceFuture is NOT true, as the compiler error indicates. Is this intended?
For async closures, their AsyncFnOnce::CallOnceFuture is exactly FnOnce::Output, as the following code shows. Will it change in the future?
#![feature(async_fn_traits)]
fn test() {
let f = async || {};
let fut = if true {
call_fn_once(f)
} else {
call_async_fn_once(f)
};
}
fn call_fn_once<Out>(f: impl FnOnce() -> Out) -> Out {
f()
}
fn call_async_fn_once<F: AsyncFnOnce()>(f: F) -> F::CallOnceFuture {
f()
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the diagnostic with the provided async-closure example, then trace the call_fn_once and call_async_fn_once entry points through async closure type checking and error reporting. The work is done when the mismatch reports CallRefFuture<'_> versus CallOnceFuture for the same closure without unrelated i16 or i32 types, with relevant compiler tests updated or added.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100