]> git.proxmox.com Git - rustc.git/blobdiff - src/tools/clippy/clippy_lints/src/blocks_in_if_conditions.rs
Merge tag 'debian/1.52.1+dfsg1-1_exp2' into proxmox/buster
[rustc.git] / src / tools / clippy / clippy_lints / src / blocks_in_if_conditions.rs
index 4efca10bcdf13d650cdff8067231ae3f8f32d4f5..b53f80fd8bc15801ea0238153a71444e4a657eab 100644 (file)
@@ -1,4 +1,8 @@
-use crate::utils::{differing_macro_contexts, snippet_block_with_applicability, span_lint, span_lint_and_sugg};
+use crate::utils::{
+    differing_macro_contexts, get_parent_expr, get_trait_def_id, implements_trait, paths,
+    snippet_block_with_applicability, span_lint, span_lint_and_sugg,
+};
+use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
 use rustc_hir::{BlockCheckMode, Expr, ExprKind};
@@ -52,6 +56,18 @@ impl<'a, 'tcx> Visitor<'tcx> for ExVisitor<'a, 'tcx> {
 
     fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
         if let ExprKind::Closure(_, _, eid, _, _) = expr.kind {
+            // do not lint if the closure is called using an iterator (see #1141)
+            if_chain! {
+                if let Some(parent) = get_parent_expr(self.cx, expr);
+                if let ExprKind::MethodCall(_, _, args, _) = parent.kind;
+                let caller = self.cx.typeck_results().expr_ty(&args[0]);
+                if let Some(iter_id) = get_trait_def_id(self.cx, &paths::ITERATOR);
+                if implements_trait(self.cx, caller, iter_id, &[]);
+                then {
+                    return;
+                }
+            }
+
             let body = self.cx.tcx.hir().body(eid);
             let ex = &body.value;
             if matches!(ex.kind, ExprKind::Block(_, _)) && !body.value.span.from_expansion() {