@@ -5127,6 +5127,73 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
51275127 _ => { }
51285128 }
51295129 }
5130+ pub ( crate ) fn suggest_impl_similarly_named_trait (
5131+ & self ,
5132+ err : & mut Diag < ' _ > ,
5133+ obligation : & PredicateObligation < ' tcx > ,
5134+ trait_predicate : ty:: PolyTraitPredicate < ' tcx > ,
5135+ ) {
5136+ let trait_def_id = trait_predicate. def_id ( ) ;
5137+ let trait_name = self . tcx . item_name ( trait_def_id) ;
5138+
5139+ let trait_has_same_params = |other_trait_def_id : DefId | -> bool {
5140+ let trait_generics = self . tcx . generics_of ( trait_def_id) ;
5141+ let other_trait_generics = self . tcx . generics_of ( other_trait_def_id) ;
5142+
5143+ if trait_generics. count ( ) != other_trait_generics. count ( ) {
5144+ return false ;
5145+ }
5146+ trait_generics. own_params . iter ( ) . zip ( other_trait_generics. own_params . iter ( ) ) . all (
5147+ |( a, b) | {
5148+ a. name == b. name
5149+ && a. index == b. index
5150+ && ( ( matches ! ( a. kind, ty:: GenericParamDefKind :: Type { .. } )
5151+ && matches ! ( b. kind, ty:: GenericParamDefKind :: Type { .. } ) )
5152+ || ( matches ! ( a. kind, ty:: GenericParamDefKind :: Lifetime , )
5153+ && matches ! ( b. kind, ty:: GenericParamDefKind :: Lifetime ) )
5154+ || ( matches ! ( a. kind, ty:: GenericParamDefKind :: Const { .. } )
5155+ && matches ! ( b. kind, ty:: GenericParamDefKind :: Const { .. } ) ) )
5156+ } ,
5157+ )
5158+ } ;
5159+
5160+ if let Some ( other_trait_def_id) = self . tcx . all_traits_including_private ( ) . find ( |def_id| {
5161+ trait_def_id != * def_id
5162+ && trait_name == self . tcx . item_name ( def_id)
5163+ && trait_has_same_params ( * def_id)
5164+ && self
5165+ . tcx
5166+ . predicates_of ( * def_id)
5167+ . instantiate ( self . tcx , trait_predicate. skip_binder ( ) . trait_ref . args )
5168+ . predicates
5169+ . iter ( )
5170+ . find ( |clause| {
5171+ if clause
5172+ . as_trait_clause ( )
5173+ . map_or ( false , |trait_clause| trait_clause. def_id ( ) == * def_id)
5174+ == false
5175+ {
5176+ return false ;
5177+ }
5178+ let pred = clause. as_trait_clause ( ) . unwrap ( ) ;
5179+ self . predicate_must_hold_modulo_regions ( & Obligation :: new (
5180+ self . tcx ,
5181+ obligation. cause . clone ( ) ,
5182+ obligation. param_env ,
5183+ pred,
5184+ ) )
5185+ } )
5186+ . is_some ( )
5187+ } ) {
5188+ err. note ( format ! (
5189+ "`{}` implements similarly named `{}`, but not `{}`" ,
5190+ trait_predicate. self_ty( ) ,
5191+ self . tcx. def_path_str( other_trait_def_id) ,
5192+ trait_predicate. print_modifiers_and_trait_path( )
5193+ ) ) ;
5194+ }
5195+ ( )
5196+ }
51305197}
51315198
51325199/// Add a hint to add a missing borrow or remove an unnecessary one.
0 commit comments