@@ -319,23 +319,34 @@ impl<'tcx> RegionInferenceContext<'tcx> {
319
319
}
320
320
321
321
for variable in self . definitions . indices ( ) {
322
+ let scc = self . constraint_sccs . scc ( variable) ;
323
+
322
324
match self . definitions [ variable] . origin {
323
325
NLLRegionVariableOrigin :: FreeRegion => {
324
326
// For each free, universally quantified region X:
325
327
326
328
// Add all nodes in the CFG to liveness constraints
327
- let variable_scc = self . constraint_sccs . scc ( variable) ;
328
329
self . liveness_constraints . add_all_points ( variable) ;
329
- self . scc_values . add_all_points ( variable_scc ) ;
330
+ self . scc_values . add_all_points ( scc ) ;
330
331
331
332
// Add `end(X)` into the set for X.
332
- self . add_element_to_scc_of ( variable , variable) ;
333
+ self . scc_values . add_element ( scc , variable) ;
333
334
}
334
335
335
336
NLLRegionVariableOrigin :: BoundRegion ( ui) => {
336
337
// Each placeholder region X outlives its
337
- // associated universe but nothing else.
338
- self . add_element_to_scc_of ( variable, ui) ;
338
+ // associated universe but nothing else. Every
339
+ // placeholder region is always in a universe that
340
+ // contains `ui` -- but when placeholder regions
341
+ // are placed into an SCC, that SCC may include
342
+ // things from other universes that do not include
343
+ // `ui`.
344
+ let scc_universe = self . scc_universes [ scc] ;
345
+ if ui. is_subset_of ( scc_universe) {
346
+ self . scc_values . add_element ( scc, ui) ;
347
+ } else {
348
+ self . add_incompatible_universe ( scc) ;
349
+ }
339
350
}
340
351
341
352
NLLRegionVariableOrigin :: Existential => {
@@ -383,13 +394,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
383
394
self . scc_universes [ scc]
384
395
}
385
396
386
- /// Adds `elem` to the value of the SCC in which `v` appears.
387
- fn add_element_to_scc_of ( & mut self , v : RegionVid , elem : impl ToElementIndex ) {
388
- debug ! ( "add_live_element({:?}, {:?})" , v, elem) ;
389
- let scc = self . constraint_sccs . scc ( v) ;
390
- self . scc_values . add_element ( scc, elem) ;
391
- }
392
-
393
397
/// Perform region inference and report errors if we see any
394
398
/// unsatisfiable constraints. If this is a closure, returns the
395
399
/// region requirements to propagate to our creator, if any.
@@ -516,22 +520,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
516
520
// merge the bits.
517
521
self . scc_values . add_region ( scc_a, scc_b) ;
518
522
} else {
519
- // Otherwise, the only way for `A` to outlive `B`
520
- // is for it to outlive static. This is actually stricter
521
- // than necessary: ideally, we'd support bounds like `for<'a: 'b`>`
522
- // that might then allow us to approximate `'a` with `'b` and not
523
- // `'static`. But it will have to do for now.
524
- //
525
- // The code here is a bit hacky: we grab the current
526
- // value of the SCC in which `'static` appears, but
527
- // this value may not be fully computed yet. That's ok
528
- // though: it will contain the base liveness values,
529
- // which include (a) the static free region element
530
- // and (b) all the points in the CFG, so it is "good
531
- // enough" to bring it in here for our purposes.
532
- let fr_static = self . universal_regions . fr_static ;
533
- let scc_static = constraint_sccs. scc ( fr_static) ;
534
- self . scc_values . add_region ( scc_a, scc_static) ;
523
+ self . add_incompatible_universe ( scc_a) ;
535
524
}
536
525
}
537
526
@@ -563,6 +552,19 @@ impl<'tcx> RegionInferenceContext<'tcx> {
563
552
. all ( |u| u. is_subset_of ( universe_a) )
564
553
}
565
554
555
+ /// Extend `scc` so that it can outlive some placeholder region
556
+ /// from a universe it can't name; at present, the only way for
557
+ /// this to be true is if `scc` outlives `'static`. This is
558
+ /// actually stricter than necessary: ideally, we'd support bounds
559
+ /// like `for<'a: 'b`>` that might then allow us to approximate
560
+ /// `'a` with `'b` and not `'static`. But it will have to do for
561
+ /// now.
562
+ fn add_incompatible_universe ( & mut self , scc : ConstraintSccIndex ) {
563
+ let fr_static = self . universal_regions . fr_static ;
564
+ self . scc_values . add_all_points ( scc) ;
565
+ self . scc_values . add_element ( scc, fr_static) ;
566
+ }
567
+
566
568
/// Once regions have been propagated, this method is used to see
567
569
/// whether the "type tests" produced by typeck were satisfied;
568
570
/// type tests encode type-outlives relationships like `T:
0 commit comments