@@ -46,6 +46,19 @@ pub struct FulfillmentContext<'tcx> {
46
46
// A list of all obligations that have been registered with this
47
47
// fulfillment context.
48
48
predicates : ObligationForest < PendingPredicateObligation < ' tcx > > ,
49
+ // Should this fulfillment context register type-lives-for-region
50
+ // obligations on its parent infcx? In some cases, region
51
+ // obligations are either already known to hold (normalization) or
52
+ // hopefully verifed elsewhere (type-impls-bound), and therefore
53
+ // should not be checked.
54
+ //
55
+ // Note that if we are normalizing a type that we already
56
+ // know is well-formed, there should be no harm setting this
57
+ // to true - all the region variables should be determinable
58
+ // using the RFC 447 rules, which don't depend on
59
+ // type-lives-for-region constraints, and because the type
60
+ // is well-formed, the constraints should hold.
61
+ register_region_obligations : bool ,
49
62
}
50
63
51
64
#[ derive( Clone , Debug ) ]
@@ -59,6 +72,14 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
59
72
pub fn new ( ) -> FulfillmentContext < ' tcx > {
60
73
FulfillmentContext {
61
74
predicates : ObligationForest :: new ( ) ,
75
+ register_region_obligations : true
76
+ }
77
+ }
78
+
79
+ pub fn new_ignoring_regions ( ) -> FulfillmentContext < ' tcx > {
80
+ FulfillmentContext {
81
+ predicates : ObligationForest :: new ( ) ,
82
+ register_region_obligations : false
62
83
}
63
84
}
64
85
@@ -191,7 +212,10 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
191
212
debug ! ( "select: starting another iteration" ) ;
192
213
193
214
// Process pending obligations.
194
- let outcome = self . predicates . process_obligations ( & mut FulfillProcessor { selcx } ) ;
215
+ let outcome = self . predicates . process_obligations ( & mut FulfillProcessor {
216
+ selcx,
217
+ register_region_obligations : self . register_region_obligations
218
+ } ) ;
195
219
debug ! ( "select: outcome={:?}" , outcome) ;
196
220
197
221
// FIXME: if we kept the original cache key, we could mark projection
@@ -220,6 +244,7 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
220
244
221
245
struct FulfillProcessor < ' a , ' b : ' a , ' gcx : ' tcx , ' tcx : ' b > {
222
246
selcx : & ' a mut SelectionContext < ' b , ' gcx , ' tcx > ,
247
+ register_region_obligations : bool
223
248
}
224
249
225
250
impl < ' a , ' b , ' gcx , ' tcx > ObligationProcessor for FulfillProcessor < ' a , ' b , ' gcx , ' tcx > {
@@ -230,7 +255,7 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx,
230
255
obligation : & mut Self :: Obligation )
231
256
-> Result < Option < Vec < Self :: Obligation > > , Self :: Error >
232
257
{
233
- process_predicate ( self . selcx , obligation)
258
+ process_predicate ( self . selcx , obligation, self . register_region_obligations )
234
259
. map ( |os| os. map ( |os| os. into_iter ( ) . map ( |o| PendingPredicateObligation {
235
260
obligation : o,
236
261
stalled_on : vec ! [ ]
@@ -269,7 +294,8 @@ fn trait_ref_type_vars<'a, 'gcx, 'tcx>(selcx: &mut SelectionContext<'a, 'gcx, 't
269
294
/// - `Err` if the predicate does not hold
270
295
fn process_predicate < ' a , ' gcx , ' tcx > (
271
296
selcx : & mut SelectionContext < ' a , ' gcx , ' tcx > ,
272
- pending_obligation : & mut PendingPredicateObligation < ' tcx > )
297
+ pending_obligation : & mut PendingPredicateObligation < ' tcx > ,
298
+ register_region_obligations : bool )
273
299
-> Result < Option < Vec < PredicateObligation < ' tcx > > > ,
274
300
FulfillmentErrorCode < ' tcx > >
275
301
{
@@ -391,26 +417,30 @@ fn process_predicate<'a, 'gcx, 'tcx>(
391
417
// `for<'a> T: 'a where 'a not in T`, which we can treat as `T: 'static`.
392
418
Some ( t_a) => {
393
419
let r_static = selcx. tcx ( ) . types . re_static ;
394
- selcx. infcx ( ) . register_region_obligation (
395
- obligation. cause . body_id ,
396
- RegionObligation {
397
- sup_type : t_a,
398
- sub_region : r_static,
399
- cause : obligation. cause . clone ( ) ,
400
- } ) ;
420
+ if register_region_obligations {
421
+ selcx. infcx ( ) . register_region_obligation (
422
+ obligation. cause . body_id ,
423
+ RegionObligation {
424
+ sup_type : t_a,
425
+ sub_region : r_static,
426
+ cause : obligation. cause . clone ( ) ,
427
+ } ) ;
428
+ }
401
429
Ok ( Some ( vec ! [ ] ) )
402
430
}
403
431
}
404
432
}
405
433
// If there aren't, register the obligation.
406
434
Some ( ty:: OutlivesPredicate ( t_a, r_b) ) => {
407
- selcx. infcx ( ) . register_region_obligation (
408
- obligation. cause . body_id ,
409
- RegionObligation {
410
- sup_type : t_a,
411
- sub_region : r_b,
412
- cause : obligation. cause . clone ( )
413
- } ) ;
435
+ if register_region_obligations {
436
+ selcx. infcx ( ) . register_region_obligation (
437
+ obligation. cause . body_id ,
438
+ RegionObligation {
439
+ sup_type : t_a,
440
+ sub_region : r_b,
441
+ cause : obligation. cause . clone ( )
442
+ } ) ;
443
+ }
414
444
Ok ( Some ( vec ! [ ] ) )
415
445
}
416
446
}
0 commit comments