Misleading error message when passing a reference to an FnOnce and a non-reference is expected
3ff54ed
Opened by Daniel Wagner-Hall at
Compiling this code:
struct Foo {}
impl Foo {
pub fn foo(&self) -> String {
"foo".to_owned()
}
}
fn main() {
let foo = Foo{};
let closure = move || foo;
call(&closure);
}
fn call<F: FnOnce() -> Foo>(f: F) {
println!("{}", f().foo())
}
error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce`
--> src/main.rs:11:19
|
11 | let closure = move || foo;
| ^^^^^^^^^^^
12 |
13 | call(&closure);
| ---- the requirement to implement `Fn` derives from here
|
note: closure is `FnOnce` because it moves the variable `foo` out of its environment
--> src/main.rs:11:27
|
11 | let closure = move || foo;
| ^^^
call does expect a closure which implements FnOnce, not one which implements Fn as the error message suggests. Accordingly, the line "expected a closure that implements the Fn trait, but this closure only implements FnOnce" is very misleading.
The actual problem here is that a reference to an FnOnce is being passed, rather than the FnOnce itself. It would be great if the error message reflected this fact.
Current output, still incorrect:
error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce` --> src/main.rs:11:19 | 11 | let closure = move || foo; | ^^^^^^^^--- | | | | | closure is `FnOnce` because it moves the variable `foo` out of its environment | this closure implements `FnOnce`, not `Fn` 12 | 13 | call(&closure); | ---- the requirement to implement `Fn` derives from hereEsteban Kuber at 2019-05-23 00:17:05