@@ -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 _ => ( ) ,
0 commit comments