@@ -46,89 +46,53 @@ mod reverse_sccs;
4646
4747pub ( crate ) mod values;
4848
49- pub ( crate ) type ConstraintSccs = Sccs < RegionVid , ConstraintSccIndex , PlaceholderTracking > ;
50-
51- #[ derive( Copy , Clone , Debug ) ]
52- pub enum PlaceholderTracking {
53- Off ( Representative ) ,
54- On ( RegionTracker ) ,
49+ pub ( crate ) struct SccAnnotations < ' d , ' tcx , A : scc:: Annotation > {
50+ pub ( crate ) scc_to_annotation : IndexVec < ConstraintSccIndex , A > ,
51+ definitions : & ' d IndexVec < RegionVid , RegionDefinition < ' tcx > > ,
5552}
5653
57- impl scc:: Annotation for PlaceholderTracking {
58- fn merge_scc ( self , other : Self ) -> Self {
59- use PlaceholderTracking :: * ;
60-
61- match ( self , other) {
62- ( Off ( this) , Off ( that) ) => Off ( this. merge_scc ( that) ) ,
63- ( On ( this) , On ( that) ) => On ( this. merge_scc ( that) ) ,
64- _ => unreachable ! ( ) ,
65- }
66- }
67-
68- fn merge_reached ( self , other : Self ) -> Self {
69- use PlaceholderTracking :: * ;
70-
71- match ( self , other) {
72- ( Off ( this) , Off ( that) ) => Off ( this. merge_reached ( that) ) ,
73- ( On ( this) , On ( that) ) => On ( this. merge_reached ( that) ) ,
74- _ => unreachable ! ( ) ,
75- }
54+ impl < ' d , ' tcx , A : scc:: Annotation > SccAnnotations < ' d , ' tcx , A > {
55+ pub ( crate ) fn init ( definitions : & ' d IndexVec < RegionVid , RegionDefinition < ' tcx > > ) -> Self {
56+ Self { scc_to_annotation : IndexVec :: new ( ) , definitions }
7657 }
7758}
7859
79- impl PlaceholderTracking {
80- pub ( crate ) fn representative_rvid ( & self ) -> RegionVid {
81- match self {
82- PlaceholderTracking :: Off ( r) => r. rvid ( ) ,
83- PlaceholderTracking :: On ( region_tracker) => region_tracker. representative_rvid ( ) ,
84- }
85- }
86-
87- pub ( crate ) fn reaches_other_placeholder ( & self , other : RegionVid ) -> Option < RegionVid > {
88- match self {
89- PlaceholderTracking :: Off ( _) => None ,
90- PlaceholderTracking :: On ( region_tracker) => {
91- region_tracker. reaches_other_placeholder ( other)
92- }
93- }
60+ impl scc:: Annotations < RegionVid , ConstraintSccIndex , RegionTracker >
61+ for SccAnnotations < ' _ , ' _ , RegionTracker >
62+ {
63+ fn new ( & self , element : RegionVid ) -> RegionTracker {
64+ RegionTracker :: new ( element, & self . definitions [ element] )
9465 }
9566
96- pub ( crate ) fn universe_violation ( & self ) -> Option < RegionVid > {
97- match self {
98- PlaceholderTracking :: Off ( _) => None ,
99- PlaceholderTracking :: On ( region_tracker) => region_tracker. universe_violation ( ) ,
100- }
67+ fn annotate_scc ( & mut self , scc : ConstraintSccIndex , annotation : RegionTracker ) {
68+ let idx = self . scc_to_annotation . push ( annotation) ;
69+ assert ! ( idx == scc) ;
10170 }
71+ }
10272
103- fn min_universe ( & self ) -> UniverseIndex {
104- match self {
105- PlaceholderTracking :: Off ( _ ) => UniverseIndex :: ROOT , // Not technically correct?
106- PlaceholderTracking :: On ( region_tracker ) => region_tracker . min_universe ( ) ,
107- }
73+ impl scc :: Annotations < RegionVid , ConstraintSccIndex , Representative >
74+ for SccAnnotations < ' _ , ' _ , Representative >
75+ {
76+ fn new ( & self , element : RegionVid ) -> Representative {
77+ Representative :: new ( element , self . definitions )
10878 }
10979
110- fn universe_compatible_with ( & self , other : PlaceholderTracking ) -> bool {
111- use PlaceholderTracking :: * ;
112- match ( self , other) {
113- ( Off ( _) , Off ( _) ) => true , // Not technically correct?
114- ( On ( this) , On ( that) ) => this. universe_compatible_with ( that) ,
115- _ => unreachable ! ( ) ,
116- }
80+ fn annotate_scc ( & mut self , scc : ConstraintSccIndex , annotation : Representative ) {
81+ let idx = self . scc_to_annotation . push ( annotation) ;
82+ assert ! ( idx == scc) ;
11783 }
84+ }
11885
119- fn placeholder_representative ( & self ) -> Option < RegionVid > {
120- match self {
121- PlaceholderTracking :: Off ( _) => None ,
122- PlaceholderTracking :: On ( region_tracker) => region_tracker. placeholder_representative ( ) ,
123- }
124- }
86+ pub ( crate ) enum PlaceholderTracking {
87+ Off ( IndexVec < ConstraintSccIndex , Representative > ) ,
88+ On ( IndexVec < ConstraintSccIndex , RegionTracker > ) ,
12589}
12690
12791/// The representative region variable for an SCC, tagged by its origin.
12892/// We prefer placeholders over existentially quantified variables, otherwise
12993/// it's the one with the smallest Region Variable ID.
13094#[ derive( Copy , Debug , Clone , PartialEq , PartialOrd , Eq , Ord ) ]
131- pub enum Representative {
95+ pub ( crate ) enum Representative {
13296 FreeRegion ( RegionVid ) ,
13397 Placeholder ( RegionVid ) ,
13498 Existential ( RegionVid ) ,
@@ -217,7 +181,7 @@ impl PlaceholderReachability {
217181/// An annotation for region graph SCCs that tracks
218182/// the values of its elements.
219183#[ derive( Copy , Debug , Clone ) ]
220- pub struct RegionTracker {
184+ pub ( crate ) struct RegionTracker {
221185 /// The representative Region Variable Id for this SCC.
222186 representative : Representative ,
223187
@@ -379,7 +343,9 @@ pub struct RegionInferenceContext<'tcx> {
379343 /// The SCC computed from `constraints` and the constraint
380344 /// graph. We have an edge from SCC A to SCC B if `A: B`. Used to
381345 /// compute the values of each region.
382- constraint_sccs : ConstraintSccs ,
346+ constraint_sccs : Sccs < RegionVid , ConstraintSccIndex > ,
347+
348+ scc_annotations : PlaceholderTracking ,
383349
384350 /// Reverse of the SCC constraint graph -- i.e., an edge `A -> B` exists if
385351 /// `B: A`. This is used to compute the universal regions that are required
@@ -541,9 +507,9 @@ pub(crate) enum ExtraConstraintInfo {
541507}
542508
543509#[ instrument( skip( infcx, sccs) , level = "debug" ) ]
544- fn sccs_info < ' tcx , A : scc :: Annotation > (
510+ fn sccs_info < ' tcx > (
545511 infcx : & BorrowckInferCtxt < ' tcx > ,
546- sccs : & scc:: Sccs < RegionVid , ConstraintSccIndex , A > ,
512+ sccs : & scc:: Sccs < RegionVid , ConstraintSccIndex > ,
547513) {
548514 use crate :: renumber:: RegionCtxt ;
549515
@@ -624,7 +590,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
624590 universe_causes : FxIndexMap < ty:: UniverseIndex , UniverseInfo < ' tcx > > ,
625591 type_tests : Vec < TypeTest < ' tcx > > ,
626592 mut liveness_constraints : LivenessValues ,
627- elements : & Rc < DenseLocationMap > ,
593+ elements : Rc < DenseLocationMap > ,
628594 ) -> Self {
629595 debug ! ( "universal_regions: {:#?}" , universal_regions) ;
630596 debug ! ( "outlives constraints: {:#?}" , outlives_constraints) ;
@@ -650,14 +616,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
650616 ( definitions, has_placeholders)
651617 } ;
652618
653- let constraint_sccs = if has_placeholders {
619+ let ( constraint_sccs, scc_annotations ) = if has_placeholders {
654620 debug ! ( "Placeholders present; activating placeholder handling logic!" ) ;
655621 outlives_constraints. add_outlives_static ( & universal_regions, & definitions)
656622 } else {
657623 debug ! ( "No placeholders in MIR body; disabling their validation." ) ;
658- outlives_constraints. compute_sccs ( universal_regions. fr_static , & definitions, |r| {
659- PlaceholderTracking :: Off ( Representative :: new ( r, & definitions) )
660- } )
624+ let mut annotator = SccAnnotations :: init ( & definitions) ;
625+ let sccs = outlives_constraints. compute_sccs (
626+ universal_regions. fr_static ,
627+ definitions. len ( ) ,
628+ & mut annotator,
629+ ) ;
630+ ( sccs, PlaceholderTracking :: Off ( annotator. scc_to_annotation ) )
661631 } ;
662632 let constraints = Frozen :: freeze ( outlives_constraints) ;
663633 let constraint_graph = Frozen :: freeze ( constraints. graph ( definitions. len ( ) ) ) ;
@@ -707,6 +677,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
707677 type_tests,
708678 universal_regions,
709679 universal_region_relations,
680+ scc_annotations,
710681 }
711682 }
712683
@@ -932,8 +903,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
932903
933904 // If the member region lives in a higher universe, we currently choose
934905 // the most conservative option by leaving it unchanged.
935-
936- if !self . constraint_sccs ( ) . annotation ( scc) . min_universe ( ) . is_root ( ) {
906+ if !self . scc_universe ( scc) . is_root ( ) {
937907 return ;
938908 }
939909
@@ -1005,9 +975,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1005975 /// in `scc_a`. Used during constraint propagation, and only once
1006976 /// the value of `scc_b` has been computed.
1007977 fn universe_compatible ( & self , scc_b : ConstraintSccIndex , scc_a : ConstraintSccIndex ) -> bool {
1008- self . constraint_sccs ( )
1009- . annotation ( scc_a)
1010- . universe_compatible_with ( self . constraint_sccs ( ) . annotation ( scc_b) )
978+ match & self . scc_annotations {
979+ // This isn't technically true but seems to work.
980+ PlaceholderTracking :: Off ( _) => true ,
981+ PlaceholderTracking :: On ( annotations) => {
982+ annotations[ scc_a] . universe_compatible_with ( annotations[ scc_b] )
983+ }
984+ }
1011985 }
1012986
1013987 /// Once regions have been propagated, this method is used to see
@@ -1115,7 +1089,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
11151089 "lower_bound = {:?} r_scc={:?} universe={:?}" ,
11161090 lower_bound,
11171091 r_scc,
1118- self . constraint_sccs . annotation ( r_scc) . min_universe ( )
1092+ self . scc_universe ( r_scc)
11191093 ) ;
11201094
11211095 // If the type test requires that `T: 'a` where `'a` is a
@@ -1125,7 +1099,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
11251099 // It doesn't matter *what* universe because the promoted `T` will
11261100 // always be in the root universe.
11271101
1128- if let Some ( p) = self . constraint_sccs . annotation ( r_scc ) . placeholder_representative ( ) {
1102+ if let Some ( p) = self . placeholder_representative ( r_scc ) {
11291103 debug ! ( "encountered placeholder in higher universe: {:?}, requiring 'static" , p) ;
11301104 let static_r = self . universal_regions . fr_static ;
11311105 propagated_outlives_requirements. push ( ClosureOutlivesRequirement {
@@ -1633,7 +1607,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
16331607 /// The minimum universe of any variable reachable from this
16341608 /// SCC, inside or outside of it.
16351609 fn scc_universe ( & self , scc : ConstraintSccIndex ) -> UniverseIndex {
1636- self . constraint_sccs ( ) . annotation ( scc) . min_universe ( )
1610+ match & self . scc_annotations {
1611+ PlaceholderTracking :: Off ( _) => UniverseIndex :: ROOT , // Not technically correct?
1612+ PlaceholderTracking :: On ( annotations) => annotations[ scc] . min_universe ( ) ,
1613+ }
16371614 }
16381615 /// Checks the final value for the free region `fr` to see if it
16391616 /// grew too large. In particular, examine what `end(X)` points
@@ -2303,7 +2280,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
23032280 /// This can be used to quickly under-approximate the regions which are equal to each other
23042281 /// and their relative orderings.
23052282 // This is `pub` because it's used by unstable external borrowck data users, see `consumers.rs`.
2306- pub fn constraint_sccs ( & self ) -> & ConstraintSccs {
2283+ pub fn constraint_sccs ( & self ) -> & Sccs < RegionVid , ConstraintSccIndex > {
23072284 & self . constraint_sccs
23082285 }
23092286
@@ -2343,7 +2320,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
23432320 /// they *must* be equal (though not having the same repr does not
23442321 /// mean they are unequal).
23452322 fn scc_representative ( & self , scc : ConstraintSccIndex ) -> RegionVid {
2346- self . constraint_sccs . annotation ( scc) . representative_rvid ( )
2323+ match & self . scc_annotations {
2324+ PlaceholderTracking :: Off ( annotations) => annotations[ scc] . rvid ( ) ,
2325+ PlaceholderTracking :: On ( annotations) => annotations[ scc] . representative_rvid ( ) ,
2326+ }
23472327 }
23482328
23492329 /// Returns true if `r` is `'static`.
@@ -2357,13 +2337,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
23572337 & self ,
23582338 scc : ConstraintSccIndex ,
23592339 ) -> Option < PlaceholderRegion > {
2360- if let Some ( representative) =
2361- self . constraint_sccs . annotation ( scc) . placeholder_representative ( )
2362- && let NllRegionVariableOrigin :: Placeholder ( p) = self . definitions [ representative] . origin
2363- {
2364- Some ( p)
2365- } else {
2366- None
2340+ match & self . scc_annotations {
2341+ PlaceholderTracking :: Off ( _) => None ,
2342+ PlaceholderTracking :: On ( annotations) => {
2343+ if let Some ( representative) = annotations[ scc] . placeholder_representative ( )
2344+ && let NllRegionVariableOrigin :: Placeholder ( p) =
2345+ self . definitions [ representative] . origin
2346+ {
2347+ Some ( p)
2348+ } else {
2349+ None
2350+ }
2351+ }
23672352 }
23682353 }
23692354}
0 commit comments