@@ -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:: {
@@ -651,11 +651,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
651651 let impl_sig = ocx. normalize (
652652 & norm_cause,
653653 param_env,
654- infcx. instantiate_binder_with_fresh_vars (
655- return_span,
656- infer:: HigherRankedType ,
657- tcx. fn_sig ( impl_m. def_id ) . subst_identity ( ) ,
658- ) ,
654+ tcx. liberate_late_bound_regions ( impl_m. def_id , tcx. fn_sig ( impl_m. def_id ) . subst_identity ( ) ) ,
659655 ) ;
660656 impl_sig. error_reported ( ) ?;
661657 let impl_return_ty = impl_sig. output ( ) ;
@@ -665,9 +661,10 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
665661 // them with inference variables.
666662 // We will use these inference variables to collect the hidden types of RPITITs.
667663 let mut collector = ImplTraitInTraitCollector :: new ( & ocx, return_span, param_env, impl_m_def_id) ;
668- let unnormalized_trait_sig = tcx
669- . liberate_late_bound_regions (
670- impl_m. def_id ,
664+ let unnormalized_trait_sig = infcx
665+ . instantiate_binder_with_fresh_vars (
666+ return_span,
667+ infer:: HigherRankedType ,
671668 tcx. fn_sig ( trait_m. def_id ) . subst ( tcx, trait_to_placeholder_substs) ,
672669 )
673670 . fold_with ( & mut collector) ;
@@ -760,15 +757,17 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
760757
761758 let mut collected_tys = FxHashMap :: default ( ) ;
762759 for ( def_id, ( ty, substs) ) in collected_types {
763- match infcx. fully_resolve ( ty ) {
764- Ok ( ty ) => {
760+ match infcx. fully_resolve ( ( ty , substs ) ) {
761+ Ok ( ( ty , substs ) ) => {
765762 // `ty` contains free regions that we created earlier while liberating the
766763 // trait fn signature. However, projection normalization expects `ty` to
767764 // contains `def_id`'s early-bound regions.
768765 let id_substs = InternalSubsts :: identity_for_item ( tcx, def_id) ;
769766 debug ! ( ?id_substs, ?substs) ;
770- let map: FxHashMap < ty:: GenericArg < ' tcx > , ty:: GenericArg < ' tcx > > =
771- std:: iter:: zip ( substs, id_substs) . collect ( ) ;
767+ let map: FxHashMap < _ , _ > = std:: iter:: zip ( substs, id_substs)
768+ . skip ( tcx. generics_of ( trait_m. def_id ) . count ( ) )
769+ . filter_map ( |( a, b) | Some ( ( a. as_region ( ) ?, b. as_region ( ) ?) ) )
770+ . collect ( ) ;
772771 debug ! ( ?map) ;
773772
774773 // NOTE(compiler-errors): RPITITs, like all other RPITs, have early-bound
@@ -793,25 +792,19 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
793792 // same generics.
794793 let num_trait_substs = trait_to_impl_substs. len ( ) ;
795794 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) ;
795+ let ty = match ty. try_fold_with ( & mut RemapHiddenTyRegions {
796+ tcx,
797+ map,
798+ num_trait_substs,
799+ num_impl_substs,
800+ def_id,
801+ impl_def_id : impl_m. container_id ( tcx) ,
802+ ty,
803+ return_span,
804+ } ) {
805+ Ok ( ty) => ty,
806+ Err ( guar) => tcx. ty_error ( guar) ,
807+ } ;
815808 collected_tys. insert ( def_id, ty:: EarlyBinder :: bind ( ty) ) ;
816809 }
817810 Err ( err) => {
@@ -895,6 +888,97 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx> {
895888 }
896889}
897890
891+ struct RemapHiddenTyRegions < ' tcx > {
892+ tcx : TyCtxt < ' tcx > ,
893+ map : FxHashMap < ty:: Region < ' tcx > , ty:: Region < ' tcx > > ,
894+ num_trait_substs : usize ,
895+ num_impl_substs : usize ,
896+ def_id : DefId ,
897+ impl_def_id : DefId ,
898+ ty : Ty < ' tcx > ,
899+ return_span : Span ,
900+ }
901+
902+ impl < ' tcx > ty:: FallibleTypeFolder < TyCtxt < ' tcx > > for RemapHiddenTyRegions < ' tcx > {
903+ type Error = ErrorGuaranteed ;
904+
905+ fn interner ( & self ) -> TyCtxt < ' tcx > {
906+ self . tcx
907+ }
908+
909+ fn try_fold_ty ( & mut self , t : Ty < ' tcx > ) -> Result < Ty < ' tcx > , Self :: Error > {
910+ if let ty:: Alias ( ty:: Opaque , ty:: AliasTy { substs, def_id, .. } ) = * t. kind ( ) {
911+ let mut mapped_substs = Vec :: with_capacity ( substs. len ( ) ) ;
912+ for ( arg, v) in std:: iter:: zip ( substs, self . tcx . variances_of ( def_id) ) {
913+ mapped_substs. push ( match ( arg. unpack ( ) , v) {
914+ // Skip uncaptured opaque substs
915+ ( ty:: GenericArgKind :: Lifetime ( _) , ty:: Bivariant ) => arg,
916+ _ => arg. try_fold_with ( self ) ?,
917+ } ) ;
918+ }
919+ Ok ( self . tcx . mk_opaque ( def_id, self . tcx . mk_substs ( & mapped_substs) ) )
920+ } else {
921+ t. try_super_fold_with ( self )
922+ }
923+ }
924+
925+ fn try_fold_region (
926+ & mut self ,
927+ region : ty:: Region < ' tcx > ,
928+ ) -> Result < ty:: Region < ' tcx > , Self :: Error > {
929+ match region. kind ( ) {
930+ // Remap all free regions, which correspond to late-bound regions in the function.
931+ ty:: ReFree ( _) => { }
932+ // Remap early-bound regions as long as they don't come from the `impl` itself,
933+ // in which case we don't really need to renumber them.
934+ ty:: ReEarlyBound ( ebr) if self . tcx . parent ( ebr. def_id ) != self . impl_def_id => { }
935+ _ => return Ok ( region) ,
936+ }
937+
938+ let e = if let Some ( region) = self . map . get ( & region) {
939+ if let ty:: ReEarlyBound ( e) = region. kind ( ) { e } else { bug ! ( ) }
940+ } else {
941+ let guar = match region. kind ( ) {
942+ ty:: ReEarlyBound ( ty:: EarlyBoundRegion { def_id, .. } )
943+ | ty:: ReFree ( ty:: FreeRegion {
944+ bound_region : ty:: BoundRegionKind :: BrNamed ( def_id, _) ,
945+ ..
946+ } ) => {
947+ let return_span = if let ty:: Alias ( ty:: Opaque , opaque_ty) = self . ty . kind ( ) {
948+ self . tcx . def_span ( opaque_ty. def_id )
949+ } else {
950+ self . return_span
951+ } ;
952+ self . tcx
953+ . sess
954+ . struct_span_err (
955+ return_span,
956+ "return type captures more lifetimes than trait definition" ,
957+ )
958+ . span_label ( self . tcx . def_span ( def_id) , "this lifetime was captured" )
959+ . span_note (
960+ self . tcx . def_span ( self . def_id ) ,
961+ "hidden type must only reference lifetimes captured by this impl trait" ,
962+ )
963+ . note ( format ! ( "hidden type inferred to be `{}`" , self . ty) )
964+ . emit ( )
965+ }
966+ _ => self . tcx . sess . delay_span_bug ( DUMMY_SP , "should've been able to remap region" ) ,
967+ } ;
968+ return Err ( guar) ;
969+ } ;
970+
971+ Ok ( ty:: Region :: new_early_bound (
972+ self . tcx ,
973+ ty:: EarlyBoundRegion {
974+ def_id : e. def_id ,
975+ name : e. name ,
976+ index : ( e. index as usize - self . num_trait_substs + self . num_impl_substs ) as u32 ,
977+ } ,
978+ ) )
979+ }
980+ }
981+
898982fn report_trait_method_mismatch < ' tcx > (
899983 infcx : & InferCtxt < ' tcx > ,
900984 mut cause : ObligationCause < ' tcx > ,
0 commit comments