@@ -46,6 +46,19 @@ pub struct FulfillmentContext<'tcx> {
4646 // A list of all obligations that have been registered with this
4747 // fulfillment context.
4848 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 ,
4962}
5063
5164#[ derive( Clone , Debug ) ]
@@ -59,6 +72,14 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
5972 pub fn new ( ) -> FulfillmentContext < ' tcx > {
6073 FulfillmentContext {
6174 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
6283 }
6384 }
6485
@@ -191,7 +212,10 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
191212 debug ! ( "select: starting another iteration" ) ;
192213
193214 // 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+ } ) ;
195219 debug ! ( "select: outcome={:?}" , outcome) ;
196220
197221 // FIXME: if we kept the original cache key, we could mark projection
@@ -220,6 +244,7 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
220244
221245struct FulfillProcessor < ' a , ' b : ' a , ' gcx : ' tcx , ' tcx : ' b > {
222246 selcx : & ' a mut SelectionContext < ' b , ' gcx , ' tcx > ,
247+ register_region_obligations : bool
223248}
224249
225250impl < ' 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,
230255 obligation : & mut Self :: Obligation )
231256 -> Result < Option < Vec < Self :: Obligation > > , Self :: Error >
232257 {
233- process_predicate ( self . selcx , obligation)
258+ process_predicate ( self . selcx , obligation, self . register_region_obligations )
234259 . map ( |os| os. map ( |os| os. into_iter ( ) . map ( |o| PendingPredicateObligation {
235260 obligation : o,
236261 stalled_on : vec ! [ ]
@@ -269,7 +294,8 @@ fn trait_ref_type_vars<'a, 'gcx, 'tcx>(selcx: &mut SelectionContext<'a, 'gcx, 't
269294/// - `Err` if the predicate does not hold
270295fn process_predicate < ' a , ' gcx , ' tcx > (
271296 selcx : & mut SelectionContext < ' a , ' gcx , ' tcx > ,
272- pending_obligation : & mut PendingPredicateObligation < ' tcx > )
297+ pending_obligation : & mut PendingPredicateObligation < ' tcx > ,
298+ register_region_obligations : bool )
273299 -> Result < Option < Vec < PredicateObligation < ' tcx > > > ,
274300 FulfillmentErrorCode < ' tcx > >
275301{
@@ -391,26 +417,30 @@ fn process_predicate<'a, 'gcx, 'tcx>(
391417 // `for<'a> T: 'a where 'a not in T`, which we can treat as `T: 'static`.
392418 Some ( t_a) => {
393419 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+ }
401429 Ok ( Some ( vec ! [ ] ) )
402430 }
403431 }
404432 }
405433 // If there aren't, register the obligation.
406434 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+ }
414444 Ok ( Some ( vec ! [ ] ) )
415445 }
416446 }
0 commit comments