@@ -16,7 +16,7 @@ use rustc_ast::{LitFloatType, LitIntType, LitKind};
1616use rustc_hir:: def:: { DefKind , Res } ;
1717use rustc_hir:: def_id:: DefId ;
1818use 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 } ;
2020use rustc_lint:: LateContext ;
2121use rustc_middle:: ty:: { self , AdtDef , GenericArgKind , Ty } ;
2222use rustc_span:: Span ;
@@ -215,6 +215,20 @@ fn qpath_certainty(cx: &LateContext<'_>, qpath: &QPath<'_>, resolves_to_type: bo
215215 certainty
216216}
217217
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+
218232fn path_segment_certainty (
219233 cx : & LateContext < ' _ > ,
220234 parent_certainty : Certainty ,
@@ -267,8 +281,9 @@ fn path_segment_certainty(
267281
268282 // `get_parent` because `hir_id` refers to a `Pat`, and we're interested in the node containing the `Pat`.
269283 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) ,
272287 // A local's type is certain if its type annotation is certain or it has an initializer whose
273288 // type is certain.
274289 Node :: LetStmt ( local) => {
0 commit comments