diff --git a/src/loops.rs b/src/loops.rs index 36bab550b67..5f18439eafe 100644 --- a/src/loops.rs +++ b/src/loops.rs @@ -1,10 +1,9 @@ use rustc::lint::*; use syntax::ast::*; use syntax::visit::{Visitor, walk_expr}; -use rustc::middle::ty; use std::collections::HashSet; -use utils::{snippet, span_lint, get_parent_expr, match_def_path}; +use utils::{snippet, span_lint, get_parent_expr, match_trait_method}; declare_lint!{ pub NEEDLESS_RANGE_LOOP, Warn, "for-looping over a range of indices where an iterator over items would do" } @@ -68,16 +67,10 @@ impl LintPass for LoopsPass { object, object)); // check for looping over Iterator::next() which is not what you want } else if method_name == "next" { - let method_call = ty::MethodCall::expr(arg.id); - let trt_id = cx.tcx.tables - .borrow().method_map.get(&method_call) - .and_then(|callee| cx.tcx.trait_of_item(callee.def_id)); - if let Some(trt_id) = trt_id { - if match_def_path(cx, trt_id, &["core", "iter", "Iterator"]) { - span_lint(cx, ITER_NEXT_LOOP, expr.span, - "you are iterating over `Iterator::next()` which is an Option; \ - this will compile but is probably not what you want"); - } + if match_trait_method(cx, arg, &["core", "iter", "Iterator"]) { + span_lint(cx, ITER_NEXT_LOOP, expr.span, + "you are iterating over `Iterator::next()` which is an Option; \ + this will compile but is probably not what you want"); } } } diff --git a/src/ranges.rs b/src/ranges.rs index d1a0a7e702e..914b4daa6be 100644 --- a/src/ranges.rs +++ b/src/ranges.rs @@ -20,7 +20,7 @@ impl LintPass for StepByZero { if let ExprMethodCall(Spanned { node: ref ident, .. }, _, ref args) = expr.node { // Only warn on literal ranges. - if ident.name.as_str() == "step_by" && args.len() == 2 && + if ident.name == "step_by" && args.len() == 2 && is_range(cx, &args[0]) && is_lit_zero(&args[1]) { cx.span_lint(RANGE_STEP_BY_ZERO, expr.span, "Range::step_by(0) produces an infinite iterator. \ diff --git a/src/utils.rs b/src/utils.rs index 4fd36fb91d4..5e7c63e85d9 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -56,6 +56,19 @@ pub fn match_type(cx: &Context, ty: ty::Ty, path: &[&str]) -> bool { } } +/// check if method call given in "expr" belongs to given trait +pub fn match_trait_method(cx: &Context, expr: &Expr, path: &[&str]) -> bool { + let method_call = ty::MethodCall::expr(expr.id); + let trt_id = cx.tcx.tables + .borrow().method_map.get(&method_call) + .and_then(|callee| cx.tcx.trait_of_item(callee.def_id)); + if let Some(trt_id) = trt_id { + match_def_path(cx, trt_id, path) + } else { + false + } +} + /// match a Path against a slice of segment string literals, e.g. /// `match_path(path, &["std", "rt", "begin_unwind"])` pub fn match_path(path: &Path, segments: &[&str]) -> bool {