Skip to content

Commit 5c71c1b

Browse files
committed
Auto merge of #4411 - mikerite:fix-4384, r=flip1995
Fix `clone_on_copy` false positives Closes #4384 changelog: Fix `clone_on_copy` false positives
2 parents d1f1844 + 68a1af5 commit 5c71c1b

File tree

3 files changed

+37
-32
lines changed

3 files changed

+37
-32
lines changed

clippy_lints/src/methods/mod.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1549,30 +1549,30 @@ fn lint_clone_on_copy(cx: &LateContext<'_, '_>, expr: &hir::Expr, arg: &hir::Exp
15491549
if is_copy(cx, ty) {
15501550
let snip;
15511551
if let Some(snippet) = sugg::Sugg::hir_opt(cx, arg) {
1552+
let parent = cx.tcx.hir().get_parent_node(expr.hir_id);
1553+
match &cx.tcx.hir().get(parent) {
1554+
hir::Node::Expr(parent) => match parent.node {
1555+
// &*x is a nop, &x.clone() is not
1556+
hir::ExprKind::AddrOf(..) |
1557+
// (*x).func() is useless, x.clone().func() can work in case func borrows mutably
1558+
hir::ExprKind::MethodCall(..) => return,
1559+
_ => {},
1560+
},
1561+
hir::Node::Stmt(stmt) => {
1562+
if let hir::StmtKind::Local(ref loc) = stmt.node {
1563+
if let hir::PatKind::Ref(..) = loc.pat.node {
1564+
// let ref y = *x borrows x, let ref y = x.clone() does not
1565+
return;
1566+
}
1567+
}
1568+
},
1569+
_ => {},
1570+
}
1571+
15521572
// x.clone() might have dereferenced x, possibly through Deref impls
15531573
if cx.tables.expr_ty(arg) == ty {
15541574
snip = Some(("try removing the `clone` call", format!("{}", snippet)));
15551575
} else {
1556-
let parent = cx.tcx.hir().get_parent_node(expr.hir_id);
1557-
match cx.tcx.hir().get(parent) {
1558-
hir::Node::Expr(parent) => match parent.node {
1559-
// &*x is a nop, &x.clone() is not
1560-
hir::ExprKind::AddrOf(..) |
1561-
// (*x).func() is useless, x.clone().func() can work in case func borrows mutably
1562-
hir::ExprKind::MethodCall(..) => return,
1563-
_ => {},
1564-
},
1565-
hir::Node::Stmt(stmt) => {
1566-
if let hir::StmtKind::Local(ref loc) = stmt.node {
1567-
if let hir::PatKind::Ref(..) = loc.pat.node {
1568-
// let ref y = *x borrows x, let ref y = x.clone() does not
1569-
return;
1570-
}
1571-
}
1572-
},
1573-
_ => {},
1574-
}
1575-
15761576
let deref_count = cx
15771577
.tables
15781578
.expr_adjustments(arg)

tests/ui/unnecessary_clone.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ fn clone_on_copy() {
2222

2323
let rc = RefCell::new(0);
2424
rc.borrow().clone();
25+
26+
// Issue #4348
27+
let mut x = 43;
28+
let _ = &x.clone(); // ok, getting a ref
29+
'a'.clone().make_ascii_uppercase(); // ok, clone and then mutate
2530
}
2631

2732
fn clone_on_ref_ptr() {

tests/ui/unnecessary_clone.stderr

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,51 +19,51 @@ LL | rc.borrow().clone();
1919
| ^^^^^^^^^^^^^^^^^^^ help: try dereferencing it: `*rc.borrow()`
2020

2121
error: using '.clone()' on a ref-counted pointer
22-
--> $DIR/unnecessary_clone.rs:34:5
22+
--> $DIR/unnecessary_clone.rs:39:5
2323
|
2424
LL | rc.clone();
2525
| ^^^^^^^^^^ help: try this: `Rc::<bool>::clone(&rc)`
2626
|
2727
= note: `-D clippy::clone-on-ref-ptr` implied by `-D warnings`
2828

2929
error: using '.clone()' on a ref-counted pointer
30-
--> $DIR/unnecessary_clone.rs:37:5
30+
--> $DIR/unnecessary_clone.rs:42:5
3131
|
3232
LL | arc.clone();
3333
| ^^^^^^^^^^^ help: try this: `Arc::<bool>::clone(&arc)`
3434

3535
error: using '.clone()' on a ref-counted pointer
36-
--> $DIR/unnecessary_clone.rs:40:5
36+
--> $DIR/unnecessary_clone.rs:45:5
3737
|
3838
LL | rcweak.clone();
3939
| ^^^^^^^^^^^^^^ help: try this: `Weak::<bool>::clone(&rcweak)`
4040

4141
error: using '.clone()' on a ref-counted pointer
42-
--> $DIR/unnecessary_clone.rs:43:5
42+
--> $DIR/unnecessary_clone.rs:48:5
4343
|
4444
LL | arc_weak.clone();
4545
| ^^^^^^^^^^^^^^^^ help: try this: `Weak::<bool>::clone(&arc_weak)`
4646

4747
error: using '.clone()' on a ref-counted pointer
48-
--> $DIR/unnecessary_clone.rs:47:33
48+
--> $DIR/unnecessary_clone.rs:52:33
4949
|
5050
LL | let _: Arc<dyn SomeTrait> = x.clone();
5151
| ^^^^^^^^^ help: try this: `Arc::<SomeImpl>::clone(&x)`
5252

5353
error: using `clone` on a `Copy` type
54-
--> $DIR/unnecessary_clone.rs:51:5
54+
--> $DIR/unnecessary_clone.rs:56:5
5555
|
5656
LL | t.clone();
5757
| ^^^^^^^^^ help: try removing the `clone` call: `t`
5858

5959
error: using `clone` on a `Copy` type
60-
--> $DIR/unnecessary_clone.rs:53:5
60+
--> $DIR/unnecessary_clone.rs:58:5
6161
|
6262
LL | Some(t).clone();
6363
| ^^^^^^^^^^^^^^^ help: try removing the `clone` call: `Some(t)`
6464

6565
error: using `clone` on a double-reference; this will copy the reference instead of cloning the inner type
66-
--> $DIR/unnecessary_clone.rs:59:22
66+
--> $DIR/unnecessary_clone.rs:64:22
6767
|
6868
LL | let z: &Vec<_> = y.clone();
6969
| ^^^^^^^^^
@@ -79,21 +79,21 @@ LL | let z: &Vec<_> = &std::vec::Vec<i32>::clone(y);
7979
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8080

8181
error: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable
82-
--> $DIR/unnecessary_clone.rs:66:27
82+
--> $DIR/unnecessary_clone.rs:71:27
8383
|
8484
LL | let v2: Vec<isize> = v.iter().cloned().collect();
8585
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.to_vec()`
8686
|
8787
= note: `-D clippy::iter-cloned-collect` implied by `-D warnings`
8888

8989
error: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable
90-
--> $DIR/unnecessary_clone.rs:71:38
90+
--> $DIR/unnecessary_clone.rs:76:38
9191
|
9292
LL | let _: Vec<isize> = vec![1, 2, 3].iter().cloned().collect();
9393
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.to_vec()`
9494

9595
error: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable
96-
--> $DIR/unnecessary_clone.rs:76:24
96+
--> $DIR/unnecessary_clone.rs:81:24
9797
|
9898
LL | .to_bytes()
9999
| ________________________^
@@ -103,7 +103,7 @@ LL | | .collect();
103103
| |______________________^ help: try: `.to_vec()`
104104

105105
error: using `clone` on a `Copy` type
106-
--> $DIR/unnecessary_clone.rs:114:20
106+
--> $DIR/unnecessary_clone.rs:119:20
107107
|
108108
LL | let _: E = a.clone();
109109
| ^^^^^^^^^ help: try dereferencing it: `*****a`

0 commit comments

Comments
 (0)