Skip to content

Commit

Permalink
Exclude pattern guards from unnecessary_fold lint
Browse files Browse the repository at this point in the history
Methods like `Iterator::any` borrow the iterator mutably,
which is not allowed within a pattern guard and will fail to compile.
This commit prevents clippy from suggesting this type of change.

Closes #3069
  • Loading branch information
Joshua Holmer committed Oct 12, 2018
1 parent d445dbf commit d3c06f7
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 0 deletions.
18 changes: 18 additions & 0 deletions clippy_lints/src/methods/mod.rs
Expand Up @@ -9,6 +9,7 @@


use crate::rustc::hir;
use crate::rustc::hir::{ExprKind, Guard, Node};
use crate::rustc::hir::def::Def;
use crate::rustc::lint::{in_external_macro, LateContext, LateLintPass, Lint, LintArray, LintContext, LintPass};
use crate::rustc::ty::{self, Ty};
Expand Down Expand Up @@ -1428,6 +1429,23 @@ fn lint_unnecessary_fold(cx: &LateContext<'_, '_>, expr: &hir::Expr, fold_args:
return;
}

// `Iterator::any` cannot be used within a pattern guard
// See https://github.com/rust-lang-nursery/rust-clippy/issues/3069
if_chain! {
if let Some(fold_parent) = cx.tcx.hir.find(cx.tcx.hir.get_parent_node(expr.id));
if let Node::Expr(fold_parent) = fold_parent;
if let ExprKind::Match(_, ref arms, _) = fold_parent.node;
if arms.iter().any(|arm| {
if let Some(Guard::If(ref guard)) = arm.guard {
return guard.id == expr.id;
}
false
});
then {
return;
}
}

assert!(fold_args.len() == 3,
"Expected fold_args to have three entries - the receiver, the initial value and the closure");

Expand Down
7 changes: 7 additions & 0 deletions tests/ui/unnecessary_fold.rs
Expand Up @@ -45,6 +45,13 @@ fn unnecessary_fold_should_ignore() {

let _ = [(0..2), (0..3)].iter().fold(0, |a, b| a + b.len());
let _ = [(0..2), (0..3)].iter().fold(1, |a, b| a * b.len());

// Because `any` takes the iterator as a mutable reference,
// it cannot be used in a pattern guard, and we must use `fold`.
match 1 {
_ if (0..3).fold(false, |acc, x| acc || x > 2) => {}
_ => {}
}
}

fn main() {}

0 comments on commit d3c06f7

Please sign in to comment.