Open
Description
I tried this code:
fn demo<F: FnOnce()>(f: F) -> F { f }
fn other<F: Fn()>(_f: F) {}
fn main() {
let x = || ();
other(x);
let x = demo(|| ());
other(x);
}
I expected to see this happen: The code to compile.
Instead, this happened: Compilation failed stating the second x
does not implement Fn
.
error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce`
--> src/main.rs:9:18
|
9 | let x = demo(|| ());
| ^^ this closure implements `FnOnce`, not `Fn`
10 | other(x);
| ----- - the requirement to implement `Fn` derives from here
| |
| required by a bound introduced by this call
|
note: required by a bound in `other`
--> src/main.rs:3:13
|
3 | fn other<F: Fn()>(_f: F) {}
| ^^^^ required by this bound in `other`
I would expect this to either compile fine (which means changing something about how closure coercion works) or for the diagnostic given to point at the coercion to a FnOnce
for the reason why it doesn't implement the Fn
trait.
Meta
rustc --version --verbose
:
rustc 1.80.1 (3f5fd8dd4 2024-08-06)
binary: rustc
commit-hash: 3f5fd8dd41153bc5fdca9427e9e05be2c767ba23
commit-date: 2024-08-06
host: x86_64-unknown-linux-gnu
release: 1.80.1
LLVM version: 18.1.7