@@ -341,39 +341,48 @@ impl<T> Trait<T> for X {
341341 let tcx = self . tcx ;
342342 let assoc = tcx. associated_item ( proj_ty. def_id ) ;
343343 let ( trait_ref, assoc_args) = proj_ty. trait_ref_and_own_args ( tcx) ;
344- if let Some ( item) = tcx. hir ( ) . get_if_local ( body_owner_def_id) {
345- if let Some ( hir_generics) = item. generics ( ) {
346- // Get the `DefId` for the type parameter corresponding to `A` in `<A as T>::Foo`.
347- // This will also work for `impl Trait`.
348- let def_id = if let ty:: Param ( param_ty) = proj_ty. self_ty ( ) . kind ( ) {
349- let generics = tcx. generics_of ( body_owner_def_id) ;
350- generics. type_param ( param_ty, tcx) . def_id
351- } else {
352- return false ;
353- } ;
354- let Some ( def_id) = def_id. as_local ( ) else {
355- return false ;
356- } ;
357-
358- // First look in the `where` clause, as this might be
359- // `fn foo<T>(x: T) where T: Trait`.
360- for pred in hir_generics. bounds_for_param ( def_id) {
361- if self . constrain_generic_bound_associated_type_structured_suggestion (
362- diag,
363- & trait_ref,
364- pred. bounds ,
365- assoc,
366- assoc_args,
367- ty,
368- & msg,
369- false ,
370- ) {
371- return true ;
372- }
373- }
344+ let Some ( item) = tcx. hir ( ) . get_if_local ( body_owner_def_id) else {
345+ return false ;
346+ } ;
347+ let Some ( hir_generics) = item. generics ( ) else {
348+ return false ;
349+ } ;
350+ // Get the `DefId` for the type parameter corresponding to `A` in `<A as T>::Foo`.
351+ // This will also work for `impl Trait`.
352+ let def_id = if let ty:: Param ( param_ty) = proj_ty. self_ty ( ) . kind ( ) {
353+ let generics = tcx. generics_of ( body_owner_def_id) ;
354+ generics. type_param ( param_ty, tcx) . def_id
355+ } else {
356+ return false ;
357+ } ;
358+ let Some ( def_id) = def_id. as_local ( ) else {
359+ return false ;
360+ } ;
361+
362+ // First look in the `where` clause, as this might be
363+ // `fn foo<T>(x: T) where T: Trait`.
364+ for pred in hir_generics. bounds_for_param ( def_id) {
365+ if self . constrain_generic_bound_associated_type_structured_suggestion (
366+ diag,
367+ & trait_ref,
368+ pred. bounds ,
369+ assoc,
370+ assoc_args,
371+ ty,
372+ & msg,
373+ false ,
374+ ) {
375+ return true ;
374376 }
375377 }
376- false
378+ // If associated item, look to constrain the params of the trait/impl.
379+ let hir_id = match item {
380+ hir:: Node :: ImplItem ( item) => item. hir_id ( ) ,
381+ hir:: Node :: TraitItem ( item) => item. hir_id ( ) ,
382+ _ => return false ,
383+ } ;
384+ let parent = tcx. hir ( ) . get_parent_item ( hir_id) . def_id ;
385+ self . suggest_constraint ( diag, msg, parent. into ( ) , proj_ty, ty)
377386 }
378387
379388 /// An associated type was expected and a different type was found.
@@ -426,21 +435,26 @@ impl<T> Trait<T> for X {
426435 let impl_comparison =
427436 matches ! ( cause_code, ObligationCauseCode :: CompareImplItemObligation { .. } ) ;
428437 let assoc = tcx. associated_item ( proj_ty. def_id ) ;
429- if !callable_scope || impl_comparison {
438+ if impl_comparison {
430439 // We do not want to suggest calling functions when the reason of the
431- // type error is a comparison of an `impl` with its `trait` or when the
432- // scope is outside of a `Body`.
440+ // type error is a comparison of an `impl` with its `trait`.
433441 } else {
434- // If we find a suitable associated function that returns the expected type, we don't
435- // want the more general suggestion later in this method about "consider constraining
436- // the associated type or calling a method that returns the associated type".
437- let point_at_assoc_fn = self . point_at_methods_that_satisfy_associated_type (
438- diag,
439- assoc. container_id ( tcx) ,
440- current_method_ident,
441- proj_ty. def_id ,
442- values. expected ,
443- ) ;
442+ let point_at_assoc_fn = if callable_scope
443+ && self . point_at_methods_that_satisfy_associated_type (
444+ diag,
445+ assoc. container_id ( tcx) ,
446+ current_method_ident,
447+ proj_ty. def_id ,
448+ values. expected ,
449+ ) {
450+ // If we find a suitable associated function that returns the expected type, we
451+ // don't want the more general suggestion later in this method about "consider
452+ // constraining the associated type or calling a method that returns the associated
453+ // type".
454+ true
455+ } else {
456+ false
457+ } ;
444458 // Possibly suggest constraining the associated type to conform to the
445459 // found type.
446460 if self . suggest_constraint ( diag, & msg, body_owner_def_id, proj_ty, values. found )
0 commit comments