@@ -319,23 +319,34 @@ impl<'tcx> RegionInferenceContext<'tcx> {
319319 }
320320
321321 for variable in self . definitions . indices ( ) {
322+ let scc = self . constraint_sccs . scc ( variable) ;
323+
322324 match self . definitions [ variable] . origin {
323325 NLLRegionVariableOrigin :: FreeRegion => {
324326 // For each free, universally quantified region X:
325327
326328 // Add all nodes in the CFG to liveness constraints
327- let variable_scc = self . constraint_sccs . scc ( variable) ;
328329 self . liveness_constraints . add_all_points ( variable) ;
329- self . scc_values . add_all_points ( variable_scc ) ;
330+ self . scc_values . add_all_points ( scc ) ;
330331
331332 // 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) ;
333334 }
334335
335336 NLLRegionVariableOrigin :: BoundRegion ( ui) => {
336337 // 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+ }
339350 }
340351
341352 NLLRegionVariableOrigin :: Existential => {
@@ -383,13 +394,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
383394 self . scc_universes [ scc]
384395 }
385396
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-
393397 /// Perform region inference and report errors if we see any
394398 /// unsatisfiable constraints. If this is a closure, returns the
395399 /// region requirements to propagate to our creator, if any.
@@ -516,22 +520,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
516520 // merge the bits.
517521 self . scc_values . add_region ( scc_a, scc_b) ;
518522 } 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) ;
535524 }
536525 }
537526
@@ -563,6 +552,19 @@ impl<'tcx> RegionInferenceContext<'tcx> {
563552 . all ( |u| u. is_subset_of ( universe_a) )
564553 }
565554
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+
566568 /// Once regions have been propagated, this method is used to see
567569 /// whether the "type tests" produced by typeck were satisfied;
568570 /// type tests encode type-outlives relationships like `T:
0 commit comments