Skip to content

Commit 5b7efe8

Browse files
committed
Auto merge of #12516 - humannum14916:assigning_clones_msrv, r=Alexendoo
Make `assigning_clones` MSRV check more precise Continuation of #12511 `clone_into` is the only suggestion subject to the 1.63 MSRV requirement, and the lint should still emit other suggestions regardless of the MSRV. changelog: [assigning_clones]: only apply MSRV check to `clone_into` suggestions.
2 parents 89aba8d + db7c9fe commit 5b7efe8

File tree

4 files changed

+42
-24
lines changed

4 files changed

+42
-24
lines changed

clippy_lints/src/assigning_clones.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,6 @@ impl_lint_pass!(AssigningClones => [ASSIGNING_CLONES]);
6666

6767
impl<'tcx> LateLintPass<'tcx> for AssigningClones {
6868
fn check_expr(&mut self, cx: &LateContext<'tcx>, assign_expr: &'tcx hir::Expr<'_>) {
69-
if !self.msrv.meets(msrvs::ASSIGNING_CLONES) {
70-
return;
71-
}
72-
7369
// Do not fire the lint in macros
7470
let expn_data = assign_expr.span().ctxt().outer_expn_data();
7571
match expn_data.kind {
@@ -85,7 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for AssigningClones {
8581
return;
8682
};
8783

88-
if is_ok_to_suggest(cx, lhs, &call) {
84+
if is_ok_to_suggest(cx, lhs, &call, &self.msrv) {
8985
suggest(cx, assign_expr, lhs, &call);
9086
}
9187
}
@@ -154,7 +150,13 @@ fn extract_call<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<
154150

155151
// Return true if we find that the called method has a custom implementation and isn't derived or
156152
// provided by default by the corresponding trait.
157-
fn is_ok_to_suggest<'tcx>(cx: &LateContext<'tcx>, lhs: &Expr<'tcx>, call: &CallCandidate<'tcx>) -> bool {
153+
fn is_ok_to_suggest<'tcx>(cx: &LateContext<'tcx>, lhs: &Expr<'tcx>, call: &CallCandidate<'tcx>, msrv: &Msrv) -> bool {
154+
// For calls to .to_owned we suggest using .clone_into(), which was only stablilized in 1.63.
155+
// If the current MSRV is below that, don't suggest the lint.
156+
if !msrv.meets(msrvs::ASSIGNING_CLONES) && matches!(call.target, TargetTrait::ToOwned) {
157+
return false;
158+
}
159+
158160
// If the left-hand side is a local variable, it might be uninitialized at this point.
159161
// In that case we do not want to suggest the lint.
160162
if let Some(local) = path_to_local(lhs) {

tests/ui/assigning_clones.fixed

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,14 +129,16 @@ fn ignore_generic_clone<T: Clone>(a: &mut T, b: &T) {
129129
}
130130

131131
#[clippy::msrv = "1.62"]
132-
fn msrv_1_62(mut a: String, b: &str) {
132+
fn msrv_1_62(mut a: String, b: String, c: &str) {
133+
a.clone_from(&b);
133134
// Should not be linted, as clone_into wasn't stabilized until 1.63
134-
a = b.to_owned();
135+
a = c.to_owned();
135136
}
136137

137138
#[clippy::msrv = "1.63"]
138-
fn msrv_1_63(mut a: String, b: &str) {
139-
b.clone_into(&mut a);
139+
fn msrv_1_63(mut a: String, b: String, c: &str) {
140+
a.clone_from(&b);
141+
c.clone_into(&mut a);
140142
}
141143

142144
macro_rules! clone_inside {

tests/ui/assigning_clones.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,14 +129,16 @@ fn ignore_generic_clone<T: Clone>(a: &mut T, b: &T) {
129129
}
130130

131131
#[clippy::msrv = "1.62"]
132-
fn msrv_1_62(mut a: String, b: &str) {
132+
fn msrv_1_62(mut a: String, b: String, c: &str) {
133+
a = b.clone();
133134
// Should not be linted, as clone_into wasn't stabilized until 1.63
134-
a = b.to_owned();
135+
a = c.to_owned();
135136
}
136137

137138
#[clippy::msrv = "1.63"]
138-
fn msrv_1_63(mut a: String, b: &str) {
139-
a = b.to_owned();
139+
fn msrv_1_63(mut a: String, b: String, c: &str) {
140+
a = b.clone();
141+
a = c.to_owned();
140142
}
141143

142144
macro_rules! clone_inside {

tests/ui/assigning_clones.stderr

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,47 +67,59 @@ error: assigning the result of `Clone::clone()` may be inefficient
6767
LL | a = b.clone();
6868
| ^^^^^^^^^^^^^ help: use `clone_from()`: `a.clone_from(&b)`
6969

70+
error: assigning the result of `Clone::clone()` may be inefficient
71+
--> tests/ui/assigning_clones.rs:133:5
72+
|
73+
LL | a = b.clone();
74+
| ^^^^^^^^^^^^^ help: use `clone_from()`: `a.clone_from(&b)`
75+
76+
error: assigning the result of `Clone::clone()` may be inefficient
77+
--> tests/ui/assigning_clones.rs:140:5
78+
|
79+
LL | a = b.clone();
80+
| ^^^^^^^^^^^^^ help: use `clone_from()`: `a.clone_from(&b)`
81+
7082
error: assigning the result of `ToOwned::to_owned()` may be inefficient
71-
--> tests/ui/assigning_clones.rs:139:5
83+
--> tests/ui/assigning_clones.rs:141:5
7284
|
73-
LL | a = b.to_owned();
74-
| ^^^^^^^^^^^^^^^^ help: use `clone_into()`: `b.clone_into(&mut a)`
85+
LL | a = c.to_owned();
86+
| ^^^^^^^^^^^^^^^^ help: use `clone_into()`: `c.clone_into(&mut a)`
7587

7688
error: assigning the result of `ToOwned::to_owned()` may be inefficient
77-
--> tests/ui/assigning_clones.rs:156:5
89+
--> tests/ui/assigning_clones.rs:158:5
7890
|
7991
LL | *mut_string = ref_str.to_owned();
8092
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ref_str.clone_into(mut_string)`
8193

8294
error: assigning the result of `ToOwned::to_owned()` may be inefficient
83-
--> tests/ui/assigning_clones.rs:160:5
95+
--> tests/ui/assigning_clones.rs:162:5
8496
|
8597
LL | mut_string = ref_str.to_owned();
8698
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ref_str.clone_into(&mut mut_string)`
8799

88100
error: assigning the result of `ToOwned::to_owned()` may be inefficient
89-
--> tests/ui/assigning_clones.rs:181:5
101+
--> tests/ui/assigning_clones.rs:183:5
90102
|
91103
LL | **mut_box_string = ref_str.to_owned();
92104
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ref_str.clone_into(&mut (*mut_box_string))`
93105

94106
error: assigning the result of `ToOwned::to_owned()` may be inefficient
95-
--> tests/ui/assigning_clones.rs:185:5
107+
--> tests/ui/assigning_clones.rs:187:5
96108
|
97109
LL | **mut_box_string = ref_str.to_owned();
98110
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ref_str.clone_into(&mut (*mut_box_string))`
99111

100112
error: assigning the result of `ToOwned::to_owned()` may be inefficient
101-
--> tests/ui/assigning_clones.rs:189:5
113+
--> tests/ui/assigning_clones.rs:191:5
102114
|
103115
LL | *mut_thing = ToOwned::to_owned(ref_str);
104116
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ToOwned::clone_into(ref_str, mut_thing)`
105117

106118
error: assigning the result of `ToOwned::to_owned()` may be inefficient
107-
--> tests/ui/assigning_clones.rs:193:5
119+
--> tests/ui/assigning_clones.rs:195:5
108120
|
109121
LL | mut_thing = ToOwned::to_owned(ref_str);
110122
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ToOwned::clone_into(ref_str, &mut mut_thing)`
111123

112-
error: aborting due to 18 previous errors
124+
error: aborting due to 20 previous errors
113125

0 commit comments

Comments
 (0)