@@ -45,12 +45,13 @@ mod reverse_sccs;
45
45
46
46
pub ( crate ) mod values;
47
47
48
- pub ( crate ) type ConstraintSccs = Sccs < RegionVid , ConstraintSccIndex , RegionTracker > ;
48
+ pub ( crate ) type ConstraintSccs = Sccs < RegionVid , ConstraintSccIndex > ;
49
+ pub ( crate ) type AnnotatedSccs = ( ConstraintSccs , IndexVec < ConstraintSccIndex , RegionTracker > ) ;
49
50
50
51
/// An annotation for region graph SCCs that tracks
51
- /// the values of its elements.
52
+ /// the values of its elements. This annotates a single SCC.
52
53
#[ derive( Copy , Debug , Clone ) ]
53
- pub struct RegionTracker {
54
+ pub ( crate ) struct RegionTracker {
54
55
/// The largest universe of a placeholder reached from this SCC.
55
56
/// This includes placeholders within this SCC.
56
57
max_placeholder_universe_reached : UniverseIndex ,
@@ -95,6 +96,31 @@ impl scc::Annotation for RegionTracker {
95
96
}
96
97
}
97
98
99
+ /// A Visitor for SCC annotation construction.
100
+ pub ( crate ) struct SccAnnotations < ' d , ' tcx , A : scc:: Annotation > {
101
+ pub ( crate ) scc_to_annotation : IndexVec < ConstraintSccIndex , A > ,
102
+ definitions : & ' d IndexVec < RegionVid , RegionDefinition < ' tcx > > ,
103
+ }
104
+
105
+ impl < ' d , ' tcx , A : scc:: Annotation > SccAnnotations < ' d , ' tcx , A > {
106
+ pub ( crate ) fn new ( definitions : & ' d IndexVec < RegionVid , RegionDefinition < ' tcx > > ) -> Self {
107
+ Self { scc_to_annotation : IndexVec :: new ( ) , definitions }
108
+ }
109
+ }
110
+
111
+ impl scc:: Annotations < RegionVid , ConstraintSccIndex , RegionTracker >
112
+ for SccAnnotations < ' _ , ' _ , RegionTracker >
113
+ {
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
+
98
124
impl RegionTracker {
99
125
pub ( crate ) fn new ( rvid : RegionVid , definition : & RegionDefinition < ' _ > ) -> Self {
100
126
let ( representative_is_placeholder, representative_is_existential) = match definition. origin
@@ -166,6 +192,8 @@ pub struct RegionInferenceContext<'tcx> {
166
192
/// compute the values of each region.
167
193
constraint_sccs : ConstraintSccs ,
168
194
195
+ scc_annotations : IndexVec < ConstraintSccIndex , RegionTracker > ,
196
+
169
197
/// Reverse of the SCC constraint graph -- i.e., an edge `A -> B` exists if
170
198
/// `B: A`. This is used to compute the universal regions that are required
171
199
/// to outlive a given SCC. Computed lazily.
@@ -428,7 +456,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
428
456
. map ( |info| RegionDefinition :: new ( info. universe , info. origin ) )
429
457
. collect ( ) ;
430
458
431
- let constraint_sccs =
459
+ let ( constraint_sccs, scc_annotations ) =
432
460
outlives_constraints. add_outlives_static ( & universal_regions, & definitions) ;
433
461
let constraints = Frozen :: freeze ( outlives_constraints) ;
434
462
let constraint_graph = Frozen :: freeze ( constraints. graph ( definitions. len ( ) ) ) ;
@@ -455,6 +483,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
455
483
constraints,
456
484
constraint_graph,
457
485
constraint_sccs,
486
+ scc_annotations,
458
487
rev_scc_graph : None ,
459
488
member_constraints,
460
489
member_constraints_applied : Vec :: new ( ) ,
@@ -752,6 +781,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
752
781
debug ! ( value = ?self . scc_values. region_value_str( scc_a) ) ;
753
782
}
754
783
784
+ fn scc_annotations ( & self ) -> & IndexVec < ConstraintSccIndex , RegionTracker > {
785
+ & self . scc_annotations
786
+ }
787
+
755
788
/// Invoked for each `R0 member of [R1..Rn]` constraint.
756
789
///
757
790
/// `scc` is the SCC containing R0, and `choice_regions` are the
@@ -793,7 +826,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
793
826
794
827
// If the member region lives in a higher universe, we currently choose
795
828
// the most conservative option by leaving it unchanged.
796
- if !self . constraint_sccs ( ) . annotation ( scc) . min_universe ( ) . is_root ( ) {
829
+ if !self . scc_annotations ( ) [ scc] . min_universe ( ) . is_root ( ) {
797
830
return ;
798
831
}
799
832
@@ -869,8 +902,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
869
902
/// in `scc_a`. Used during constraint propagation, and only once
870
903
/// the value of `scc_b` has been computed.
871
904
fn universe_compatible ( & self , scc_b : ConstraintSccIndex , scc_a : ConstraintSccIndex ) -> bool {
872
- let a_annotation = self . constraint_sccs ( ) . annotation ( scc_a) ;
873
- let b_annotation = self . constraint_sccs ( ) . annotation ( scc_b) ;
905
+ let a_annotation = self . scc_annotations ( ) [ scc_a] ;
906
+ let b_annotation = self . scc_annotations ( ) [ scc_b] ;
874
907
let a_universe = a_annotation. min_universe ( ) ;
875
908
876
909
// If scc_b's declared universe is a subset of
@@ -986,7 +1019,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
986
1019
"lower_bound = {:?} r_scc={:?} universe={:?}" ,
987
1020
lower_bound,
988
1021
r_scc,
989
- self . constraint_sccs . annotation ( r_scc ) . min_universe( )
1022
+ self . scc_annotations ( ) [ r_scc ] . min_universe( )
990
1023
) ;
991
1024
// If the type test requires that `T: 'a` where `'a` is a
992
1025
// placeholder from another universe, that effectively requires
@@ -1467,7 +1500,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1467
1500
/// The minimum universe of any variable reachable from this
1468
1501
/// SCC, inside or outside of it.
1469
1502
fn scc_universe ( & self , scc : ConstraintSccIndex ) -> UniverseIndex {
1470
- self . constraint_sccs ( ) . annotation ( scc) . min_universe ( )
1503
+ self . scc_annotations ( ) [ scc] . min_universe ( )
1471
1504
}
1472
1505
1473
1506
/// Checks the final value for the free region `fr` to see if it
@@ -2214,7 +2247,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
2214
2247
/// they *must* be equal (though not having the same repr does not
2215
2248
/// mean they are unequal).
2216
2249
fn scc_representative ( & self , scc : ConstraintSccIndex ) -> RegionVid {
2217
- self . constraint_sccs . annotation ( scc ) . representative
2250
+ self . scc_annotations ( ) [ scc ] . representative
2218
2251
}
2219
2252
2220
2253
pub ( crate ) fn liveness_constraints ( & self ) -> & LivenessValues {
0 commit comments