@@ -28,7 +28,7 @@ use crate::constraints::graph::{self, NormalConstraintGraph, RegionGraph};
2828use crate :: constraints:: { ConstraintSccIndex , OutlivesConstraint , OutlivesConstraintSet } ;
2929use crate :: dataflow:: BorrowIndex ;
3030use crate :: diagnostics:: { RegionErrorKind , RegionErrors , UniverseInfo } ;
31- use crate :: handle_placeholders:: { LoweredConstraints , RegionTracker } ;
31+ use crate :: handle_placeholders:: { LoweredConstraints , PlaceholderReachability , RegionTracker } ;
3232use crate :: member_constraints:: { MemberConstraintSet , NllMemberConstraintIndex } ;
3333use crate :: polonius:: LiveLoans ;
3434use crate :: polonius:: legacy:: PoloniusOutput ;
@@ -360,7 +360,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
360360 outlives_constraints,
361361 scc_annotations,
362362 type_tests,
363- liveness_constraints,
363+ mut liveness_constraints,
364364 universe_causes,
365365 placeholder_indices,
366366 member_constraints,
@@ -377,8 +377,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
377377 sccs_info ( infcx, & constraint_sccs) ;
378378 }
379379
380- let mut scc_values =
381- RegionValues :: new ( location_map, universal_regions. len ( ) , placeholder_indices) ;
380+ let mut scc_values = RegionValues :: new ( location_map, universal_regions. len ( ) ) ;
382381
383382 for region in liveness_constraints. regions ( ) {
384383 let scc = constraint_sccs. scc ( region) ;
@@ -388,7 +387,22 @@ impl<'tcx> RegionInferenceContext<'tcx> {
388387 let member_constraints =
389388 Rc :: new ( member_constraints. into_mapped ( |r| constraint_sccs. scc ( r) ) ) ;
390389
391- let mut result = Self {
390+ for variable in definitions. indices ( ) {
391+ if let NllRegionVariableOrigin :: FreeRegion = definitions[ variable] . origin {
392+ // For each free, universally quantified region X:
393+
394+ let scc = constraint_sccs. scc ( variable) ;
395+
396+ // Add all nodes in the CFG to liveness constraints
397+ liveness_constraints. add_all_points ( variable) ;
398+ scc_values. add_all_points ( scc) ;
399+
400+ // Add `end(X)` into the set for X.
401+ scc_values. add_element ( scc, variable) ;
402+ }
403+ }
404+
405+ Self {
392406 definitions,
393407 liveness_constraints,
394408 constraints : outlives_constraints,
@@ -402,90 +416,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
402416 scc_values,
403417 type_tests,
404418 universal_region_relations,
405- } ;
406-
407- result. init_free_and_bound_regions ( ) ;
408-
409- result
410- }
411-
412- /// Initializes the region variables for each universally
413- /// quantified region (lifetime parameter). The first N variables
414- /// always correspond to the regions appearing in the function
415- /// signature (both named and anonymous) and where-clauses. This
416- /// function iterates over those regions and initializes them with
417- /// minimum values.
418- ///
419- /// For example:
420- /// ```
421- /// fn foo<'a, 'b>( /* ... */ ) where 'a: 'b { /* ... */ }
422- /// ```
423- /// would initialize two variables like so:
424- /// ```ignore (illustrative)
425- /// R0 = { CFG, R0 } // 'a
426- /// R1 = { CFG, R0, R1 } // 'b
427- /// ```
428- /// Here, R0 represents `'a`, and it contains (a) the entire CFG
429- /// and (b) any universally quantified regions that it outlives,
430- /// which in this case is just itself. R1 (`'b`) in contrast also
431- /// outlives `'a` and hence contains R0 and R1.
432- ///
433- /// This bit of logic also handles invalid universe relations
434- /// for higher-kinded types.
435- ///
436- /// We Walk each SCC `A` and `B` such that `A: B`
437- /// and ensure that universe(A) can see universe(B).
438- ///
439- /// This serves to enforce the 'empty/placeholder' hierarchy
440- /// (described in more detail on `RegionKind`):
441- ///
442- /// ```ignore (illustrative)
443- /// static -----+
444- /// | |
445- /// empty(U0) placeholder(U1)
446- /// | /
447- /// empty(U1)
448- /// ```
449- ///
450- /// In particular, imagine we have variables R0 in U0 and R1
451- /// created in U1, and constraints like this;
452- ///
453- /// ```ignore (illustrative)
454- /// R1: !1 // R1 outlives the placeholder in U1
455- /// R1: R0 // R1 outlives R0
456- /// ```
457- ///
458- /// Here, we wish for R1 to be `'static`, because it
459- /// cannot outlive `placeholder(U1)` and `empty(U0)` any other way.
460- ///
461- /// Thanks to this loop, what happens is that the `R1: R0`
462- /// constraint has lowered the universe of `R1` to `U0`, which in turn
463- /// means that the `R1: !1` constraint here will cause
464- /// `R1` to become `'static`.
465- fn init_free_and_bound_regions ( & mut self ) {
466- for variable in self . definitions . indices ( ) {
467- let scc = self . constraint_sccs . scc ( variable) ;
468-
469- match self . definitions [ variable] . origin {
470- NllRegionVariableOrigin :: FreeRegion => {
471- // For each free, universally quantified region X:
472-
473- // Add all nodes in the CFG to liveness constraints
474- self . liveness_constraints . add_all_points ( variable) ;
475- self . scc_values . add_all_points ( scc) ;
476-
477- // Add `end(X)` into the set for X.
478- self . scc_values . add_element ( scc, variable) ;
479- }
480-
481- NllRegionVariableOrigin :: Placeholder ( placeholder) => {
482- self . scc_values . add_element ( scc, placeholder) ;
483- }
484-
485- NllRegionVariableOrigin :: Existential { .. } => {
486- // For existential, regions, nothing to do.
487- }
488- }
489419 }
490420 }
491421
@@ -542,14 +472,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
542472 self . scc_values . region_value_str ( scc)
543473 }
544474
545- pub ( crate ) fn placeholders_contained_in (
546- & self ,
547- r : RegionVid ,
548- ) -> impl Iterator < Item = ty:: PlaceholderRegion > {
549- let scc = self . constraint_sccs . scc ( r) ;
550- self . scc_values . placeholders_contained_in ( scc)
551- }
552-
553475 /// Once region solving has completed, this function will return the member constraints that
554476 /// were applied to the value of a given SCC `scc`. See `AppliedMemberConstraint`.
555477 pub ( crate ) fn applied_member_constraints (
@@ -901,8 +823,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
901823 //
902824 // It doesn't matter *what* universe because the promoted `T` will
903825 // always be in the root universe.
904- if let Some ( p) = self . scc_values . placeholders_contained_in ( r_scc) . next ( ) {
905- debug ! ( "encountered placeholder in higher universe: {:?}, requiring 'static" , p) ;
826+ if let PlaceholderReachability :: Placeholders { min_placeholder, .. } =
827+ self . scc_annotations [ r_scc] . reachable_placeholders ( )
828+ {
829+ debug ! (
830+ "encountered placeholder in higher universe: {min_placeholder:?}, requiring 'static"
831+ ) ;
832+
906833 let static_r = self . universal_regions ( ) . fr_static ;
907834 propagated_outlives_requirements. push ( ClosureOutlivesRequirement {
908835 subject,
@@ -1792,14 +1719,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
17921719 match * element {
17931720 RegionElement :: Location ( l) => self . find_sub_region_live_at ( longer_fr, l) ,
17941721 RegionElement :: RootUniversalRegion ( r) => r,
1795- RegionElement :: PlaceholderRegion ( error_placeholder) => self
1796- . definitions
1797- . iter_enumerated ( )
1798- . find_map ( |( r, definition) | match definition. origin {
1799- NllRegionVariableOrigin :: Placeholder ( p) if p == error_placeholder => Some ( r) ,
1800- _ => None ,
1801- } )
1802- . unwrap ( ) ,
18031722 }
18041723 }
18051724
@@ -2082,6 +2001,21 @@ impl<'tcx> RegionInferenceContext<'tcx> {
20822001 self . scc_annotations [ scc] . representative . rvid ( )
20832002 }
20842003
2004+ /// If the representative of an SCC is a placeholder, return
2005+ /// its originating `PlaceholderRegion`.
2006+ pub ( crate ) fn placeholder_representative (
2007+ & self ,
2008+ scc : ConstraintSccIndex ,
2009+ ) -> Option < ty:: PlaceholderRegion > {
2010+ if let Representative :: Placeholder ( r) = self . scc_annotations [ scc] . representative
2011+ && let NllRegionVariableOrigin :: Placeholder ( p) = self . definitions [ r] . origin
2012+ {
2013+ Some ( p)
2014+ } else {
2015+ None
2016+ }
2017+ }
2018+
20852019 pub ( crate ) fn liveness_constraints ( & self ) -> & LivenessValues {
20862020 & self . liveness_constraints
20872021 }
0 commit comments