Skip to content

Commit 10cc168

Browse files
committed
rename lint and disallow clone_from
1 parent 67d5e6e commit 10cc168

12 files changed

+145
-39
lines changed

CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -4833,6 +4833,7 @@ Released 2018-09-13
48334833
[`imprecise_flops`]: https://rust-lang.github.io/rust-clippy/master/index.html#imprecise_flops
48344834
[`inconsistent_digit_grouping`]: https://rust-lang.github.io/rust-clippy/master/index.html#inconsistent_digit_grouping
48354835
[`inconsistent_struct_constructor`]: https://rust-lang.github.io/rust-clippy/master/index.html#inconsistent_struct_constructor
4836+
[`incorrect_clone_impl_on_copy_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#incorrect_clone_impl_on_copy_type
48364837
[`index_refutable_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice
48374838
[`indexing_slicing`]: https://rust-lang.github.io/rust-clippy/master/index.html#indexing_slicing
48384839
[`ineffective_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#ineffective_bit_mask
@@ -5005,7 +5006,6 @@ Released 2018-09-13
50055006
[`needless_bool_assign`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_bool_assign
50065007
[`needless_borrow`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow
50075008
[`needless_borrowed_reference`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrowed_reference
5008-
[`needless_clone_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_clone_impl
50095009
[`needless_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_collect
50105010
[`needless_continue`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_continue
50115011
[`needless_doctest_main`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_doctest_main

clippy_lints/src/declared_lints.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
206206
crate::implicit_saturating_add::IMPLICIT_SATURATING_ADD_INFO,
207207
crate::implicit_saturating_sub::IMPLICIT_SATURATING_SUB_INFO,
208208
crate::inconsistent_struct_constructor::INCONSISTENT_STRUCT_CONSTRUCTOR_INFO,
209+
crate::incorrect_impls::INCORRECT_CLONE_IMPL_ON_COPY_TYPE_INFO,
209210
crate::index_refutable_slice::INDEX_REFUTABLE_SLICE_INFO,
210211
crate::indexing_slicing::INDEXING_SLICING_INFO,
211212
crate::indexing_slicing::OUT_OF_BOUNDS_INDEXING_INFO,
@@ -463,7 +464,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
463464
crate::needless_else::NEEDLESS_ELSE_INFO,
464465
crate::needless_for_each::NEEDLESS_FOR_EACH_INFO,
465466
crate::needless_if::NEEDLESS_IF_INFO,
466-
crate::needless_impls::NEEDLESS_CLONE_IMPL_INFO,
467467
crate::needless_late_init::NEEDLESS_LATE_INIT_INFO,
468468
crate::needless_parens_on_range_literals::NEEDLESS_PARENS_ON_RANGE_LITERALS_INFO,
469469
crate::needless_pass_by_value::NEEDLESS_PASS_BY_VALUE_INFO,

clippy_lints/src/needless_impls.rs renamed to clippy_lints/src/incorrect_impls.rs

+31-16
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,13 @@ declare_clippy_lint! {
4242
/// impl Copy for A {}
4343
/// ```
4444
#[clippy::version = "1.72.0"]
45-
pub NEEDLESS_CLONE_IMPL,
45+
pub INCORRECT_CLONE_IMPL_ON_COPY_TYPE,
4646
correctness,
4747
"manual implementation of `Clone` on a `Copy` type"
4848
}
49-
declare_lint_pass!(NeedlessImpls => [NEEDLESS_CLONE_IMPL]);
49+
declare_lint_pass!(IncorrectImpls => [INCORRECT_CLONE_IMPL_ON_COPY_TYPE]);
5050

51-
impl LateLintPass<'_> for NeedlessImpls {
51+
impl LateLintPass<'_> for IncorrectImpls {
5252
#[expect(clippy::needless_return)]
5353
fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &ImplItem<'_>) {
5454
let node = get_parent_node(cx.tcx, impl_item.hir_id());
@@ -77,7 +77,6 @@ impl LateLintPass<'_> for NeedlessImpls {
7777

7878
// Actual implementation; remove this comment once aforementioned PR is merged
7979
if cx.tcx.is_diagnostic_item(sym::Clone, trait_impl_def_id)
80-
&& impl_item.ident.name == sym::clone
8180
&& let Some(copy_def_id) = cx.tcx.get_diagnostic_item(sym::Copy)
8281
&& implements_trait(
8382
cx,
@@ -86,20 +85,36 @@ impl LateLintPass<'_> for NeedlessImpls {
8685
trait_impl.substs,
8786
)
8887
{
89-
if block.stmts.is_empty()
90-
&& let Some(expr) = block.expr
91-
&& let ExprKind::Unary(UnOp::Deref, inner) = expr.kind
92-
&& let ExprKind::Path(qpath) = inner.kind
93-
&& last_path_segment(&qpath).ident.name == symbol::kw::SelfLower
94-
{} else {
88+
if impl_item.ident.name == sym::clone {
89+
if block.stmts.is_empty()
90+
&& let Some(expr) = block.expr
91+
&& let ExprKind::Unary(UnOp::Deref, inner) = expr.kind
92+
&& let ExprKind::Path(qpath) = inner.kind
93+
&& last_path_segment(&qpath).ident.name == symbol::kw::SelfLower
94+
{} else {
95+
span_lint_and_sugg(
96+
cx,
97+
INCORRECT_CLONE_IMPL_ON_COPY_TYPE,
98+
block.span,
99+
"incorrect implementation of `clone` on a `Copy` type",
100+
"change this to",
101+
"{ *self }".to_owned(),
102+
Applicability::MaybeIncorrect,
103+
);
104+
105+
return;
106+
}
107+
}
108+
109+
if impl_item.ident.name == sym::clone_from {
95110
span_lint_and_sugg(
96111
cx,
97-
NEEDLESS_CLONE_IMPL,
98-
block.span,
99-
"manual implementation of `Clone` on a `Copy` type",
100-
"change this to",
101-
"{ *self }".to_owned(),
102-
Applicability::Unspecified,
112+
INCORRECT_CLONE_IMPL_ON_COPY_TYPE,
113+
impl_item.span,
114+
"incorrect implementation of `clone_from` on a `Copy` type",
115+
"remove this",
116+
String::new(),
117+
Applicability::MaybeIncorrect,
103118
);
104119

105120
return;

clippy_lints/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ mod implicit_return;
150150
mod implicit_saturating_add;
151151
mod implicit_saturating_sub;
152152
mod inconsistent_struct_constructor;
153+
mod incorrect_impls;
153154
mod index_refutable_slice;
154155
mod indexing_slicing;
155156
mod infinite_iter;
@@ -226,7 +227,6 @@ mod needless_continue;
226227
mod needless_else;
227228
mod needless_for_each;
228229
mod needless_if;
229-
mod needless_impls;
230230
mod needless_late_init;
231231
mod needless_parens_on_range_literals;
232232
mod needless_pass_by_value;
@@ -1048,7 +1048,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
10481048
let stack_size_threshold = conf.stack_size_threshold;
10491049
store.register_late_pass(move |_| Box::new(large_stack_frames::LargeStackFrames::new(stack_size_threshold)));
10501050
store.register_late_pass(|_| Box::new(single_range_in_vec_init::SingleRangeInVecInit));
1051-
store.register_late_pass(|_| Box::new(needless_impls::NeedlessImpls));
1051+
store.register_late_pass(|_| Box::new(incorrect_impls::IncorrectImpls));
10521052
// add lints here, do not remove this comment, it's used in `new_lint`
10531053
}
10541054

tests/ui/clone_on_copy_impl.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![allow(clippy::needless_clone_impl)]
1+
#![allow(clippy::incorrect_clone_impl_on_copy_type)]
22

33
use std::fmt;
44
use std::marker::PhantomData;

tests/ui/derive.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![allow(clippy::needless_clone_impl, dead_code)]
1+
#![allow(clippy::incorrect_clone_impl_on_copy_type, dead_code)]
22
#![warn(clippy::expl_impl_clone_on_copy)]
33

44
#[derive(Copy)]

tests/ui/needless_clone_impl.fixed renamed to tests/ui/incorrect_clone_impl_on_copy_type.fixed

+29-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//@run-rustfix
2-
#![allow(unused)]
2+
#![allow(clippy::clone_on_copy, unused)]
33
#![no_main]
44

55
// lint
@@ -8,6 +8,8 @@ struct A(u32);
88

99
impl Clone for A {
1010
fn clone(&self) -> Self { *self }
11+
12+
1113
}
1214

1315
impl Copy for A {}
@@ -38,6 +40,11 @@ impl Clone for D {
3840
fn clone(&self) -> Self {
3941
Self(self.0)
4042
}
43+
44+
fn clone_from(&mut self, source: &Self) {
45+
source.clone();
46+
*self = source.clone();
47+
}
4148
}
4249

4350
impl Copy for D {}
@@ -51,10 +58,26 @@ impl Clone for E {
5158
fn clone(&self) -> Self {
5259
Self(self.0)
5360
}
61+
62+
fn clone_from(&mut self, source: &Self) {
63+
source.clone();
64+
*self = source.clone();
65+
}
5466
}
5567

5668
impl Copy for E {}
5769

70+
// lint since clone is not derived
71+
72+
#[derive(Copy)]
73+
struct F(u32);
74+
75+
impl Clone for F {
76+
fn clone(&self) -> Self { *self }
77+
78+
79+
}
80+
5881
// do not lint since copy has more restrictive bounds
5982

6083
#[derive(Eq, PartialEq)]
@@ -64,6 +87,11 @@ impl<A: Copy> Clone for Uwu<A> {
6487
fn clone(&self) -> Self {
6588
Self(self.0)
6689
}
90+
91+
fn clone_from(&mut self, source: &Self) {
92+
source.clone();
93+
*self = source.clone();
94+
}
6795
}
6896

6997
impl<A: std::fmt::Debug + Copy + Clone> Copy for Uwu<A> {}

tests/ui/needless_clone_impl.rs renamed to tests/ui/incorrect_clone_impl_on_copy_type.rs

+37-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//@run-rustfix
2-
#![allow(unused)]
2+
#![allow(clippy::clone_on_copy, unused)]
33
#![no_main]
44

55
// lint
@@ -10,6 +10,11 @@ impl Clone for A {
1010
fn clone(&self) -> Self {
1111
Self(self.0)
1212
}
13+
14+
fn clone_from(&mut self, source: &Self) {
15+
source.clone();
16+
*self = source.clone();
17+
}
1318
}
1419

1520
impl Copy for A {}
@@ -40,6 +45,11 @@ impl Clone for D {
4045
fn clone(&self) -> Self {
4146
Self(self.0)
4247
}
48+
49+
fn clone_from(&mut self, source: &Self) {
50+
source.clone();
51+
*self = source.clone();
52+
}
4353
}
4454

4555
impl Copy for D {}
@@ -53,10 +63,31 @@ impl Clone for E {
5363
fn clone(&self) -> Self {
5464
Self(self.0)
5565
}
66+
67+
fn clone_from(&mut self, source: &Self) {
68+
source.clone();
69+
*self = source.clone();
70+
}
5671
}
5772

5873
impl Copy for E {}
5974

75+
// lint since clone is not derived
76+
77+
#[derive(Copy)]
78+
struct F(u32);
79+
80+
impl Clone for F {
81+
fn clone(&self) -> Self {
82+
Self(self.0)
83+
}
84+
85+
fn clone_from(&mut self, source: &Self) {
86+
source.clone();
87+
*self = source.clone();
88+
}
89+
}
90+
6091
// do not lint since copy has more restrictive bounds
6192

6293
#[derive(Eq, PartialEq)]
@@ -66,6 +97,11 @@ impl<A: Copy> Clone for Uwu<A> {
6697
fn clone(&self) -> Self {
6798
Self(self.0)
6899
}
100+
101+
fn clone_from(&mut self, source: &Self) {
102+
source.clone();
103+
*self = source.clone();
104+
}
69105
}
70106

71107
impl<A: std::fmt::Debug + Copy + Clone> Copy for Uwu<A> {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
error: incorrect implementation of `clone` on a `Copy` type
2+
--> $DIR/incorrect_clone_impl_on_copy_type.rs:10:29
3+
|
4+
LL | fn clone(&self) -> Self {
5+
| _____________________________^
6+
LL | | Self(self.0)
7+
LL | | }
8+
| |_____^ help: change this to: `{ *self }`
9+
|
10+
= note: `#[deny(clippy::incorrect_clone_impl_on_copy_type)]` on by default
11+
12+
error: incorrect implementation of `clone_from` on a `Copy` type
13+
--> $DIR/incorrect_clone_impl_on_copy_type.rs:14:5
14+
|
15+
LL | / fn clone_from(&mut self, source: &Self) {
16+
LL | | source.clone();
17+
LL | | *self = source.clone();
18+
LL | | }
19+
| |_____^ help: remove this
20+
21+
error: incorrect implementation of `clone` on a `Copy` type
22+
--> $DIR/incorrect_clone_impl_on_copy_type.rs:81:29
23+
|
24+
LL | fn clone(&self) -> Self {
25+
| _____________________________^
26+
LL | | Self(self.0)
27+
LL | | }
28+
| |_____^ help: change this to: `{ *self }`
29+
30+
error: incorrect implementation of `clone_from` on a `Copy` type
31+
--> $DIR/incorrect_clone_impl_on_copy_type.rs:85:5
32+
|
33+
LL | / fn clone_from(&mut self, source: &Self) {
34+
LL | | source.clone();
35+
LL | | *self = source.clone();
36+
LL | | }
37+
| |_____^ help: remove this
38+
39+
error: aborting due to 4 previous errors
40+

tests/ui/needless_clone_impl.stderr

-13
This file was deleted.

tests/ui/unnecessary_struct_initialization.fixed

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//@run-rustfix
22

3-
#![allow(clippy::needless_clone_impl, unused)]
3+
#![allow(clippy::incorrect_clone_impl_on_copy_type, unused)]
44
#![warn(clippy::unnecessary_struct_initialization)]
55

66
struct S {

tests/ui/unnecessary_struct_initialization.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//@run-rustfix
22

3-
#![allow(clippy::needless_clone_impl, unused)]
3+
#![allow(clippy::incorrect_clone_impl_on_copy_type, unused)]
44
#![warn(clippy::unnecessary_struct_initialization)]
55

66
struct S {

0 commit comments

Comments
 (0)