@@ -551,15 +551,40 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
551551 let id_substs = InternalSubsts :: identity_for_item ( tcx, def_id) ;
552552 debug ! ( ?id_substs, ?substs) ;
553553 let map: FxHashMap < ty:: GenericArg < ' tcx > , ty:: GenericArg < ' tcx > > =
554- substs . iter ( ) . enumerate ( ) . map ( | ( index , arg ) | ( arg , id_substs[ index ] ) ) . collect ( ) ;
554+ std :: iter:: zip ( substs , id_substs) . collect ( ) ;
555555 debug ! ( ?map) ;
556556
557+ // NOTE(compiler-errors): RPITITs, like all other RPITs, have early-bound
558+ // region substs that are synthesized during AST lowering. These are substs
559+ // that are appended to the parent substs (trait and trait method). However,
560+ // we're trying to infer the unsubstituted type value of the RPITIT inside
561+ // the *impl*, so we can later use the impl's method substitutions to normalize
562+ // an RPITIT to a concrete type.
563+ //
564+ // Due to the design of RPITITs, during AST lowering, we have no idea that
565+ // an impl method is satisfying a trait method with RPITITs in it. Therefore,
566+ // we don't have a list ofearly-bound region substs for the RPITIT in the impl.
567+ // Since early region parameters are index-based, we can't just rebase these
568+ // (trait method) early-bound region substs onto the impl, since region
569+ // parameters are index-based, and there's no guarantee that the indices from
570+ // the trait substs and impl substs line up -- so we subtract the number of
571+ // trait substs and add the number of impl substs to *renumber* these early-
572+ // bound regions to their corresponding indices in the impl's substitutions list.
573+ //
574+ // Also, we only need to account for a difference in trait and impl substs,
575+ // since we previously enforce that the trait method and impl method have the
576+ // same generics.
577+ let num_trait_substs = trait_to_impl_substs. len ( ) ;
578+ let num_impl_substs = tcx. generics_of ( impl_m. container_id ( tcx) ) . params . len ( ) ;
557579 let ty = tcx. fold_regions ( ty, |region, _| {
558- if let ty:: ReFree ( _) = region. kind ( ) {
559- map[ & region. into ( ) ] . expect_region ( )
560- } else {
561- region
562- }
580+ let ty:: ReFree ( _) = region. kind ( ) else { return region; } ;
581+ let ty:: ReEarlyBound ( e) = map[ & region. into ( ) ] . expect_region ( ) . kind ( )
582+ else { bug ! ( "expected ReFree to map to ReEarlyBound" ) ; } ;
583+ tcx. mk_region ( ty:: ReEarlyBound ( ty:: EarlyBoundRegion {
584+ def_id : e. def_id ,
585+ name : e. name ,
586+ index : ( e. index as usize - num_trait_substs + num_impl_substs) as u32 ,
587+ } ) )
563588 } ) ;
564589 debug ! ( %ty) ;
565590 collected_tys. insert ( def_id, ty) ;
0 commit comments