@@ -197,6 +197,18 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx
197
197
// in a type which is `'static`.
198
198
// For now ignore all callee types which reference a type parameter.
199
199
&& !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
+ )
200
212
{
201
213
span_lint_hir_and_then (
202
214
cx,
@@ -213,19 +225,10 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx
213
225
// 'cuz currently nothing changes after deleting this check.
214
226
local_used_in ( cx, l, args) || local_used_after_expr ( cx, l, expr)
215
227
} ) {
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 {
226
229
// 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 ( ) => {
229
232
snippet = format ! ( "&{snippet}" ) ;
230
233
} ,
231
234
_ => ( ) ,
0 commit comments