fixed suggestion for iter case

This commit is contained in:
llogiq 2016-01-27 14:51:30 +01:00
parent d152e5c683
commit 5d5e50d67e
2 changed files with 23 additions and 14 deletions

View file

@ -446,36 +446,44 @@ fn lint_extend(cx: &LateContext, expr: &Expr, args: &MethodArgs) {
return; return;
} }
let arg_ty = cx.tcx.expr_ty(&args[1]); let arg_ty = cx.tcx.expr_ty(&args[1]);
if derefs_to_slice(cx, &args[1], &arg_ty) { if let Some((span, r)) = derefs_to_slice(cx, &args[1], &arg_ty) {
span_lint(cx, EXTEND_FROM_SLICE, expr.span, span_lint(cx, EXTEND_FROM_SLICE, expr.span,
&format!("use of `extend` to extend a Vec by a slice")) &format!("use of `extend` to extend a Vec by a slice"))
.span_suggestion(expr.span, "try this", .span_suggestion(expr.span, "try this",
format!("{}.extend_from_slice({})", format!("{}.extend_from_slice({}{})",
snippet(cx, args[0].span, "_"), snippet(cx, args[0].span, "_"),
snippet(cx, args[1].span, "_"))); r, snippet(cx, span, "_")));
} }
} }
fn derefs_to_slice(cx: &LateContext, expr: &Expr, ty: &ty::Ty) -> bool { fn derefs_to_slice(cx: &LateContext, expr: &Expr, ty: &ty::Ty)
fn may_slice(cx: &LateContext, expr: &Expr, ty: &ty::Ty) -> bool { -> Option<(Span, &'static str)> {
fn may_slice(cx: &LateContext, ty: &ty::Ty) -> bool {
match ty.sty { match ty.sty {
ty::TySlice(_) => true, ty::TySlice(_) => true,
ty::TyStruct(..) => match_type(cx, ty, &VEC_PATH), ty::TyStruct(..) => match_type(cx, ty, &VEC_PATH),
ty::TyArray(_, size) => size < 32, ty::TyArray(_, size) => size < 32,
ty::TyRef(_, ty::TypeAndMut { ty: ref inner, .. }) | ty::TyRef(_, ty::TypeAndMut { ty: ref inner, .. }) |
ty::TyBox(ref inner) => may_slice(cx, expr, inner), ty::TyBox(ref inner) => may_slice(cx, inner),
_ => false _ => false
} }
} }
if let ExprMethodCall(name, _, ref args) = expr.node { if let ExprMethodCall(name, _, ref args) = expr.node {
return &name.node.as_str() == &"iter" && if &name.node.as_str() == &"iter" &&
may_slice(cx, &args[0], &cx.tcx.expr_ty(&args[0])) may_slice(cx, &cx.tcx.expr_ty(&args[0])) {
Some((args[0].span, "&"))
} else {
None
} }
} else {
match ty.sty { match ty.sty {
ty::TySlice(_) => true, ty::TySlice(_) => Some((expr.span, "")),
ty::TyRef(_, ty::TypeAndMut { ty: ref inner, .. }) | ty::TyRef(_, ty::TypeAndMut { ty: ref inner, .. }) |
ty::TyBox(ref inner) => may_slice(cx, expr, inner), ty::TyBox(ref inner) => if may_slice(cx, inner) {
_ => false Some((expr.span, ""))
} else { None },
_ => None
}
} }
} }

View file

@ -314,4 +314,5 @@ fn use_extend_from_slice() {
v.extend(o); v.extend(o);
v.extend(Some("Bye")); v.extend(Some("Bye"));
v.extend(vec!["Not", "like", "this"]); v.extend(vec!["Not", "like", "this"]);
v.extend(["Nor", "this"].iter());
} }