1
- use rustc_data_structures:: fx:: { FxIndexMap , FxIndexSet } ;
1
+ use rustc_data_structures:: fx:: FxIndexMap ;
2
2
use rustc_errors:: ErrorGuaranteed ;
3
3
use rustc_hir:: def:: DefKind ;
4
4
use rustc_hir:: def_id:: LocalDefId ;
5
5
use rustc_hir:: OpaqueTyOrigin ;
6
- use rustc_infer:: infer:: InferCtxt ;
7
6
use rustc_infer:: infer:: TyCtxtInferExt as _;
7
+ use rustc_infer:: infer:: { InferCtxt , NllRegionVariableOrigin } ;
8
8
use rustc_infer:: traits:: { Obligation , ObligationCause } ;
9
9
use rustc_middle:: traits:: DefiningAnchor ;
10
10
use rustc_middle:: ty:: visit:: TypeVisitableExt ;
@@ -66,85 +66,60 @@ impl<'tcx> RegionInferenceContext<'tcx> {
66
66
) -> FxIndexMap < LocalDefId , OpaqueHiddenType < ' tcx > > {
67
67
let mut result: FxIndexMap < LocalDefId , OpaqueHiddenType < ' tcx > > = FxIndexMap :: default ( ) ;
68
68
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
-
76
69
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) ;
79
71
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) ] ;
81
74
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 ,
93
97
}
94
- None => {
95
- subst_regions. push ( vid) ;
98
+ . unwrap_or_else ( || {
96
99
ty:: Region :: new_error_with_message (
97
100
infcx. tcx ,
98
101
concrete_type. span ,
99
102
"opaque type with non-universal region args" ,
100
103
)
101
- }
102
- }
103
- } ;
104
+ } ) ;
104
105
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, _| {
121
112
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 )
123
118
} ) ;
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) ;
141
120
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) ;
148
123
// Sometimes two opaque types are the same only after we remap the generic parameters
149
124
// back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to `(X, Y)`
150
125
// 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>(
365
340
}
366
341
}
367
342
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 > ,
371
346
span : Span ,
372
347
) -> Result < ( ) , ErrorGuaranteed > {
373
348
let opaque_ty_hir = tcx. hir ( ) . expect_item ( opaque_type_key. def_id ) ;
@@ -378,25 +353,28 @@ fn check_opaque_type_parameter_valid(
378
353
379
354
let opaque_generics = tcx. generics_of ( opaque_type_key. def_id ) ;
380
355
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 ) {
382
357
if let Err ( guar) = arg. error_reported ( ) {
383
358
return Err ( guar) ;
384
359
}
385
360
386
361
let arg_is_param = match arg. unpack ( ) {
387
362
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
+ } ,
395
369
GenericArgKind :: Const ( ct) => matches ! ( ct. kind( ) , ty:: ConstKind :: Param ( _) ) ,
396
370
} ;
397
371
398
372
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
+ }
400
378
} else {
401
379
// Prevent `fn foo() -> Foo<u32>` from being defining.
402
380
let opaque_param = opaque_generics. param_at ( i, tcx) ;
0 commit comments