@@ -8,6 +8,7 @@ use rustc_hir::intravisit::FnKind;
8
8
use rustc_hir:: { self as hir, Body , Constness , FnDecl , GenericParamKind } ;
9
9
use rustc_lint:: { LateContext , LateLintPass } ;
10
10
use rustc_middle:: lint:: in_external_macro;
11
+ use rustc_middle:: ty;
11
12
use rustc_session:: impl_lint_pass;
12
13
use rustc_span:: def_id:: LocalDefId ;
13
14
use rustc_span:: Span ;
@@ -131,6 +132,10 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
131
132
FnKind :: Closure => return ,
132
133
}
133
134
135
+ if fn_inputs_has_impl_trait_ty ( cx, def_id) {
136
+ return ;
137
+ }
138
+
134
139
let hir_id = cx. tcx . local_def_id_to_hir_id ( def_id) ;
135
140
136
141
// Const fns are not allowed as methods in a trait.
@@ -185,3 +190,17 @@ fn could_be_const_with_abi(cx: &LateContext<'_>, msrv: &Msrv, abi: Abi) -> bool
185
190
_ => cx. tcx . features ( ) . const_extern_fn ,
186
191
}
187
192
}
193
+
194
+ /// Return `true` when the given `def_id` is a function that has `impl Trait` ty as one of
195
+ /// its parameter types.
196
+ fn fn_inputs_has_impl_trait_ty ( cx : & LateContext < ' _ > , def_id : LocalDefId ) -> bool {
197
+ let inputs = cx. tcx . fn_sig ( def_id) . instantiate_identity ( ) . inputs ( ) . skip_binder ( ) ;
198
+ inputs. iter ( ) . any ( |input| {
199
+ // NB: Other alias ty kind might missing default.
200
+ // For example, an associate type alias declared as `type T: Fn();`
201
+ // would cause ICE when `type_of` is called with it.
202
+ matches ! (
203
+ input. kind( ) ,
204
+ ty:: Alias ( ty:: AliasTyKind :: Weak , alias_ty) if cx. tcx. type_of( alias_ty. def_id) . skip_binder( ) . is_impl_trait( ) )
205
+ } )
206
+ }
0 commit comments