In this very contrived code:
fn main() {
let duration = &std::time::Duration::from_secs(1);
consume(duration.clone());
println!("Duration in main: {:?}", duration);
}
fn consume(duration: std::time::Duration) {
println!("Duration in consume: {:?}", duration);
}
Clippy gives a warning:
warning: using `clone` on a `Copy` type
--> src/main.rs:3:13
|
3 | consume(duration.clone());
| ^^^^^^^^^^^^^^^^ help: try dereferencing it: `*duration`
|
= note: #[warn(clone_on_copy)] on by default
= help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.207/index.html#clone_on_copy
I'm not sure this is a good recommendation. Using .clone() makes it obvious that the work is happening, whereas the mental jumps of "I'm dereferencing, which means that my type can be copied, and that copy will be moved" are less obvious. In particular, when I explained to someone just starting out with Rust that these were the two ways of fixing the compile error they ran into, their conclusion was that calling .clone() is better self-documenting code than calling *.
I'm in general fine with the clone_on_copy lint, but I feel like it should specifically be disabled for cases where the suggestion is to dereference. Is there a compelling reason that the above code is _worse_ than the suggested alternative? What do others think?
To me, an explicit use of clone always suggests there's something nontrivial going on. If you call a method on a copy type which takes it by value, you also get a copy without first cloning. A dereference shows you that a cheap operation is happening
Most helpful comment
To me, an explicit use of clone always suggests there's something nontrivial going on. If you call a method on a copy type which takes it by value, you also get a copy without first cloning. A dereference shows you that a cheap operation is happening