-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
clone_on_ref_ptr lint is not always trivial to resolve #2048
Comments
I've got an even more minimal repro: https://play.rust-lang.org/?gist=23bd63e731740d2cd3727ce419979ad5&version=nightly |
I'd personally consider the lint wrong in all cases, and would rather see it removed. It's more annoying to write, and type inference will do The Right Thing anyways. |
Yea we can move it to the restriction lints. |
The reason for writing It's also the recommended by the standard library docs: nical/rust@1b414f5 |
I realize that. What I meant with type inference is that you almost never have to worry that you're actually cloning the internal piece, because if you pass the clone to a function taking
I assume this is a newer recommendation, I don't recall seeing it before. But again, I'd personally disagree with it. |
One thing I have against the lint is that I can create my own structs which implement clone in different ways, shallow (e.g. cloning references such as Suppose
To me, unless the answers to the above questions are both "yes" for a custom struct, I don't see any value in making them "yes" for a standard library struct. Edit 1: The argument for Edit 2: If |
My bad - when I said "it's to make it clear that only the pointer is being cloned, as opposed to the underlying data.", I was referring only to people reading the code, not the compiler itself. The issue isn't that the compiler will do the wrong thing - it's that people reading the code will get an incorrect impression of what it's doing.
I believe the idea behind the recommendation in the docs is that people can be expected to be familiar with the common container/pointer types in the stdlib ( |
So likewise, when dealing with an |
The idea of this line is that it's not always obvious what the type of |
Since I do not see a way that we can detect this case in clippy (inference makes this ridiculously hard), I marked this as an easy issue, since all that needs to be done is move it to the restriction lints and maybe ensure that the suggestion also prints the full types in case traits are involved (which would also print the full thing when no inference happened) |
Hi there, I'm new here and interested in picking this up. Do you have an example for the output you had in mind for printing the full type? Thanks! |
@alusch awesome! I was thinking that we'd get |
Fix #2048: Move `clone_on_ref_ptr` to the restriction lints
**This Commit** Denies the use of `.clone()` on reference counted pointers as advised by [this `clippy` lint][0] and [The Rust Book][1]. It also addresses instances where the lint was violated. **Why?** It's best practice to make clear the clone is cheap. There is [some debate][2] on the issue and the [standard library no longer explicitly recommends it][3] but it is still noted as more idiomatic. In any case, for us there are no issues making the change and if there is a possibility for being more expressive, we should take it. See #6 (comment) for more details. [0]: https://rust-lang.github.io/rust-clippy/master/index.html#clone_on_ref_ptr [1]: https://doc.rust-lang.org/book/ch15-04-rc.html#using-rct-to-share-data [2]: rust-lang/rust-clippy#2048 [3]: rust-lang/rust#76138
**This Commit** Adds history to the functional BST and no longer requires ownership to `insert`/`delete`. **Why?** Mainly to make benchmarking easier but this has the benefit of more closely matching a functional data structure in that, when new trees are created from "mutating" operations, the history of trees/operations is still accessible. Use struct update syntax for conciseness **Why?** I didn't think I could do this but the issue was that I had `derive`d `Clone` on `Node` when I should've implemented it directly because it's generic and leverages reference counting. See #6 (comment) Explicitly clone needed fields of nodes **This Commit** Removes instances of instantiating new `Node`s using the functional update syntax of a clone of an existing `Node`. That is it replaces: ```rust Node { some_field: some_value, ..existing_node.clone() } ``` with ```rust Node { some_field: some_value, other_field: existing_node.other_field.clone(), // etc. } ``` **Why?** For clarity - when using `..node.clone()` what's happening is we are first cloning the node in its entirety (which results in bumping the reference count for all its fields), moving the fields we care about to the new `Node`, and then dropping the remaining fields (and decrementing their reference count). This is a surprise to the reader and is needless and not what we want to express. It also may have a performance impact but that isn't measured. For more details see [this comment thread][0]. [0]: #6 (comment) Deny `clippy::clone_on_ref_ptr` **This Commit** Denies the use of `.clone()` on reference counted pointers as advised by [this `clippy` lint][0] and [The Rust Book][1]. It also addresses instances where the lint was violated. **Why?** It's best practice to make clear the clone is cheap. There is [some debate][2] on the issue and the [standard library no longer explicitly recommends it][3] but it is still noted as more idiomatic. In any case, for us there are no issues making the change and if there is a possibility for being more expressive, we should take it. See #6 (comment) for more details. [0]: https://rust-lang.github.io/rust-clippy/master/index.html#clone_on_ref_ptr [1]: https://doc.rust-lang.org/book/ch15-04-rc.html#using-rct-to-share-data [2]: rust-lang/rust-clippy#2048 [3]: rust-lang/rust#76138
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 astruct
as anArc
of atrait
).Concrete example: playground
let _z = Bar(y.clone());
fails the clippy lint:The suggested fix, however, does not compile.
One way to actually get this to work, is to provide explicit types (
Arc::<Bar>::clone
). However, in real life the structBar
might actually have a bunch of generics, which are incredibly tedious to write out (even with underscores) - for exampleArc::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.The text was updated successfully, but these errors were encountered: