Clippy lints / Suspicious
Clippy lint · Suspicious · checked with Clippy 0.1.99
clippy::non_canonical_clone_impl: non-canonical implementation of `clone` on a `Copy` type
What it meansChecks for non-canonical implementations of Clone when Copy is already implemented. It is in the suspicious group and warns by default.
What you see
warning: non-canonical implementation of `clone` on a `Copy` type --> main.rs:7:29 | 7 | fn clone(&self) -> Self { | _____________________________^ 8 | | Self(self.0) 9 | | } | |_____^ help: change this to: `{ *self }` | = help: for further information visit https://rust-lang.github.io/rust-clippy/stable/index.html#non_canonical_clone_impl = note: `#[warn(clippy::non_canonical_clone_impl)]` on by default
Real output of Clippy 0.1.99 (Rust 1.99) on the example below. Names and line numbers in yours will differ.
Does it matter?
If both Clone and Copy are implemented, they must agree. This can done by dereferencing self in Clone’s implementation, which will avoid any possibility of the implementations becoming out of sync.
Code that is most likely wrong or useless. Warns by default.
How to fix it
Clippy does not fix this one automatically (its suggestion may change behaviour, so it only shows it). Change the code by hand:
Flagged
#[derive(Eq, PartialEq)]
struct A(u32);
impl Clone for A {
fn clone(&self) -> Self {
Self(self.0)
}
}
impl Copy for A {}
Write this instead
#[derive(Eq, PartialEq)]
struct A(u32);
impl Clone for A {
fn clone(&self) -> Self {
*self
}
}
impl Copy for A {}
Turn it off, or on
Allow it where it does not fit your code, as narrowly as you can:
On one item
#[allow(clippy::non_canonical_clone_impl)]
fn my_function() { /* ... */ }Whole crate (Cargo.toml)
[lints.clippy]
non_canonical_clone_impl = "allow"One run
cargo clippy -- -A clippy::non-canonical-clone-implThe [lints] table needs Rust 1.74 or newer. In a workspace, put it under [workspace.lints.clippy] and add [lints] workspace = true to each member.
Clippy's own documentation
What it does
Checks for non-canonical implementations of Clone when Copy is already implemented.
Why is this bad?
If both Clone and Copy are implemented, they must agree. This can done by dereferencing
self in Clone’s implementation, which will avoid any possibility of the implementations
becoming out of sync.
Example
#[derive(Eq, PartialEq)]
struct A(u32);
impl Clone for A {
fn clone(&self) -> Self {
Self(self.0)
}
}
impl Copy for A {}
Use instead:
#[derive(Eq, PartialEq)]
struct A(u32);
impl Clone for A {
fn clone(&self) -> Self {
*self
}
}
impl Copy for A {}
Past names
- incorrect_clone_impl_on_copy_type
From the Clippy lint list (0.1.99), part of the Rust project, MIT or Apache-2.0. Official entry.
Related lints
- needless_character_iterationchecking if a string is ascii using iterators
- needless_maybe_sized`?Sized` bound is ignored because of a `Sized` requirement
- no_effect_replacereplacing text with itself
- non_canonical_partial_ord_implChecks for non-canonical implementations of PartialOrd when Ord is already implemented
- octal_escapesoctal-looking escape in a literal
- path_ends_with_extLooks for calls to Path::ends_with calls where the argument looks like a file extension. By default, Clippy has a short list of known filenames that start with a dot but aren’t necessarily file extensions (e.g
All 847 Clippy lints · Rust compiler errors · Cargo.toml checker
Up next
Related lintclippy::needless_character_iterationchecking if a string is ascii using iteratorsRead it next →Did this answer your question?