@@ -2146,10 +2146,10 @@ fn confirm_impl_candidate<'cx, 'tcx>(
21462146 } else {
21472147 ty. map_bound ( |ty| ty. into ( ) )
21482148 } ;
2149- if substs . len ( ) != tcx . generics_of ( assoc_ty. item . def_id ) . count ( ) {
2149+ if ! check_substs_compatible ( tcx , & assoc_ty. item , substs ) {
21502150 let err = tcx. ty_error_with_message (
21512151 obligation. cause . span ,
2152- "impl item and trait item have different parameter counts " ,
2152+ "impl item and trait item have different parameters " ,
21532153 ) ;
21542154 Progress { term : err. into ( ) , obligations : nested }
21552155 } else {
@@ -2158,6 +2158,44 @@ fn confirm_impl_candidate<'cx, 'tcx>(
21582158 }
21592159}
21602160
2161+ // Verify that the trait item and its implementation have compatible substs lists
2162+ fn check_substs_compatible < ' tcx > (
2163+ tcx : TyCtxt < ' tcx > ,
2164+ assoc_ty : & ty:: AssocItem ,
2165+ substs : ty:: SubstsRef < ' tcx > ,
2166+ ) -> bool {
2167+ fn check_substs_compatible_inner < ' tcx > (
2168+ tcx : TyCtxt < ' tcx > ,
2169+ generics : & ' tcx ty:: Generics ,
2170+ args : & ' tcx [ ty:: GenericArg < ' tcx > ] ,
2171+ ) -> bool {
2172+ if generics. count ( ) != args. len ( ) {
2173+ return false ;
2174+ }
2175+
2176+ let ( parent_args, own_args) = args. split_at ( generics. parent_count ) ;
2177+
2178+ if let Some ( parent) = generics. parent
2179+ && let parent_generics = tcx. generics_of ( parent)
2180+ && !check_substs_compatible_inner ( tcx, parent_generics, parent_args) {
2181+ return false ;
2182+ }
2183+
2184+ for ( param, arg) in std:: iter:: zip ( & generics. params , own_args) {
2185+ match ( & param. kind , arg. unpack ( ) ) {
2186+ ( ty:: GenericParamDefKind :: Type { .. } , ty:: GenericArgKind :: Type ( _) )
2187+ | ( ty:: GenericParamDefKind :: Lifetime , ty:: GenericArgKind :: Lifetime ( _) )
2188+ | ( ty:: GenericParamDefKind :: Const { .. } , ty:: GenericArgKind :: Const ( _) ) => { }
2189+ _ => return false ,
2190+ }
2191+ }
2192+
2193+ true
2194+ }
2195+
2196+ check_substs_compatible_inner ( tcx, tcx. generics_of ( assoc_ty. def_id ) , substs. as_slice ( ) )
2197+ }
2198+
21612199fn confirm_impl_trait_in_trait_candidate < ' tcx > (
21622200 selcx : & mut SelectionContext < ' _ , ' tcx > ,
21632201 obligation : & ProjectionTyObligation < ' tcx > ,
0 commit comments