@@ -16,7 +16,7 @@ use rustc_ast::{LitFloatType, LitIntType, LitKind};
16
16
use rustc_hir:: def:: { DefKind , Res } ;
17
17
use rustc_hir:: def_id:: DefId ;
18
18
use rustc_hir:: intravisit:: { InferKind , Visitor , VisitorExt , walk_qpath, walk_ty} ;
19
- use rustc_hir:: { self as hir, AmbigArg , Expr , ExprKind , GenericArgs , HirId , Node , PathSegment , QPath , TyKind } ;
19
+ use rustc_hir:: { self as hir, AmbigArg , Expr , ExprKind , GenericArgs , HirId , Node , Param , PathSegment , QPath , TyKind } ;
20
20
use rustc_lint:: LateContext ;
21
21
use rustc_middle:: ty:: { self , AdtDef , GenericArgKind , Ty } ;
22
22
use rustc_span:: Span ;
@@ -215,6 +215,20 @@ fn qpath_certainty(cx: &LateContext<'_>, qpath: &QPath<'_>, resolves_to_type: bo
215
215
certainty
216
216
}
217
217
218
+ /// Tries to tell whether `param` resolves to something certain, e.g., a non-wildcard type if
219
+ /// present. The certainty `DefId` is cleared before returning.
220
+ fn param_certainty ( cx : & LateContext < ' _ > , param : & Param < ' _ > ) -> Certainty {
221
+ let owner_did = cx. tcx . hir_enclosing_body_owner ( param. hir_id ) ;
222
+ let Some ( fn_decl) = cx. tcx . hir_fn_decl_by_hir_id ( cx. tcx . local_def_id_to_hir_id ( owner_did) ) else {
223
+ return Certainty :: Uncertain ;
224
+ } ;
225
+ let inputs = fn_decl. inputs ;
226
+ let body_params = cx. tcx . hir_body_owned_by ( owner_did) . params ;
227
+ std:: iter:: zip ( body_params, inputs)
228
+ . find ( |( p, _) | p. hir_id == param. hir_id )
229
+ . map_or ( Certainty :: Uncertain , |( _, ty) | type_certainty ( cx, ty) . clear_def_id ( ) )
230
+ }
231
+
218
232
fn path_segment_certainty (
219
233
cx : & LateContext < ' _ > ,
220
234
parent_certainty : Certainty ,
@@ -267,8 +281,9 @@ fn path_segment_certainty(
267
281
268
282
// `get_parent` because `hir_id` refers to a `Pat`, and we're interested in the node containing the `Pat`.
269
283
Res :: Local ( hir_id) => match cx. tcx . parent_hir_node ( hir_id) {
270
- // An argument's type is always certain.
271
- Node :: Param ( ..) => Certainty :: Certain ( None ) ,
284
+ // A parameter's type is not always certain, as it may come from an untyped closure definition,
285
+ // or from a wildcard in a typed closure definition.
286
+ Node :: Param ( param) => param_certainty ( cx, param) ,
272
287
// A local's type is certain if its type annotation is certain or it has an initializer whose
273
288
// type is certain.
274
289
Node :: LetStmt ( local) => {
0 commit comments