Closed
Description
Given the following code: (playground)
fn takes_fn(f: impl Fn()) {
takes_fnonce(f);
takes_fnonce(f);
}
fn takes_fnmut(f: impl FnMut()) {
takes_fnonce(f);
takes_fnonce(f);
}
// Could also be Fn[Mut], here it doesn't matter
fn takes_fnonce(_: impl FnOnce()) {}
The current output is:
error[E0382]: use of moved value: `f`
--> src/lib.rs:3:18
|
1 | fn takes_fn(f: impl Fn()) {
| - move occurs because `f` has type `impl Fn()`, which does not implement the `Copy` trait
2 | takes_fnonce(f);
| - value moved here
3 | takes_fnonce(f);
| ^ value used here after move
|
help: consider further restricting this bound
|
1 | fn takes_fn(f: impl Fn() + Copy) {
| ++++++
error[E0382]: use of moved value: `f`
--> src/lib.rs:8:18
|
6 | fn takes_fnmut(f: impl FnMut()) {
| - move occurs because `f` has type `impl FnMut()`, which does not implement the `Copy` trait
7 | takes_fnonce(f);
| - value moved here
8 | takes_fnonce(f);
| ^ value used here after move
|
help: consider further restricting this bound
|
6 | fn takes_fnmut(f: impl FnMut() + Copy) {
| ++++++
While suggestions make the code compile, they restrict the arguments. This can be avoided by borrowing functions instead.
Ideally, the output should look like this:
error[E0382]: use of moved value: `f`
--> src/lib.rs:3:18
|
1 | fn takes_fn(f: impl Fn()) {
| - move occurs because `f` has type `impl Fn()`, which does not implement the `Copy` trait
2 | takes_fnonce(f);
| - value moved here
3 | takes_fnonce(f);
| ^ value used here after move
|
help: consider borrowing `f`
|
2 | takes_fnonce(&f);
| +
error[E0382]: use of moved value: `f`
--> src/lib.rs:8:18
|
6 | fn takes_fnmut(f: impl FnMut()) {
| - move occurs because `f` has type `impl FnMut()`, which does not implement the `Copy` trait
7 | takes_fnonce(f);
| - value moved here
8 | takes_fnonce(f);
| ^ value used here after move
|
help: consider borrowing `f`
|
7 | takes_fnonce(&mut f);
| ++++
For the record, here is an example found "in the wild" where I noticed the problem: (playground)