@@ -47,12 +47,13 @@ mod reverse_sccs;
4747
4848pub ( crate ) mod values;
4949
50- pub ( crate ) type ConstraintSccs = Sccs < RegionVid , ConstraintSccIndex , RegionTracker > ;
50+ pub ( crate ) type ConstraintSccs = Sccs < RegionVid , ConstraintSccIndex > ;
51+ pub ( crate ) type AnnotatedSccs = ( ConstraintSccs , IndexVec < ConstraintSccIndex , RegionTracker > ) ;
5152
5253/// An annotation for region graph SCCs that tracks
53- /// the values of its elements.
54+ /// the values of its elements. This annotates a single SCC.
5455#[ derive( Copy , Debug , Clone ) ]
55- pub struct RegionTracker {
56+ pub ( crate ) struct RegionTracker {
5657 /// The largest universe of a placeholder reached from this SCC.
5758 /// This includes placeholders within this SCC.
5859 max_placeholder_universe_reached : UniverseIndex ,
@@ -97,6 +98,32 @@ impl scc::Annotation for RegionTracker {
9798 }
9899}
99100
101+ /// A Visitor for SCC annotation construction.
102+ pub ( crate ) struct SccAnnotations < ' d , ' tcx , A : scc:: Annotation > {
103+ pub ( crate ) scc_to_annotation : IndexVec < ConstraintSccIndex , A > ,
104+ definitions : & ' d IndexVec < RegionVid , RegionDefinition < ' tcx > > ,
105+ }
106+
107+ impl < ' d , ' tcx , A : scc:: Annotation > SccAnnotations < ' d , ' tcx , A > {
108+ pub ( crate ) fn new ( definitions : & ' d IndexVec < RegionVid , RegionDefinition < ' tcx > > ) -> Self {
109+ Self { scc_to_annotation : IndexVec :: new ( ) , definitions }
110+ }
111+ }
112+
113+ impl scc:: Annotations < RegionVid > for SccAnnotations < ' _ , ' _ , RegionTracker > {
114+ fn new ( & self , element : RegionVid ) -> RegionTracker {
115+ RegionTracker :: new ( element, & self . definitions [ element] )
116+ }
117+
118+ fn annotate_scc ( & mut self , scc : ConstraintSccIndex , annotation : RegionTracker ) {
119+ let idx = self . scc_to_annotation . push ( annotation) ;
120+ assert ! ( idx == scc) ;
121+ }
122+
123+ type Ann = RegionTracker ;
124+ type SccIdx = ConstraintSccIndex ;
125+ }
126+
100127impl RegionTracker {
101128 pub ( crate ) fn new ( rvid : RegionVid , definition : & RegionDefinition < ' _ > ) -> Self {
102129 let ( representative_is_placeholder, representative_is_existential) = match definition. origin
@@ -166,6 +193,8 @@ pub struct RegionInferenceContext<'tcx> {
166193 /// compute the values of each region.
167194 constraint_sccs : ConstraintSccs ,
168195
196+ scc_annotations : IndexVec < ConstraintSccIndex , RegionTracker > ,
197+
169198 /// Reverse of the SCC constraint graph -- i.e., an edge `A -> B` exists if
170199 /// `B: A`. This is used to compute the universal regions that are required
171200 /// to outlive a given SCC. Computed lazily.
@@ -446,7 +475,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
446475
447476 let definitions = create_definitions ( infcx, & universal_regions) ;
448477
449- let constraint_sccs =
478+ let ( constraint_sccs, scc_annotations ) =
450479 outlives_constraints. add_outlives_static ( & universal_regions, & definitions) ;
451480 let constraints = Frozen :: freeze ( outlives_constraints) ;
452481 let constraint_graph = Frozen :: freeze ( constraints. graph ( definitions. len ( ) ) ) ;
@@ -472,6 +501,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
472501 constraints,
473502 constraint_graph,
474503 constraint_sccs,
504+ scc_annotations,
475505 rev_scc_graph : None ,
476506 member_constraints,
477507 member_constraints_applied : Vec :: new ( ) ,
@@ -798,7 +828,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
798828
799829 // If the member region lives in a higher universe, we currently choose
800830 // the most conservative option by leaving it unchanged.
801- if !self . constraint_sccs ( ) . annotation ( scc) . min_universe ( ) . is_root ( ) {
831+ if !self . scc_universe ( scc) . is_root ( ) {
802832 return ;
803833 }
804834
@@ -874,8 +904,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
874904 /// in `scc_a`. Used during constraint propagation, and only once
875905 /// the value of `scc_b` has been computed.
876906 fn universe_compatible ( & self , scc_b : ConstraintSccIndex , scc_a : ConstraintSccIndex ) -> bool {
877- let a_annotation = self . constraint_sccs ( ) . annotation ( scc_a) ;
878- let b_annotation = self . constraint_sccs ( ) . annotation ( scc_b) ;
907+ let a_annotation = self . scc_annotations [ scc_a] ;
908+ let b_annotation = self . scc_annotations [ scc_b] ;
879909 let a_universe = a_annotation. min_universe ( ) ;
880910
881911 // If scc_b's declared universe is a subset of
@@ -991,7 +1021,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
9911021 "lower_bound = {:?} r_scc={:?} universe={:?}" ,
9921022 lower_bound,
9931023 r_scc,
994- self . constraint_sccs . annotation ( r_scc) . min_universe ( )
1024+ self . scc_universe ( r_scc)
9951025 ) ;
9961026 // If the type test requires that `T: 'a` where `'a` is a
9971027 // placeholder from another universe, that effectively requires
@@ -1472,7 +1502,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
14721502 /// The minimum universe of any variable reachable from this
14731503 /// SCC, inside or outside of it.
14741504 fn scc_universe ( & self , scc : ConstraintSccIndex ) -> UniverseIndex {
1475- self . constraint_sccs ( ) . annotation ( scc) . min_universe ( )
1505+ self . scc_annotations [ scc] . min_universe ( )
14761506 }
14771507
14781508 /// Checks the final value for the free region `fr` to see if it
@@ -2216,7 +2246,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
22162246 /// they *must* be equal (though not having the same repr does not
22172247 /// mean they are unequal).
22182248 fn scc_representative ( & self , scc : ConstraintSccIndex ) -> RegionVid {
2219- self . constraint_sccs . annotation ( scc) . representative
2249+ self . scc_annotations [ scc] . representative
22202250 }
22212251
22222252 pub ( crate ) fn liveness_constraints ( & self ) -> & LivenessValues {
0 commit comments