Skip to content

Commit 68a1af5

Browse files
author
Michael Wright
committed
Fix clone_on_copy false positives
Closes #4384
1 parent f01a0c0 commit 68a1af5

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
@@ -1521,30 +1521,30 @@ fn lint_clone_on_copy(cx: &LateContext<'_, '_>, expr: &hir::Expr, arg: &hir::Exp
15211521
if is_copy(cx, ty) {
15221522
let snip;
15231523
if let Some(snippet) = sugg::Sugg::hir_opt(cx, arg) {
1524+
let parent = cx.tcx.hir().get_parent_node(expr.hir_id);
1525+
match &cx.tcx.hir().get(parent) {
1526+
hir::Node::Expr(parent) => match parent.node {
1527+
// &*x is a nop, &x.clone() is not
1528+
hir::ExprKind::AddrOf(..) |
1529+
// (*x).func() is useless, x.clone().func() can work in case func borrows mutably
1530+
hir::ExprKind::MethodCall(..) => return,
1531+
_ => {},
1532+
},
1533+
hir::Node::Stmt(stmt) => {
1534+
if let hir::StmtKind::Local(ref loc) = stmt.node {
1535+
if let hir::PatKind::Ref(..) = loc.pat.node {
1536+
// let ref y = *x borrows x, let ref y = x.clone() does not
1537+
return;
1538+
}
1539+
}
1540+
},
1541+
_ => {},
1542+
}
1543+
15241544
// x.clone() might have dereferenced x, possibly through Deref impls
15251545
if cx.tables.expr_ty(arg) == ty {
15261546
snip = Some(("try removing the `clone` call", format!("{}", snippet)));
15271547
} else {
1528-
let parent = cx.tcx.hir().get_parent_node(expr.hir_id);
1529-
match cx.tcx.hir().get(parent) {
1530-
hir::Node::Expr(parent) => match parent.node {
1531-
// &*x is a nop, &x.clone() is not
1532-
hir::ExprKind::AddrOf(..) |
1533-
// (*x).func() is useless, x.clone().func() can work in case func borrows mutably
1534-
hir::ExprKind::MethodCall(..) => return,
1535-
_ => {},
1536-
},
1537-
hir::Node::Stmt(stmt) => {
1538-
if let hir::StmtKind::Local(ref loc) = stmt.node {
1539-
if let hir::PatKind::Ref(..) = loc.pat.node {
1540-
// let ref y = *x borrows x, let ref y = x.clone() does not
1541-
return;
1542-
}
1543-
}
1544-
},
1545-
_ => {},
1546-
}
1547-
15481548
let deref_count = cx
15491549
.tables
15501550
.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)