@@ -5,10 +5,13 @@ use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelega
5
5
use rustc_infer:: infer:: region_constraints:: { GenericKind , VerifyBound } ;
6
6
use rustc_infer:: infer:: { self , InferCtxt , SubregionOrigin } ;
7
7
use rustc_middle:: mir:: { ClosureOutlivesSubject , ClosureRegionRequirements , ConstraintCategory } ;
8
- use rustc_middle:: ty :: GenericArgKind ;
9
- use rustc_middle:: ty :: { self , TyCtxt } ;
10
- use rustc_middle:: ty:: { TypeFoldable , TypeVisitableExt } ;
8
+ use rustc_middle:: traits :: query :: NoSolution ;
9
+ use rustc_middle:: traits :: ObligationCause ;
10
+ use rustc_middle:: ty:: { self , GenericArgKind , Ty , TyCtxt , TypeFoldable , TypeVisitableExt } ;
11
11
use rustc_span:: { Span , DUMMY_SP } ;
12
+ use rustc_trait_selection:: solve:: deeply_normalize;
13
+ use rustc_trait_selection:: traits:: query:: type_op:: custom:: CustomTypeOp ;
14
+ use rustc_trait_selection:: traits:: query:: type_op:: { TypeOp , TypeOpOutput } ;
12
15
13
16
use crate :: {
14
17
constraints:: OutlivesConstraint ,
@@ -33,6 +36,7 @@ pub(crate) struct ConstraintConversion<'a, 'tcx> {
33
36
/// our special inference variable there, we would mess that up.
34
37
region_bound_pairs : & ' a RegionBoundPairs < ' tcx > ,
35
38
implicit_region_bound : ty:: Region < ' tcx > ,
39
+ param_env : ty:: ParamEnv < ' tcx > ,
36
40
known_type_outlives_obligations : & ' tcx [ ty:: PolyTypeOutlivesPredicate < ' tcx > ] ,
37
41
locations : Locations ,
38
42
span : Span ,
@@ -47,6 +51,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
47
51
universal_regions : & ' a UniversalRegions < ' tcx > ,
48
52
region_bound_pairs : & ' a RegionBoundPairs < ' tcx > ,
49
53
implicit_region_bound : ty:: Region < ' tcx > ,
54
+ param_env : ty:: ParamEnv < ' tcx > ,
50
55
known_type_outlives_obligations : & ' tcx [ ty:: PolyTypeOutlivesPredicate < ' tcx > ] ,
51
56
locations : Locations ,
52
57
span : Span ,
@@ -59,6 +64,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
59
64
universal_regions,
60
65
region_bound_pairs,
61
66
implicit_region_bound,
67
+ param_env,
62
68
known_type_outlives_obligations,
63
69
locations,
64
70
span,
@@ -137,36 +143,68 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
137
143
// Extract out various useful fields we'll need below.
138
144
let ConstraintConversion {
139
145
tcx,
146
+ infcx,
140
147
region_bound_pairs,
141
148
implicit_region_bound,
142
149
known_type_outlives_obligations,
143
150
..
144
151
} = * self ;
145
152
146
- let ty:: OutlivesPredicate ( k1, r2) = predicate;
147
- match k1. unpack ( ) {
148
- GenericArgKind :: Lifetime ( r1) => {
149
- let r1_vid = self . to_region_vid ( r1) ;
150
- let r2_vid = self . to_region_vid ( r2) ;
151
- self . add_outlives ( r1_vid, r2_vid, constraint_category) ;
153
+ let mut outlives_predicates = vec ! [ ( predicate, constraint_category) ] ;
154
+ for iteration in 0 .. {
155
+ if outlives_predicates. is_empty ( ) {
156
+ break ;
157
+ }
158
+
159
+ if !self . tcx . recursion_limit ( ) . value_within_limit ( iteration) {
160
+ bug ! (
161
+ "FIXME(-Znext-solver): Overflowed when processing region obligations: {outlives_predicates:#?}"
162
+ ) ;
152
163
}
153
164
154
- GenericArgKind :: Type ( t1) => {
155
- // we don't actually use this for anything, but
156
- // the `TypeOutlives` code needs an origin.
157
- let origin = infer:: RelateParamBound ( DUMMY_SP , t1, None ) ;
165
+ let mut next_outlives_predicates = vec ! [ ] ;
166
+ for ( ty:: OutlivesPredicate ( k1, r2) , constraint_category) in outlives_predicates {
167
+ match k1. unpack ( ) {
168
+ GenericArgKind :: Lifetime ( r1) => {
169
+ let r1_vid = self . to_region_vid ( r1) ;
170
+ let r2_vid = self . to_region_vid ( r2) ;
171
+ self . add_outlives ( r1_vid, r2_vid, constraint_category) ;
172
+ }
158
173
159
- TypeOutlives :: new (
160
- & mut * self ,
161
- tcx,
162
- region_bound_pairs,
163
- Some ( implicit_region_bound) ,
164
- known_type_outlives_obligations,
165
- )
166
- . type_must_outlive ( origin, t1, r2, constraint_category) ;
174
+ GenericArgKind :: Type ( mut t1) => {
175
+ // Normalize the type we receive from a `TypeOutlives` obligation
176
+ // in the new trait solver.
177
+ if infcx. next_trait_solver ( ) {
178
+ t1 = self . normalize_and_add_type_outlives_constraints (
179
+ t1,
180
+ & mut next_outlives_predicates,
181
+ ) ;
182
+ }
183
+
184
+ // we don't actually use this for anything, but
185
+ // the `TypeOutlives` code needs an origin.
186
+ let origin = infer:: RelateParamBound ( DUMMY_SP , t1, None ) ;
187
+
188
+ TypeOutlives :: new (
189
+ & mut * self ,
190
+ tcx,
191
+ region_bound_pairs,
192
+ Some ( implicit_region_bound) ,
193
+ known_type_outlives_obligations,
194
+ )
195
+ . type_must_outlive (
196
+ origin,
197
+ t1,
198
+ r2,
199
+ constraint_category,
200
+ ) ;
201
+ }
202
+
203
+ GenericArgKind :: Const ( _) => unreachable ! ( ) ,
204
+ }
167
205
}
168
206
169
- GenericArgKind :: Const ( _ ) => unreachable ! ( ) ,
207
+ outlives_predicates = next_outlives_predicates ;
170
208
}
171
209
}
172
210
@@ -232,6 +270,42 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
232
270
debug ! ( "add_type_test(type_test={:?})" , type_test) ;
233
271
self . constraints . type_tests . push ( type_test) ;
234
272
}
273
+
274
+ fn normalize_and_add_type_outlives_constraints (
275
+ & self ,
276
+ ty : Ty < ' tcx > ,
277
+ next_outlives_predicates : & mut Vec < (
278
+ ty:: OutlivesPredicate < ty:: GenericArg < ' tcx > , ty:: Region < ' tcx > > ,
279
+ ConstraintCategory < ' tcx > ,
280
+ ) > ,
281
+ ) -> Ty < ' tcx > {
282
+ let result = CustomTypeOp :: new (
283
+ |ocx| {
284
+ deeply_normalize (
285
+ ocx. infcx . at ( & ObligationCause :: dummy_with_span ( self . span ) , self . param_env ) ,
286
+ ty,
287
+ )
288
+ . map_err ( |_| NoSolution )
289
+ } ,
290
+ "normalize type outlives obligation" ,
291
+ )
292
+ . fully_perform ( self . infcx , self . span ) ;
293
+
294
+ match result {
295
+ Ok ( TypeOpOutput { output : ty, constraints, .. } ) => {
296
+ if let Some ( constraints) = constraints {
297
+ assert ! (
298
+ constraints. member_constraints. is_empty( ) ,
299
+ "no member constraints expected from normalizing: {:#?}" ,
300
+ constraints. member_constraints
301
+ ) ;
302
+ next_outlives_predicates. extend ( constraints. outlives . iter ( ) . copied ( ) ) ;
303
+ }
304
+ ty
305
+ }
306
+ Err ( _) => ty,
307
+ }
308
+ }
235
309
}
236
310
237
311
impl < ' a , ' b , ' tcx > TypeOutlivesDelegate < ' tcx > for & ' a mut ConstraintConversion < ' b , ' tcx > {
0 commit comments