@@ -449,7 +449,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
449449 span,
450450 leaf_trait_predicate,
451451 ) ;
452- self . note_version_mismatch ( & mut err, leaf_trait_predicate) ;
452+ self . note_version_mismatch ( & mut err, & obligation , leaf_trait_predicate) ;
453453 self . suggest_remove_await ( & obligation, & mut err) ;
454454 self . suggest_derive ( & obligation, & mut err, leaf_trait_predicate) ;
455455
@@ -2346,6 +2346,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
23462346 fn note_version_mismatch (
23472347 & self ,
23482348 err : & mut Diag < ' _ > ,
2349+ obligation : & PredicateObligation < ' tcx > ,
23492350 trait_pred : ty:: PolyTraitPredicate < ' tcx > ,
23502351 ) -> bool {
23512352 let get_trait_impls = |trait_def_id| {
@@ -2372,6 +2373,49 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
23722373 let traits_with_same_path =
23732374 traits_with_same_path. into_items ( ) . into_sorted_stable_ord_by_key ( |( p, _) | p) ;
23742375 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+ }
23752419 for ( _, trait_with_same_path) in traits_with_same_path {
23762420 let trait_impls = get_trait_impls ( trait_with_same_path) ;
23772421 if trait_impls. is_empty ( ) {
0 commit comments