Use utils::sugg in methods lints

This commit is contained in:
mcarton 2016-07-05 23:26:47 +02:00
parent c5e91e70d0
commit 8aaaf198e3
No known key found for this signature in database
GPG key ID: 5E427C794CBA45E8

View file

@ -11,10 +11,11 @@ use std::fmt;
use syntax::codemap::Span;
use syntax::ptr::P;
use utils::{get_trait_def_id, implements_trait, in_external_macro, in_macro, match_path, match_trait_method,
match_type, method_chain_args, return_ty, same_tys, snippet, snippet_opt, span_lint,
match_type, method_chain_args, return_ty, same_tys, snippet, span_lint,
span_lint_and_then, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth};
use utils::MethodArgs;
use utils::paths;
use utils::sugg;
#[derive(Clone)]
pub struct Pass;
@ -628,8 +629,8 @@ fn lint_clone_double_ref(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr, ty
expr.span,
"using `clone` on a double-reference; \
this will copy the reference instead of cloning the inner type",
|db| if let Some(snip) = snippet_opt(cx, arg.span) {
db.span_suggestion(expr.span, "try dereferencing it", format!("(*{}).clone()", snip));
|db| if let Some(snip) = sugg::Sugg::hir_opt(cx, arg) {
db.span_suggestion(expr.span, "try dereferencing it", format!("({}).clone()", snip.deref()));
});
}
}
@ -641,14 +642,13 @@ fn lint_extend(cx: &LateContext, expr: &hir::Expr, args: &MethodArgs) {
return;
}
let arg_ty = cx.tcx.expr_ty(&args[1]);
if let Some((span, r)) = derefs_to_slice(cx, &args[1], &arg_ty) {
if let Some(slice) = derefs_to_slice(cx, &args[1], &arg_ty) {
span_lint_and_then(cx, EXTEND_FROM_SLICE, expr.span, "use of `extend` to extend a Vec by a slice", |db| {
db.span_suggestion(expr.span,
"try this",
format!("{}.extend_from_slice({}{})",
format!("{}.extend_from_slice({})",
snippet(cx, args[0].span, "_"),
r,
snippet(cx, span, "_")));
slice));
});
}
}
@ -695,7 +695,7 @@ fn lint_iter_nth(cx: &LateContext, expr: &hir::Expr, iter_args: &MethodArgs, is_
);
}
fn derefs_to_slice(cx: &LateContext, expr: &hir::Expr, ty: &ty::Ty) -> Option<(Span, &'static str)> {
fn derefs_to_slice(cx: &LateContext, expr: &hir::Expr, ty: &ty::Ty) -> Option<sugg::Sugg<'static>> {
fn may_slice(cx: &LateContext, ty: &ty::Ty) -> bool {
match ty.sty {
ty::TySlice(_) => true,
@ -706,19 +706,22 @@ fn derefs_to_slice(cx: &LateContext, expr: &hir::Expr, ty: &ty::Ty) -> Option<(S
_ => false,
}
}
if let hir::ExprMethodCall(name, _, ref args) = expr.node {
if &name.node.as_str() == &"iter" && may_slice(cx, &cx.tcx.expr_ty(&args[0])) {
Some((args[0].span, "&"))
sugg::Sugg::hir_opt(cx, &*args[0]).map(|sugg| {
sugg.addr()
})
} else {
None
}
} else {
match ty.sty {
ty::TySlice(_) => Some((expr.span, "")),
ty::TySlice(_) => sugg::Sugg::hir_opt(cx, expr),
ty::TyRef(_, ty::TypeAndMut { ty: ref inner, .. }) |
ty::TyBox(ref inner) => {
if may_slice(cx, inner) {
Some((expr.span, ""))
sugg::Sugg::hir_opt(cx, expr)
} else {
None
}