|
1 |
| -use crate::utils::{differing_macro_contexts, snippet_block_with_applicability, span_lint, span_lint_and_sugg}; |
| 1 | +use crate::utils::{ |
| 2 | + differing_macro_contexts, get_parent_expr, get_trait_def_id, implements_trait, paths, |
| 3 | + snippet_block_with_applicability, span_lint, span_lint_and_sugg, |
| 4 | +}; |
| 5 | +use if_chain::if_chain; |
2 | 6 | use rustc_errors::Applicability;
|
3 | 7 | use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
|
4 | 8 | use rustc_hir::{BlockCheckMode, Expr, ExprKind};
|
@@ -52,6 +56,18 @@ impl<'a, 'tcx> Visitor<'tcx> for ExVisitor<'a, 'tcx> {
|
52 | 56 |
|
53 | 57 | fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
|
54 | 58 | if let ExprKind::Closure(_, _, eid, _, _) = expr.kind {
|
| 59 | + // do not lint if the closure is called using an iterator (see #1141) |
| 60 | + if_chain! { |
| 61 | + if let Some(parent) = get_parent_expr(self.cx, expr); |
| 62 | + if let ExprKind::MethodCall(_, _, args, _) = parent.kind; |
| 63 | + let caller = self.cx.typeck_results().expr_ty(&args[0]); |
| 64 | + if let Some(iter_id) = get_trait_def_id(self.cx, &paths::ITERATOR); |
| 65 | + if implements_trait(self.cx, caller, iter_id, &[]); |
| 66 | + then { |
| 67 | + return; |
| 68 | + } |
| 69 | + } |
| 70 | + |
55 | 71 | let body = self.cx.tcx.hir().body(eid);
|
56 | 72 | let ex = &body.value;
|
57 | 73 | if matches!(ex.kind, ExprKind::Block(_, _)) && !body.value.span.from_expansion() {
|
|
0 commit comments