@@ -214,7 +214,8 @@ pub fn implements_trait<'tcx>(
214214 trait_id : DefId ,
215215 args : & [ GenericArg < ' tcx > ] ,
216216) -> bool {
217- implements_trait_with_env_from_iter ( cx. tcx , cx. param_env , ty, trait_id, args. iter ( ) . map ( |& x| Some ( x) ) )
217+ let callee_id = cx. enclosing_body . map ( |body| cx. tcx . hir ( ) . body_owner ( body) . owner . to_def_id ( ) ) ;
218+ implements_trait_with_env_from_iter ( cx. tcx , cx. param_env , ty, trait_id, callee_id, args. iter ( ) . map ( |& x| Some ( x) ) )
218219}
219220
220221/// Same as `implements_trait` but allows using a `ParamEnv` different from the lint context.
@@ -223,9 +224,10 @@ pub fn implements_trait_with_env<'tcx>(
223224 param_env : ParamEnv < ' tcx > ,
224225 ty : Ty < ' tcx > ,
225226 trait_id : DefId ,
227+ callee_id : DefId ,
226228 args : & [ GenericArg < ' tcx > ] ,
227229) -> bool {
228- implements_trait_with_env_from_iter ( tcx, param_env, ty, trait_id, args. iter ( ) . map ( |& x| Some ( x) ) )
230+ implements_trait_with_env_from_iter ( tcx, param_env, ty, trait_id, Some ( callee_id ) , args. iter ( ) . map ( |& x| Some ( x) ) )
229231}
230232
231233/// Same as `implements_trait_from_env` but takes the arguments as an iterator.
@@ -234,6 +236,7 @@ pub fn implements_trait_with_env_from_iter<'tcx>(
234236 param_env : ParamEnv < ' tcx > ,
235237 ty : Ty < ' tcx > ,
236238 trait_id : DefId ,
239+ callee_id : Option < DefId > ,
237240 args : impl IntoIterator < Item = impl Into < Option < GenericArg < ' tcx > > > > ,
238241) -> bool {
239242 // Clippy shouldn't have infer types
@@ -245,20 +248,29 @@ pub fn implements_trait_with_env_from_iter<'tcx>(
245248 }
246249
247250 let infcx = tcx. infer_ctxt ( ) . build ( ) ;
251+ let args = args. into_iter ( ) . map ( |arg| {
252+ arg. into ( ) . unwrap_or_else ( || {
253+ let orig = TypeVariableOrigin {
254+ kind : TypeVariableOriginKind :: MiscVariable ,
255+ span : DUMMY_SP ,
256+ } ;
257+ infcx. next_ty_var ( orig) . into ( )
258+ } )
259+ } ) . collect :: < Vec < _ > > ( ) ;
260+
261+ // If an effect arg was not specified, we need to specify it.
262+ let effect_arg = if tcx. generics_of ( trait_id) . host_effect_index . is_some_and ( |x| args. get ( x - 1 ) . is_none ( ) ) {
263+ Some ( GenericArg :: from ( callee_id. map ( |def_id| tcx. expected_host_effect_param_for_body ( def_id) ) . unwrap_or ( tcx. consts . true_ ) ) )
264+ } else {
265+ None
266+ } ;
267+
248268 let trait_ref = TraitRef :: new (
249269 tcx,
250270 trait_id,
251271 Some ( GenericArg :: from ( ty) )
252272 . into_iter ( )
253- . chain ( args. into_iter ( ) . map ( |arg| {
254- arg. into ( ) . unwrap_or_else ( || {
255- let orig = TypeVariableOrigin {
256- kind : TypeVariableOriginKind :: MiscVariable ,
257- span : DUMMY_SP ,
258- } ;
259- infcx. next_ty_var ( orig) . into ( )
260- } )
261- } ) ) ,
273+ . chain ( args) . chain ( effect_arg) ,
262274 ) ;
263275
264276 debug_assert_matches ! (
0 commit comments