@@ -47,12 +47,13 @@ mod reverse_sccs;
47
47
48
48
pub ( crate ) mod values;
49
49
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 > ) ;
51
52
52
53
/// 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.
54
55
#[ derive( Copy , Debug , Clone ) ]
55
- pub struct RegionTracker {
56
+ pub ( crate ) struct RegionTracker {
56
57
/// The largest universe of a placeholder reached from this SCC.
57
58
/// This includes placeholders within this SCC.
58
59
max_placeholder_universe_reached : UniverseIndex ,
@@ -97,6 +98,31 @@ impl scc::Annotation for RegionTracker {
97
98
}
98
99
}
99
100
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 , ConstraintSccIndex , RegionTracker >
114
+ for SccAnnotations < ' _ , ' _ , RegionTracker >
115
+ {
116
+ fn new ( & self , element : RegionVid ) -> RegionTracker {
117
+ RegionTracker :: new ( element, & self . definitions [ element] )
118
+ }
119
+
120
+ fn annotate_scc ( & mut self , scc : ConstraintSccIndex , annotation : RegionTracker ) {
121
+ let idx = self . scc_to_annotation . push ( annotation) ;
122
+ assert ! ( idx == scc) ;
123
+ }
124
+ }
125
+
100
126
impl RegionTracker {
101
127
pub ( crate ) fn new ( rvid : RegionVid , definition : & RegionDefinition < ' _ > ) -> Self {
102
128
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.
@@ -446,7 +474,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
446
474
447
475
let definitions = create_definitions ( infcx, & universal_regions) ;
448
476
449
- let constraint_sccs =
477
+ let ( constraint_sccs, scc_annotations ) =
450
478
outlives_constraints. add_outlives_static ( & universal_regions, & definitions) ;
451
479
let constraints = Frozen :: freeze ( outlives_constraints) ;
452
480
let constraint_graph = Frozen :: freeze ( constraints. graph ( definitions. len ( ) ) ) ;
@@ -472,6 +500,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
472
500
constraints,
473
501
constraint_graph,
474
502
constraint_sccs,
503
+ scc_annotations,
475
504
rev_scc_graph : None ,
476
505
member_constraints,
477
506
member_constraints_applied : Vec :: new ( ) ,
@@ -757,6 +786,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
757
786
debug ! ( value = ?self . scc_values. region_value_str( scc_a) ) ;
758
787
}
759
788
789
+ fn scc_annotations ( & self ) -> & IndexVec < ConstraintSccIndex , RegionTracker > {
790
+ & self . scc_annotations
791
+ }
792
+
760
793
/// Invoked for each `R0 member of [R1..Rn]` constraint.
761
794
///
762
795
/// `scc` is the SCC containing R0, and `choice_regions` are the
@@ -798,7 +831,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
798
831
799
832
// If the member region lives in a higher universe, we currently choose
800
833
// the most conservative option by leaving it unchanged.
801
- if !self . constraint_sccs ( ) . annotation ( scc) . min_universe ( ) . is_root ( ) {
834
+ if !self . scc_annotations ( ) [ scc] . min_universe ( ) . is_root ( ) {
802
835
return ;
803
836
}
804
837
@@ -874,8 +907,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
874
907
/// in `scc_a`. Used during constraint propagation, and only once
875
908
/// the value of `scc_b` has been computed.
876
909
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) ;
910
+ let a_annotation = self . scc_annotations ( ) [ scc_a] ;
911
+ let b_annotation = self . scc_annotations ( ) [ scc_b] ;
879
912
let a_universe = a_annotation. min_universe ( ) ;
880
913
881
914
// If scc_b's declared universe is a subset of
@@ -991,7 +1024,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
991
1024
"lower_bound = {:?} r_scc={:?} universe={:?}" ,
992
1025
lower_bound,
993
1026
r_scc,
994
- self . constraint_sccs . annotation ( r_scc ) . min_universe( )
1027
+ self . scc_annotations ( ) [ r_scc ] . min_universe( )
995
1028
) ;
996
1029
// If the type test requires that `T: 'a` where `'a` is a
997
1030
// placeholder from another universe, that effectively requires
@@ -1472,7 +1505,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1472
1505
/// The minimum universe of any variable reachable from this
1473
1506
/// SCC, inside or outside of it.
1474
1507
fn scc_universe ( & self , scc : ConstraintSccIndex ) -> UniverseIndex {
1475
- self . constraint_sccs ( ) . annotation ( scc) . min_universe ( )
1508
+ self . scc_annotations ( ) [ scc] . min_universe ( )
1476
1509
}
1477
1510
1478
1511
/// Checks the final value for the free region `fr` to see if it
@@ -2219,7 +2252,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
2219
2252
/// they *must* be equal (though not having the same repr does not
2220
2253
/// mean they are unequal).
2221
2254
fn scc_representative ( & self , scc : ConstraintSccIndex ) -> RegionVid {
2222
- self . constraint_sccs . annotation ( scc ) . representative
2255
+ self . scc_annotations ( ) [ scc ] . representative
2223
2256
}
2224
2257
2225
2258
pub ( crate ) fn liveness_constraints ( & self ) -> & LivenessValues {
0 commit comments