Skip to content

Commit 7c17dd3

Browse files
committed
needless_for_each: Check HIR tree first.
1 parent 139dad8 commit 7c17dd3

File tree

1 file changed

+5
-11
lines changed

1 file changed

+5
-11
lines changed

clippy_lints/src/needless_for_each.rs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use rustc_hir::intravisit::{walk_expr, Visitor};
33
use rustc_hir::{Block, BlockCheckMode, Closure, Expr, ExprKind, Stmt, StmtKind};
44
use rustc_lint::{LateContext, LateLintPass};
55
use rustc_session::declare_lint_pass;
6-
use rustc_span::{sym, Span, Symbol};
6+
use rustc_span::{sym, Span};
77

88
use clippy_utils::diagnostics::span_lint_and_then;
99
use clippy_utils::is_trait_method;
@@ -55,23 +55,17 @@ declare_lint_pass!(NeedlessForEach => [NEEDLESS_FOR_EACH]);
5555

5656
impl<'tcx> LateLintPass<'tcx> for NeedlessForEach {
5757
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
58-
let (StmtKind::Expr(expr) | StmtKind::Semi(expr)) = stmt.kind else {
59-
return;
60-
};
61-
62-
if let ExprKind::MethodCall(method_name, for_each_recv, [for_each_arg], _) = expr.kind
63-
// Check the method name is `for_each`.
64-
&& method_name.ident.name == Symbol::intern("for_each")
65-
// Check `for_each` is an associated function of `Iterator`.
66-
&& is_trait_method(cx, expr, sym::Iterator)
67-
// Checks the receiver of `for_each` is also a method call.
58+
if let StmtKind::Expr(expr) | StmtKind::Semi(expr) = stmt.kind
59+
&& let ExprKind::MethodCall(method_name, for_each_recv, [for_each_arg], _) = expr.kind
6860
&& let ExprKind::MethodCall(_, iter_recv, [], _) = for_each_recv.kind
6961
// Skip the lint if the call chain is too long. e.g. `v.field.iter().for_each()` or
7062
// `v.foo().iter().for_each()` must be skipped.
7163
&& matches!(
7264
iter_recv.kind,
7365
ExprKind::Array(..) | ExprKind::Call(..) | ExprKind::Path(..)
7466
)
67+
&& method_name.ident.name.as_str() == "for_each"
68+
&& is_trait_method(cx, expr, sym::Iterator)
7569
// Checks the type of the `iter` method receiver is NOT a user defined type.
7670
&& has_iter_method(cx, cx.typeck_results().expr_ty(iter_recv)).is_some()
7771
// Skip the lint if the body is not block because this is simpler than `for` loop.

0 commit comments

Comments
 (0)