new lint: using collect() to just exhaust an iterator

Should use a for loop instead.
This commit is contained in:
Georg Brandl 2015-08-30 13:10:59 +02:00
parent b72ef5a173
commit 16df79a054
4 changed files with 27 additions and 2 deletions

View file

@ -96,6 +96,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
loops::EXPLICIT_ITER_LOOP,
loops::ITER_NEXT_LOOP,
loops::NEEDLESS_RANGE_LOOP,
loops::UNUSED_COLLECT,
loops::WHILE_LET_LOOP,
matches::MATCH_REF_PATS,
matches::SINGLE_MATCH,

View file

@ -20,13 +20,17 @@ declare_lint!{ pub ITER_NEXT_LOOP, Warn,
declare_lint!{ pub WHILE_LET_LOOP, Warn,
"`loop { if let { ... } else break }` can be written as a `while let` loop" }
declare_lint!{ pub UNUSED_COLLECT, Warn,
"`collect()`ing an iterator without using the result; this is usually better \
written as a for loop" }
#[derive(Copy, Clone)]
pub struct LoopsPass;
impl LintPass for LoopsPass {
fn get_lints(&self) -> LintArray {
lint_array!(NEEDLESS_RANGE_LOOP, EXPLICIT_ITER_LOOP, ITER_NEXT_LOOP,
WHILE_LET_LOOP)
WHILE_LET_LOOP, UNUSED_COLLECT)
}
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
@ -112,6 +116,20 @@ impl LintPass for LoopsPass {
}
}
}
fn check_stmt(&mut self, cx: &Context, stmt: &Stmt) {
if let StmtSemi(ref expr, _) = stmt.node {
if let ExprMethodCall(ref method, _, ref args) = expr.node {
if args.len() == 1 && method.node.name == "collect" {
if match_trait_method(cx, expr, &["core", "iter", "Iterator"]) {
span_lint(cx, UNUSED_COLLECT, expr.span, &format!(
"you are collect()ing an iterator and throwing away the result. \
Consider using an explicit for loop to exhaust the iterator"));
}
}
}
}
}
}
/// Recover the essential nodes of a desugared for loop: