@@ -449,7 +449,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
449
449
span,
450
450
leaf_trait_predicate,
451
451
) ;
452
- self . note_version_mismatch ( & mut err, leaf_trait_predicate) ;
452
+ self . note_version_mismatch ( & mut err, & obligation , leaf_trait_predicate) ;
453
453
self . suggest_remove_await ( & obligation, & mut err) ;
454
454
self . suggest_derive ( & obligation, & mut err, leaf_trait_predicate) ;
455
455
@@ -2346,6 +2346,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
2346
2346
fn note_version_mismatch (
2347
2347
& self ,
2348
2348
err : & mut Diag < ' _ > ,
2349
+ obligation : & PredicateObligation < ' tcx > ,
2349
2350
trait_pred : ty:: PolyTraitPredicate < ' tcx > ,
2350
2351
) -> bool {
2351
2352
let get_trait_impls = |trait_def_id| {
@@ -2372,6 +2373,49 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
2372
2373
let traits_with_same_path =
2373
2374
traits_with_same_path. into_items ( ) . into_sorted_stable_ord_by_key ( |( p, _) | p) ;
2374
2375
let mut suggested = false ;
2376
+ let trait_def_id = trait_pred. def_id ( ) ;
2377
+ let trait_has_same_params = |other_trait_def_id : DefId | -> bool {
2378
+ let trait_generics = self . tcx . generics_of ( trait_def_id) ;
2379
+ let other_trait_generics = self . tcx . generics_of ( other_trait_def_id) ;
2380
+
2381
+ if trait_generics. count ( ) != other_trait_generics. count ( ) {
2382
+ return false ;
2383
+ }
2384
+ trait_generics. own_params . iter ( ) . zip ( other_trait_generics. own_params . iter ( ) ) . all (
2385
+ |( a, b) | {
2386
+ ( matches ! ( a. kind, ty:: GenericParamDefKind :: Type { .. } )
2387
+ && matches ! ( b. kind, ty:: GenericParamDefKind :: Type { .. } ) )
2388
+ || ( matches ! ( a. kind, ty:: GenericParamDefKind :: Lifetime , )
2389
+ && matches ! ( b. kind, ty:: GenericParamDefKind :: Lifetime ) )
2390
+ || ( matches ! ( a. kind, ty:: GenericParamDefKind :: Const { .. } )
2391
+ && matches ! ( b. kind, ty:: GenericParamDefKind :: Const { .. } ) )
2392
+ } ,
2393
+ )
2394
+ } ;
2395
+
2396
+ let trait_name = self . tcx . item_name ( trait_def_id) ;
2397
+ if let Some ( other_trait_def_id) = self . tcx . all_traits_including_private ( ) . find ( |def_id| {
2398
+ trait_def_id != * def_id
2399
+ && trait_name == self . tcx . item_name ( def_id)
2400
+ && trait_has_same_params ( * def_id)
2401
+ && self . predicate_must_hold_modulo_regions ( & Obligation :: new (
2402
+ self . tcx ,
2403
+ obligation. cause . clone ( ) ,
2404
+ obligation. param_env ,
2405
+ trait_pred. map_bound ( |tr| ty:: TraitPredicate {
2406
+ trait_ref : ty:: TraitRef :: new ( self . tcx , * def_id, tr. trait_ref . args ) ,
2407
+ ..tr
2408
+ } ) ,
2409
+ ) )
2410
+ } ) {
2411
+ err. note ( format ! (
2412
+ "`{}` implements similarly named `{}`, but not `{}`" ,
2413
+ trait_pred. self_ty( ) ,
2414
+ self . tcx. def_path_str( other_trait_def_id) ,
2415
+ trait_pred. print_modifiers_and_trait_path( )
2416
+ ) ) ;
2417
+ suggested = true ;
2418
+ }
2375
2419
for ( _, trait_with_same_path) in traits_with_same_path {
2376
2420
let trait_impls = get_trait_impls ( trait_with_same_path) ;
2377
2421
if trait_impls. is_empty ( ) {
0 commit comments