@@ -341,39 +341,48 @@ impl<T> Trait<T> for X {
341
341
let tcx = self . tcx ;
342
342
let assoc = tcx. associated_item ( proj_ty. def_id ) ;
343
343
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 ;
374
376
}
375
377
}
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)
377
386
}
378
387
379
388
/// An associated type was expected and a different type was found.
@@ -426,21 +435,26 @@ impl<T> Trait<T> for X {
426
435
let impl_comparison =
427
436
matches ! ( cause_code, ObligationCauseCode :: CompareImplItemObligation { .. } ) ;
428
437
let assoc = tcx. associated_item ( proj_ty. def_id ) ;
429
- if !callable_scope || impl_comparison {
438
+ if impl_comparison {
430
439
// 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`.
433
441
} 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
+ } ;
444
458
// Possibly suggest constraining the associated type to conform to the
445
459
// found type.
446
460
if self . suggest_constraint ( diag, & msg, body_owner_def_id, proj_ty, values. found )
0 commit comments