Description
We've just spotted the clone_on_ref_ptr
lint throw up clippy warnings in our code. In an effort to go through and fix them, we realized that is isn't actually always very trivial to do so.
I've had a go at condensing our code down into a minimal repro. It has something to with type inference, and trait objects (e.g. interpreting an Arc
of a struct
as an Arc
of a trait
).
Concrete example: playground
let _z = Bar(y.clone());
fails the clippy lint:
warning: using '.clone()' on a ref-counted pointer
--> src/main.rs:13:18
|
13 | let _z = Bar(y.clone());
| ^^^^^^^^^ help: try this: `Arc::clone(&y)`
|
= note: #[warn(clone_on_ref_ptr)] on by default
= help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.160/index.html#clone_on_ref_ptr
The suggested fix, however, does not compile.
error[E0308]: mismatched types
--> src/main.rs:13:29
|
13 | let _z = Bar(Arc::clone(&y));
| ^^ expected trait Foo, found struct `Bar`
|
= note: expected type `&std::sync::Arc<Foo>`
found type `&std::sync::Arc<Bar>`
One way to actually get this to work, is to provide explicit types (Arc::<Bar>::clone
). However, in real life the struct Bar
might actually have a bunch of generics, which are incredibly tedious to write out (even with underscores) - for example Arc::Bar<_, _, _, _>::clone
.
Why I think this is an issue
In this particular case, the clippy warning is trying to get us to write the clone in a slightly different way, to make it clear that we're cloning an Arc
(cheap). However, that slightly different way doesn't actually compile. This forces us to disable the warning, or jump through several hoops to get some quite inelegant code which satisfies the compiler and clippy.