Skip to content

Commit e4f69ea

Browse files
committed
fix(needless_closure): don't lint on AsyncFn*s
1 parent 49e2f37 commit e4f69ea

File tree

3 files changed

+31
-12
lines changed

3 files changed

+31
-12
lines changed

clippy_lints/src/eta_reduction.rs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,18 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx
197197
// in a type which is `'static`.
198198
// For now ignore all callee types which reference a type parameter.
199199
&& !generic_args.types().any(|t| matches!(t.kind(), ty::Param(_)))
200+
// Rule out `AsyncFn*`s, because while they can be called as `|x| f(x)`,
201+
// they can't be passed directly into a place expecting an `Fn*` (#13892)
202+
&& let Ok((closure_kind, _)) = cx
203+
.tcx
204+
.infer_ctxt()
205+
.build(cx.typing_mode())
206+
.err_ctxt()
207+
.type_implements_fn_trait(
208+
cx.param_env,
209+
Binder::bind_with_vars(callee_ty_adjusted, List::empty()),
210+
ty::PredicatePolarity::Positive,
211+
)
200212
{
201213
span_lint_hir_and_then(
202214
cx,
@@ -213,19 +225,10 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx
213225
// 'cuz currently nothing changes after deleting this check.
214226
local_used_in(cx, l, args) || local_used_after_expr(cx, l, expr)
215227
}) {
216-
match cx
217-
.tcx
218-
.infer_ctxt()
219-
.build(cx.typing_mode())
220-
.err_ctxt()
221-
.type_implements_fn_trait(
222-
cx.param_env,
223-
Binder::bind_with_vars(callee_ty_adjusted, List::empty()),
224-
ty::PredicatePolarity::Positive,
225-
) {
228+
match closure_kind {
226229
// Mutable closure is used after current expr; we cannot consume it.
227-
Ok((ClosureKind::FnMut, _)) => snippet = format!("&mut {snippet}"),
228-
Ok((ClosureKind::Fn, _)) if !callee_ty_raw.is_ref() => {
230+
ClosureKind::FnMut => snippet = format!("&mut {snippet}"),
231+
ClosureKind::Fn if !callee_ty_raw.is_ref() => {
229232
snippet = format!("&{snippet}");
230233
},
231234
_ => (),

tests/ui/eta.fixed

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,3 +635,11 @@ fn issue8817() {
635635
//~| HELP: replace the closure with the tuple variant itself
636636
.unwrap(); // just for nicer formatting
637637
}
638+
639+
async fn issue13892<'a, T, F>(maybe: Option<&'a T>, visitor: F)
640+
where
641+
F: AsyncFn(&'a T),
642+
T: 'a,
643+
{
644+
maybe.map(|x| visitor(x));
645+
}

tests/ui/eta.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,3 +635,11 @@ fn issue8817() {
635635
//~| HELP: replace the closure with the tuple variant itself
636636
.unwrap(); // just for nicer formatting
637637
}
638+
639+
async fn issue13892<'a, T, F>(maybe: Option<&'a T>, visitor: F)
640+
where
641+
F: AsyncFn(&'a T),
642+
T: 'a,
643+
{
644+
maybe.map(|x| visitor(x));
645+
}

0 commit comments

Comments
 (0)