fn fn_once<F>(func: F)
where
F: FnOnce(usize) -> bool,
{
println!("{}", func(3));
println!("{}", func(4));
}
fn main() {
let x = 3;
fn_once(|z| z == x)
}
The above code reports an error error[E0382]: use of moved value: func.
The error disappears after adding the Copy trait constraint:
fn fn_once<F>(func: F)
where
F: FnOnce(usize) -> bool + Copy,
{
println!("{}", func(3));
println!("{}", func(4));
}
fn main() {
let x = 3;
fn_once(|z| z == x)
}
My doubt is: Is this Copy trait automatically derived because I specified trait bound? Or is it that the closure itself has always had the Copy trait, and it only takes effect after specifying the Copy bound?
I want to know what the mechanism behind this is.
>Solution :
Closures that only capture Copy types automatically implement Copy.
But Rust generics are definition-checked. It doesn’t matter how you call it (in fact, you would get the error even when compiling fn_once alone, without any callers). The signature of the function must be enough to allow the usage of everything inside. So unless you specify Copy, the compiler will assume that the type will not be Copy and check the code accordingly.
That said, a FnOnce is meant to be called once, it’s in the name! To also specify Copy so that you can use it multiple times is rather nonsensical. Instead, you should change FnOnce to Fn.