| use clippy_utils::diagnostics::span_lint_and_help; | |
| use clippy_utils::expr_or_init; | |
| use clippy_utils::res::{MaybeDef, MaybeTypeckRes}; | |
| use clippy_utils::usage::mutated_variables; | |
| use rustc_hir as hir; | |
| use rustc_lint::LateContext; | |
| use rustc_span::sym; | |
| use super::SUSPICIOUS_MAP; | |
| pub fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, count_recv: &hir::Expr<'_>, map_arg: &hir::Expr<'_>) { | |
| if cx | |
| .ty_based_def(count_recv) | |
| .opt_parent(cx) | |
| .is_diag_item(cx, sym::Iterator) | |
| && let hir::ExprKind::Closure(closure) = expr_or_init(cx, map_arg).kind | |
| && let closure_body = cx.tcx.hir_body(closure.body) | |
| && !cx.typeck_results().expr_ty(closure_body.value).is_unit() | |
| { | |
| if let Some(map_mutated_vars) = mutated_variables(closure_body.value, cx) | |
| // A variable is used mutably inside of the closure. Suppress the lint. | |
| && !map_mutated_vars.is_empty() | |
| { | |
| return; | |
| } | |
| span_lint_and_help( | |
| cx, | |
| SUSPICIOUS_MAP, | |
| expr.span, | |
| "this call to `map()` won't have an effect on the call to `count()`", | |
| None, | |
| "make sure you did not confuse `map` with `filter`, `for_each` or `inspect`", | |
| ); | |
| } | |
| } |