Moves clone_on_ref_ptr to be a restriction lint

Also updates the suggestion to include the full type (e.g. `Arc<Foo>::clone(&rc)`)
and adds a case using trait objects to the UI tests.
This commit is contained in:
Adam Lusch 2018-01-14 19:58:09 -08:00
parent 41a710e3f4
commit 1615813960
2 changed files with 27 additions and 20 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) {