1- use rustc_data_structures:: fx:: { FxIndexMap , FxIndexSet } ;
1+ use rustc_data_structures:: fx:: FxIndexMap ;
22use rustc_errors:: ErrorGuaranteed ;
33use rustc_hir:: def:: DefKind ;
44use rustc_hir:: def_id:: LocalDefId ;
55use rustc_hir:: OpaqueTyOrigin ;
6- use rustc_infer:: infer:: InferCtxt ;
76use rustc_infer:: infer:: TyCtxtInferExt as _;
7+ use rustc_infer:: infer:: { InferCtxt , NllRegionVariableOrigin } ;
88use rustc_infer:: traits:: { Obligation , ObligationCause } ;
99use rustc_middle:: traits:: DefiningAnchor ;
1010use rustc_middle:: ty:: visit:: TypeVisitableExt ;
@@ -66,85 +66,60 @@ impl<'tcx> RegionInferenceContext<'tcx> {
6666 ) -> FxIndexMap < LocalDefId , OpaqueHiddenType < ' tcx > > {
6767 let mut result: FxIndexMap < LocalDefId , OpaqueHiddenType < ' tcx > > = FxIndexMap :: default ( ) ;
6868
69- let member_constraints: FxIndexMap < _ , _ > = self
70- . member_constraints
71- . all_indices ( )
72- . map ( |ci| ( self . member_constraints [ ci] . key , ci) )
73- . collect ( ) ;
74- debug ! ( ?member_constraints) ;
75-
7669 for ( opaque_type_key, concrete_type) in opaque_ty_decls {
77- let args = opaque_type_key. args ;
78- debug ! ( ?concrete_type, ?args) ;
70+ debug ! ( ?opaque_type_key, ?concrete_type) ;
7971
80- let mut subst_regions = vec ! [ self . universal_regions. fr_static] ;
72+ let mut arg_regions: Vec < ( ty:: RegionVid , ty:: Region < ' _ > ) > =
73+ vec ! [ ( self . universal_regions. fr_static, infcx. tcx. lifetimes. re_static) ] ;
8174
82- let to_universal_region = |vid, subst_regions : & mut Vec < _ > | {
83- trace ! ( ?vid) ;
84- let scc = self . constraint_sccs . scc ( vid) ;
85- trace ! ( ?scc) ;
86- match self . scc_values . universal_regions_outlived_by ( scc) . find_map ( |lb| {
87- self . eval_equal ( vid, lb) . then_some ( self . definitions [ lb] . external_name ?)
88- } ) {
89- Some ( region) => {
90- let vid = self . universal_regions . to_region_vid ( region) ;
91- subst_regions. push ( vid) ;
92- region
75+ let opaque_type_key =
76+ opaque_type_key. fold_captured_lifetime_args ( infcx. tcx , |region| {
77+ let scc = self . constraint_sccs . scc ( self . to_region_vid ( region) ) ;
78+ let vid = self . scc_representatives [ scc] ;
79+ let named = match self . definitions [ vid] . origin {
80+ NllRegionVariableOrigin :: FreeRegion => self
81+ . universal_regions
82+ . universal_regions ( )
83+ . filter ( |& ur| {
84+ use crate :: universal_regions:: RegionClassification as Class ;
85+ matches ! (
86+ self . universal_regions. region_classification( ur) ,
87+ Some ( Class :: Global | Class :: Local )
88+ )
89+ } )
90+ . filter ( |& ur| ur != self . universal_regions . fr_fn_body )
91+ . find ( |& ur| self . universal_region_relations . equal ( vid, ur) )
92+ . map ( |ur| self . definitions [ ur] . external_name . unwrap ( ) ) ,
93+ NllRegionVariableOrigin :: Placeholder ( placeholder) => {
94+ Some ( ty:: Region :: new_placeholder ( infcx. tcx , placeholder) )
95+ }
96+ NllRegionVariableOrigin :: Existential { .. } => None ,
9397 }
94- None => {
95- subst_regions. push ( vid) ;
98+ . unwrap_or_else ( || {
9699 ty:: Region :: new_error_with_message (
97100 infcx. tcx ,
98101 concrete_type. span ,
99102 "opaque type with non-universal region args" ,
100103 )
101- }
102- }
103- } ;
104+ } ) ;
104105
105- // Start by inserting universal regions from the member_constraint choice regions.
106- // This will ensure they get precedence when folding the regions in the concrete type.
107- if let Some ( & ci) = member_constraints. get ( & opaque_type_key) {
108- for & vid in self . member_constraints . choice_regions ( ci) {
109- to_universal_region ( vid, & mut subst_regions) ;
110- }
111- }
112- debug ! ( ?subst_regions) ;
113-
114- // Next, insert universal regions from args, so we can translate regions that appear
115- // in them but are not subject to member constraints, for instance closure args.
116- let universal_args = infcx. tcx . fold_regions ( args, |region, _| {
117- if let ty:: RePlaceholder ( ..) = region. kind ( ) {
118- // Higher kinded regions don't need remapping, they don't refer to anything outside of this the args.
119- return region;
120- }
106+ arg_regions. push ( ( vid, named) ) ;
107+ named
108+ } ) ;
109+ debug ! ( ?opaque_type_key, ?arg_regions) ;
110+
111+ let concrete_type = infcx. tcx . fold_regions ( concrete_type, |region, _| {
121112 let vid = self . to_region_vid ( region) ;
122- to_universal_region ( vid, & mut subst_regions)
113+ arg_regions
114+ . iter ( )
115+ . find ( |& & ( ur_vid, _) | self . eval_equal ( vid, ur_vid) )
116+ . map ( |& ( _, ur_name) | ur_name)
117+ . unwrap_or ( infcx. tcx . lifetimes . re_erased )
123118 } ) ;
124- debug ! ( ?universal_args) ;
125- debug ! ( ?subst_regions) ;
126-
127- // Deduplicate the set of regions while keeping the chosen order.
128- let subst_regions = subst_regions. into_iter ( ) . collect :: < FxIndexSet < _ > > ( ) ;
129- debug ! ( ?subst_regions) ;
130-
131- let universal_concrete_type =
132- infcx. tcx . fold_regions ( concrete_type, |region, _| match * region {
133- ty:: ReVar ( vid) => subst_regions
134- . iter ( )
135- . find ( |ur_vid| self . eval_equal ( vid, * * ur_vid) )
136- . and_then ( |ur_vid| self . definitions [ * ur_vid] . external_name )
137- . unwrap_or ( infcx. tcx . lifetimes . re_erased ) ,
138- _ => region,
139- } ) ;
140- debug ! ( ?universal_concrete_type) ;
119+ debug ! ( ?concrete_type) ;
141120
142- let opaque_type_key =
143- OpaqueTypeKey { def_id : opaque_type_key. def_id , args : universal_args } ;
144- let ty = infcx. infer_opaque_definition_from_instantiation (
145- opaque_type_key,
146- universal_concrete_type,
147- ) ;
121+ let ty =
122+ infcx. infer_opaque_definition_from_instantiation ( opaque_type_key, concrete_type) ;
148123 // Sometimes two opaque types are the same only after we remap the generic parameters
149124 // back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to `(X, Y)`
150125 // and `OpaqueType<Y, X>` mapped to `(Y, X)`, and those are the same, but we only know that
@@ -365,9 +340,9 @@ fn check_opaque_type_well_formed<'tcx>(
365340 }
366341}
367342
368- fn check_opaque_type_parameter_valid (
369- tcx : TyCtxt < ' _ > ,
370- opaque_type_key : OpaqueTypeKey < ' _ > ,
343+ fn check_opaque_type_parameter_valid < ' tcx > (
344+ tcx : TyCtxt < ' tcx > ,
345+ opaque_type_key : OpaqueTypeKey < ' tcx > ,
371346 span : Span ,
372347) -> Result < ( ) , ErrorGuaranteed > {
373348 let opaque_ty_hir = tcx. hir ( ) . expect_item ( opaque_type_key. def_id ) ;
@@ -378,25 +353,28 @@ fn check_opaque_type_parameter_valid(
378353
379354 let opaque_generics = tcx. generics_of ( opaque_type_key. def_id ) ;
380355 let mut seen_params: FxIndexMap < _ , Vec < _ > > = FxIndexMap :: default ( ) ;
381- for ( i, arg) in opaque_type_key. args . iter ( ) . enumerate ( ) {
356+ for ( i, arg) in opaque_type_key. iter_captured_args ( tcx ) {
382357 if let Err ( guar) = arg. error_reported ( ) {
383358 return Err ( guar) ;
384359 }
385360
386361 let arg_is_param = match arg. unpack ( ) {
387362 GenericArgKind :: Type ( ty) => matches ! ( ty. kind( ) , ty:: Param ( _) ) ,
388- GenericArgKind :: Lifetime ( lt) if is_ty_alias => {
389- matches ! ( * lt, ty:: ReEarlyBound ( _) | ty:: ReFree ( _) )
390- }
391- // FIXME(#113916): we can't currently check for unique lifetime params,
392- // see that issue for more. We will also have to ignore unused lifetime
393- // params for RPIT, but that's comparatively trivial ✨
394- GenericArgKind :: Lifetime ( _) => continue ,
363+ GenericArgKind :: Lifetime ( lt) => match is_ty_alias {
364+ true => matches ! ( * lt, ty:: ReEarlyBound ( _) | ty:: ReFree ( _) ) ,
365+ // FIXME(#111935, #113916): For RPIT, we currently accept ReStatic as well.
366+ // This is a back-compat hack, see the issue for more.
367+ false => matches ! ( * lt, ty:: ReEarlyBound ( _) | ty:: ReFree ( _) | ty:: ReStatic ) ,
368+ } ,
395369 GenericArgKind :: Const ( ct) => matches ! ( ct. kind( ) , ty:: ConstKind :: Param ( _) ) ,
396370 } ;
397371
398372 if arg_is_param {
399- seen_params. entry ( arg) . or_default ( ) . push ( i) ;
373+ // FIXME(#113916): For RPIT, we can't currently check for unique lifetime
374+ // params, see that issue for more. We limit this to TAIT for now.
375+ if is_ty_alias {
376+ seen_params. entry ( arg) . or_default ( ) . push ( i) ;
377+ }
400378 } else {
401379 // Prevent `fn foo() -> Foo<u32>` from being defining.
402380 let opaque_param = opaque_generics. param_at ( i, tcx) ;
0 commit comments