@@ -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:: {
@@ -651,11 +651,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
651
651
let impl_sig = ocx. normalize (
652
652
& norm_cause,
653
653
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 ( ) ) ,
659
655
) ;
660
656
impl_sig. error_reported ( ) ?;
661
657
let impl_return_ty = impl_sig. output ( ) ;
@@ -665,9 +661,10 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
665
661
// them with inference variables.
666
662
// We will use these inference variables to collect the hidden types of RPITITs.
667
663
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 ,
671
668
tcx. fn_sig ( trait_m. def_id ) . subst ( tcx, trait_to_placeholder_substs) ,
672
669
)
673
670
. fold_with ( & mut collector) ;
@@ -760,15 +757,17 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
760
757
761
758
let mut collected_tys = FxHashMap :: default ( ) ;
762
759
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 ) ) => {
765
762
// `ty` contains free regions that we created earlier while liberating the
766
763
// trait fn signature. However, projection normalization expects `ty` to
767
764
// contains `def_id`'s early-bound regions.
768
765
let id_substs = InternalSubsts :: identity_for_item ( tcx, def_id) ;
769
766
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 ( ) ;
772
771
debug ! ( ?map) ;
773
772
774
773
// 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>(
793
792
// same generics.
794
793
let num_trait_substs = trait_to_impl_substs. len ( ) ;
795
794
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
+ } ;
815
808
collected_tys. insert ( def_id, ty:: EarlyBinder :: bind ( ty) ) ;
816
809
}
817
810
Err ( err) => {
@@ -895,6 +888,97 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx> {
895
888
}
896
889
}
897
890
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
+
898
982
fn report_trait_method_mismatch < ' tcx > (
899
983
infcx : & InferCtxt < ' tcx > ,
900
984
mut cause : ObligationCause < ' tcx > ,
0 commit comments