Skip to content

Commit 8905f78

Browse files
committedJan 27, 2024
Auto merge of #12082 - PartiallyTyped:1553, r=dswij
Fixed FP in `redundant_closure_call` when closures are passed to macros There are cases where the closure call is needed in some macros, this in particular occurs when the closure has parameters. To handle this case, we allow the lint when there are no parameters in the closure, or the closure is outside a macro invocation. fixes: #11274 #1553 changelog: FP: [`redundant_closure_call`] when closures with parameters are passed in macros.
2 parents 8de9d8c + e0228ee commit 8905f78

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed
 

Diff for: ‎clippy_lints/src/redundant_closure_call.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::rustc_lint::LintContext;
22
use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
33
use clippy_utils::get_parent_expr;
44
use clippy_utils::sugg::Sugg;
5+
use hir::Param;
56
use rustc_errors::Applicability;
67
use rustc_hir as hir;
78
use rustc_hir::intravisit::{Visitor as HirVisitor, Visitor};
@@ -13,6 +14,7 @@ use rustc_middle::hir::nested_filter;
1314
use rustc_middle::lint::in_external_macro;
1415
use rustc_middle::ty;
1516
use rustc_session::declare_lint_pass;
17+
use rustc_span::ExpnKind;
1618

1719
declare_clippy_lint! {
1820
/// ### What it does
@@ -89,7 +91,12 @@ fn find_innermost_closure<'tcx>(
8991
cx: &LateContext<'tcx>,
9092
mut expr: &'tcx hir::Expr<'tcx>,
9193
mut steps: usize,
92-
) -> Option<(&'tcx hir::Expr<'tcx>, &'tcx hir::FnDecl<'tcx>, ty::Asyncness)> {
94+
) -> Option<(
95+
&'tcx hir::Expr<'tcx>,
96+
&'tcx hir::FnDecl<'tcx>,
97+
ty::Asyncness,
98+
&'tcx [Param<'tcx>],
99+
)> {
93100
let mut data = None;
94101

95102
while let hir::ExprKind::Closure(closure) = expr.kind
@@ -110,6 +117,7 @@ fn find_innermost_closure<'tcx>(
110117
} else {
111118
ty::Asyncness::No
112119
},
120+
body.params,
113121
));
114122
steps -= 1;
115123
}
@@ -152,7 +160,9 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
152160
// without this check, we'd end up linting twice.
153161
&& !matches!(recv.kind, hir::ExprKind::Call(..))
154162
&& let (full_expr, call_depth) = get_parent_call_exprs(cx, expr)
155-
&& let Some((body, fn_decl, coroutine_kind)) = find_innermost_closure(cx, recv, call_depth)
163+
&& let Some((body, fn_decl, coroutine_kind, params)) = find_innermost_closure(cx, recv, call_depth)
164+
// outside macros we lint properly. Inside macros, we lint only ||() style closures.
165+
&& (!matches!(expr.span.ctxt().outer_expn_data().kind, ExpnKind::Macro(_, _)) || params.is_empty())
156166
{
157167
span_lint_and_then(
158168
cx,

Diff for: ‎tests/ui/redundant_closure_call_fixable.fixed

+9
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,12 @@ mod issue11707 {
102102
fn avoid_double_parens() {
103103
std::convert::identity(13_i32 + 36_i32).leading_zeros();
104104
}
105+
106+
fn fp_11274() {
107+
macro_rules! m {
108+
($closure:expr) => {
109+
$closure(1)
110+
};
111+
}
112+
m!(|x| println!("{x}"));
113+
}

Diff for: ‎tests/ui/redundant_closure_call_fixable.rs

+9
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,12 @@ mod issue11707 {
102102
fn avoid_double_parens() {
103103
std::convert::identity((|| 13_i32 + 36_i32)()).leading_zeros();
104104
}
105+
106+
fn fp_11274() {
107+
macro_rules! m {
108+
($closure:expr) => {
109+
$closure(1)
110+
};
111+
}
112+
m!(|x| println!("{x}"));
113+
}

0 commit comments

Comments
 (0)