@@ -19,7 +19,7 @@ use rustc_middle::ty::{
19
19
self , InternalSubsts , Ty , TypeFoldable , TypeFolder , TypeSuperFoldable , TypeVisitableExt ,
20
20
} ;
21
21
use rustc_middle:: ty:: { GenericParamDefKind , ToPredicate , TyCtxt } ;
22
- use rustc_span:: Span ;
22
+ use rustc_span:: { Span , DUMMY_SP } ;
23
23
use rustc_trait_selection:: traits:: error_reporting:: TypeErrCtxtExt ;
24
24
use rustc_trait_selection:: traits:: outlives_bounds:: InferCtxtExt as _;
25
25
use rustc_trait_selection:: traits:: {
@@ -767,8 +767,10 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
767
767
// contains `def_id`'s early-bound regions.
768
768
let id_substs = InternalSubsts :: identity_for_item ( tcx, def_id) ;
769
769
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 ( ) ;
772
774
debug ! ( ?map) ;
773
775
774
776
// 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>(
793
795
// same generics.
794
796
let num_trait_substs = trait_to_impl_substs. len ( ) ;
795
797
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
+ } ;
815
811
collected_tys. insert ( def_id, ty:: EarlyBinder :: bind ( ty) ) ;
816
812
}
817
813
Err ( err) => {
@@ -895,6 +891,97 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx> {
895
891
}
896
892
}
897
893
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
+
898
985
fn report_trait_method_mismatch < ' tcx > (
899
986
infcx : & InferCtxt < ' tcx > ,
900
987
mut cause : ObligationCause < ' tcx > ,
0 commit comments