Merge pull request #2355 from alusch/clone_on_ref_ptr_restriction

Fix #2048: Move `clone_on_ref_ptr` to the restriction lints
This commit is contained in:
Oliver Schneider 2018-01-16 10:40:12 +01:00 committed by GitHub
commit 61e2b7a4d6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 46 deletions

View file

@ -361,9 +361,8 @@ declare_lint! {
/// ```rust
/// x.clone()
/// ```
declare_lint! {
declare_restriction_lint! {
pub CLONE_ON_REF_PTR,
Warn,
"using 'clone' on a ref-counted pointer"
}
@ -1013,24 +1012,26 @@ fn lint_clone_on_copy(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr, arg_t
fn lint_clone_on_ref_ptr(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr) {
let (obj_ty, _) = walk_ptrs_ty_depth(cx.tables.expr_ty(arg));
let caller_type = if match_type(cx, obj_ty, &paths::RC) {
"Rc"
} else if match_type(cx, obj_ty, &paths::ARC) {
"Arc"
} else if match_type(cx, obj_ty, &paths::WEAK_RC) || match_type(cx, obj_ty, &paths::WEAK_ARC) {
"Weak"
} else {
return;
};
if let ty::TyAdt(_, subst) = obj_ty.sty {
let caller_type = if match_type(cx, obj_ty, &paths::RC) {
"Rc"
} else if match_type(cx, obj_ty, &paths::ARC) {
"Arc"
} else if match_type(cx, obj_ty, &paths::WEAK_RC) || match_type(cx, obj_ty, &paths::WEAK_ARC) {
"Weak"
} else {
return;
};
span_lint_and_sugg(
cx,
CLONE_ON_REF_PTR,
expr.span,
"using '.clone()' on a ref-counted pointer",
"try this",
format!("{}::clone(&{})", caller_type, snippet(cx, arg.span, "_")),
);
span_lint_and_sugg(
cx,
CLONE_ON_REF_PTR,
expr.span,
"using '.clone()' on a ref-counted pointer",
"try this",
format!("{}::<{}>::clone(&{})", caller_type, subst.type_at(0), snippet(cx, arg.span, "_")),
);
}
}

View file

@ -1,3 +1,4 @@
#![warn(clone_on_ref_ptr)]
#![allow(unused)]
use std::collections::HashSet;
@ -5,6 +6,10 @@ use std::collections::VecDeque;
use std::rc::{self, Rc};
use std::sync::{self, Arc};
trait SomeTrait {}
struct SomeImpl;
impl SomeTrait for SomeImpl {}
fn main() {}
fn clone_on_copy() {
@ -34,7 +39,8 @@ fn clone_on_ref_ptr() {
arc_weak.clone();
sync::Weak::clone(&arc_weak);
let x = Arc::new(SomeImpl);
let _: Arc<SomeTrait> = x.clone();
}
fn clone_on_copy_generic<T: Copy>(t: T) {

View file

@ -1,75 +1,81 @@
error: using `clone` on a `Copy` type
--> $DIR/unnecessary_clone.rs:11:5
--> $DIR/unnecessary_clone.rs:16:5
|
11 | 42.clone();
16 | 42.clone();
| ^^^^^^^^^^ help: try removing the `clone` call: `42`
|
= note: `-D clone-on-copy` implied by `-D warnings`
error: using `clone` on a `Copy` type
--> $DIR/unnecessary_clone.rs:15:5
--> $DIR/unnecessary_clone.rs:20:5
|
15 | (&42).clone();
20 | (&42).clone();
| ^^^^^^^^^^^^^ help: try dereferencing it: `*(&42)`
error: using '.clone()' on a ref-counted pointer
--> $DIR/unnecessary_clone.rs:25:5
--> $DIR/unnecessary_clone.rs:30:5
|
25 | rc.clone();
| ^^^^^^^^^^ help: try this: `Rc::clone(&rc)`
30 | rc.clone();
| ^^^^^^^^^^ help: try this: `Rc::<bool>::clone(&rc)`
|
= note: `-D clone-on-ref-ptr` implied by `-D warnings`
error: using '.clone()' on a ref-counted pointer
--> $DIR/unnecessary_clone.rs:28:5
--> $DIR/unnecessary_clone.rs:33:5
|
28 | arc.clone();
| ^^^^^^^^^^^ help: try this: `Arc::clone(&arc)`
33 | arc.clone();
| ^^^^^^^^^^^ help: try this: `Arc::<bool>::clone(&arc)`
error: using '.clone()' on a ref-counted pointer
--> $DIR/unnecessary_clone.rs:31:5
--> $DIR/unnecessary_clone.rs:36:5
|
31 | rcweak.clone();
| ^^^^^^^^^^^^^^ help: try this: `Weak::clone(&rcweak)`
36 | rcweak.clone();
| ^^^^^^^^^^^^^^ help: try this: `Weak::<bool>::clone(&rcweak)`
error: using '.clone()' on a ref-counted pointer
--> $DIR/unnecessary_clone.rs:34:5
--> $DIR/unnecessary_clone.rs:39:5
|
34 | arc_weak.clone();
| ^^^^^^^^^^^^^^^^ help: try this: `Weak::clone(&arc_weak)`
39 | arc_weak.clone();
| ^^^^^^^^^^^^^^^^ help: try this: `Weak::<bool>::clone(&arc_weak)`
error: using '.clone()' on a ref-counted pointer
--> $DIR/unnecessary_clone.rs:43:29
|
43 | let _: Arc<SomeTrait> = x.clone();
| ^^^^^^^^^ help: try this: `Arc::<SomeImpl>::clone(&x)`
error: using `clone` on a `Copy` type
--> $DIR/unnecessary_clone.rs:41:5
--> $DIR/unnecessary_clone.rs:47:5
|
41 | t.clone();
47 | t.clone();
| ^^^^^^^^^ help: try removing the `clone` call: `t`
error: using `clone` on a `Copy` type
--> $DIR/unnecessary_clone.rs:43:5
--> $DIR/unnecessary_clone.rs:49:5
|
43 | Some(t).clone();
49 | Some(t).clone();
| ^^^^^^^^^^^^^^^ help: try removing the `clone` call: `Some(t)`
error: using `clone` on a double-reference; this will copy the reference instead of cloning the inner type
--> $DIR/unnecessary_clone.rs:49:22
--> $DIR/unnecessary_clone.rs:55:22
|
49 | let z: &Vec<_> = y.clone();
55 | let z: &Vec<_> = y.clone();
| ^^^^^^^^^
|
= note: `-D clone-double-ref` implied by `-D warnings`
help: try dereferencing it
|
49 | let z: &Vec<_> = &(*y).clone();
55 | let z: &Vec<_> = &(*y).clone();
| ^^^^^^^^^^^^^
help: or try being explicit about what type to clone
|
49 | let z: &Vec<_> = &std::vec::Vec<i32>::clone(y);
55 | let z: &Vec<_> = &std::vec::Vec<i32>::clone(y);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: called `cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable
--> $DIR/unnecessary_clone.rs:56:27
--> $DIR/unnecessary_clone.rs:62:27
|
56 | let v2 : Vec<isize> = v.iter().cloned().collect();
62 | let v2 : Vec<isize> = v.iter().cloned().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D iter-cloned-collect` implied by `-D warnings`