@@ -19,7 +19,7 @@ use rustc_middle::ty::{
1919 self , InternalSubsts , Ty , TypeFoldable , TypeFolder , TypeSuperFoldable , TypeVisitableExt ,
2020} ;
2121use rustc_middle:: ty:: { GenericParamDefKind , ToPredicate , TyCtxt } ;
22- use rustc_span:: Span ;
22+ use rustc_span:: { Span , DUMMY_SP } ;
2323use rustc_trait_selection:: traits:: error_reporting:: TypeErrCtxtExt ;
2424use rustc_trait_selection:: traits:: outlives_bounds:: InferCtxtExt as _;
2525use rustc_trait_selection:: traits:: {
@@ -767,8 +767,10 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
767767 // contains `def_id`'s early-bound regions.
768768 let id_substs = InternalSubsts :: identity_for_item ( tcx, def_id) ;
769769 debug ! ( ?id_substs, ?substs) ;
770- let map: FxHashMap < ty:: GenericArg < ' tcx > , ty:: GenericArg < ' tcx > > =
771- std:: iter:: zip ( substs, id_substs) . collect ( ) ;
770+ let map: FxHashMap < _ , _ > = std:: iter:: zip ( substs, id_substs)
771+ . skip ( tcx. generics_of ( trait_m. def_id ) . count ( ) )
772+ . filter_map ( |( a, b) | Some ( ( a. as_region ( ) ?, b. as_region ( ) ?) ) )
773+ . collect ( ) ;
772774 debug ! ( ?map) ;
773775
774776 // NOTE(compiler-errors): RPITITs, like all other RPITs, have early-bound
@@ -793,25 +795,19 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
793795 // same generics.
794796 let num_trait_substs = trait_to_impl_substs. len ( ) ;
795797 let num_impl_substs = tcx. generics_of ( impl_m. container_id ( tcx) ) . params . len ( ) ;
796- let ty = tcx. fold_regions ( ty, |region, _| {
797- match region. kind ( ) {
798- // Remap all free regions, which correspond to late-bound regions in the function.
799- ty:: ReFree ( _) => { }
800- // Remap early-bound regions as long as they don't come from the `impl` itself.
801- ty:: ReEarlyBound ( ebr) if tcx. parent ( ebr. def_id ) != impl_m. container_id ( tcx) => { }
802- _ => return region,
803- }
804- let Some ( ty:: ReEarlyBound ( e) ) = map. get ( & region. into ( ) ) . map ( |r| r. expect_region ( ) . kind ( ) )
805- else {
806- return ty:: Region :: new_error_with_message ( tcx, return_span, "expected ReFree to map to ReEarlyBound" )
807- } ;
808- ty:: Region :: new_early_bound ( tcx, ty:: EarlyBoundRegion {
809- def_id : e. def_id ,
810- name : e. name ,
811- index : ( e. index as usize - num_trait_substs + num_impl_substs) as u32 ,
812- } )
813- } ) ;
814- debug ! ( %ty) ;
798+ let ty = match ty. try_fold_with ( & mut RemapHiddenTyRegions {
799+ tcx,
800+ map,
801+ num_trait_substs,
802+ num_impl_substs,
803+ def_id,
804+ impl_def_id : impl_m. container_id ( tcx) ,
805+ ty,
806+ return_span,
807+ } ) {
808+ Ok ( ty) => ty,
809+ Err ( guar) => tcx. ty_error ( guar) ,
810+ } ;
815811 collected_tys. insert ( def_id, ty:: EarlyBinder :: bind ( ty) ) ;
816812 }
817813 Err ( err) => {
@@ -895,6 +891,97 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx> {
895891 }
896892}
897893
894+ struct RemapHiddenTyRegions < ' tcx > {
895+ tcx : TyCtxt < ' tcx > ,
896+ map : FxHashMap < ty:: Region < ' tcx > , ty:: Region < ' tcx > > ,
897+ num_trait_substs : usize ,
898+ num_impl_substs : usize ,
899+ def_id : DefId ,
900+ impl_def_id : DefId ,
901+ ty : Ty < ' tcx > ,
902+ return_span : Span ,
903+ }
904+
905+ impl < ' tcx > ty:: FallibleTypeFolder < TyCtxt < ' tcx > > for RemapHiddenTyRegions < ' tcx > {
906+ type Error = ErrorGuaranteed ;
907+
908+ fn interner ( & self ) -> TyCtxt < ' tcx > {
909+ self . tcx
910+ }
911+
912+ fn try_fold_ty ( & mut self , t : Ty < ' tcx > ) -> Result < Ty < ' tcx > , Self :: Error > {
913+ if let ty:: Alias ( ty:: Opaque , ty:: AliasTy { substs, def_id, .. } ) = * t. kind ( ) {
914+ let mut mapped_substs = Vec :: with_capacity ( substs. len ( ) ) ;
915+ for ( arg, v) in std:: iter:: zip ( substs, self . tcx . variances_of ( def_id) ) {
916+ mapped_substs. push ( match ( arg. unpack ( ) , v) {
917+ // Skip uncaptured opaque substs
918+ ( ty:: GenericArgKind :: Lifetime ( _) , ty:: Bivariant ) => arg,
919+ _ => arg. try_fold_with ( self ) ?,
920+ } ) ;
921+ }
922+ Ok ( self . tcx . mk_opaque ( def_id, self . tcx . mk_substs ( & mapped_substs) ) )
923+ } else {
924+ t. try_super_fold_with ( self )
925+ }
926+ }
927+
928+ fn try_fold_region (
929+ & mut self ,
930+ region : ty:: Region < ' tcx > ,
931+ ) -> Result < ty:: Region < ' tcx > , Self :: Error > {
932+ match region. kind ( ) {
933+ // Remap all free regions, which correspond to late-bound regions in the function.
934+ ty:: ReFree ( _) => { }
935+ // Remap early-bound regions as long as they don't come from the `impl` itself,
936+ // in which case we don't really need to renumber them.
937+ ty:: ReEarlyBound ( ebr) if self . tcx . parent ( ebr. def_id ) != self . impl_def_id => { }
938+ _ => return Ok ( region) ,
939+ }
940+
941+ let e = if let Some ( region) = self . map . get ( & region) {
942+ if let ty:: ReEarlyBound ( e) = region. kind ( ) { e } else { bug ! ( ) }
943+ } else {
944+ let guar = match region. kind ( ) {
945+ ty:: ReEarlyBound ( ty:: EarlyBoundRegion { def_id, .. } )
946+ | ty:: ReFree ( ty:: FreeRegion {
947+ bound_region : ty:: BoundRegionKind :: BrNamed ( def_id, _) ,
948+ ..
949+ } ) => {
950+ let return_span = if let ty:: Alias ( ty:: Opaque , opaque_ty) = self . ty . kind ( ) {
951+ self . tcx . def_span ( opaque_ty. def_id )
952+ } else {
953+ self . return_span
954+ } ;
955+ self . tcx
956+ . sess
957+ . struct_span_err (
958+ return_span,
959+ "return type captures more lifetimes than trait definition" ,
960+ )
961+ . span_label ( self . tcx . def_span ( def_id) , "this lifetime was captured" )
962+ . span_note (
963+ self . tcx . def_span ( self . def_id ) ,
964+ "hidden type must only reference lifetimes captured by this impl trait" ,
965+ )
966+ . note ( format ! ( "hidden type inferred to be `{}`" , self . ty) )
967+ . emit ( )
968+ }
969+ _ => self . tcx . sess . delay_span_bug ( DUMMY_SP , "should've been able to remap region" ) ,
970+ } ;
971+ return Err ( guar) ;
972+ } ;
973+
974+ Ok ( ty:: Region :: new_early_bound (
975+ self . tcx ,
976+ ty:: EarlyBoundRegion {
977+ def_id : e. def_id ,
978+ name : e. name ,
979+ index : ( e. index as usize - self . num_trait_substs + self . num_impl_substs ) as u32 ,
980+ } ,
981+ ) )
982+ }
983+ }
984+
898985fn report_trait_method_mismatch < ' tcx > (
899986 infcx : & InferCtxt < ' tcx > ,
900987 mut cause : ObligationCause < ' tcx > ,
0 commit comments