@@ -24,12 +24,59 @@ use crate::type_check::{Locations, MirTypeckRegionConstraints};
2424use crate :: universal_regions:: UniversalRegions ;
2525use crate :: { BorrowckInferCtxt , NllRegionVariableOrigin } ;
2626
27+ pub ( crate ) trait RegionSccs {
28+ fn representative ( & self , scc : ConstraintSccIndex ) -> RegionVid ;
29+ fn reachable_placeholders ( & self , _scc : ConstraintSccIndex ) -> Option < PlaceholderReachability > {
30+ None
31+ }
32+ /// The largest universe this SCC can name. It's the smallest
33+ /// largest nameable universe of any reachable region, or
34+ /// `max_nameable(r) = min (max_nameable(r') for r' reachable from r)`
35+ fn max_nameable_universe ( & self , _scc : ConstraintSccIndex ) -> UniverseIndex {
36+ UniverseIndex :: ROOT
37+ }
38+ fn max_placeholder_universe_reached ( & self , _scc : ConstraintSccIndex ) -> UniverseIndex {
39+ UniverseIndex :: ROOT
40+ }
41+ }
42+
43+ impl RegionSccs for IndexVec < ConstraintSccIndex , RegionTracker > {
44+ fn representative ( & self , scc : ConstraintSccIndex ) -> RegionVid {
45+ self [ scc] . representative . rvid ( )
46+ }
47+
48+ fn reachable_placeholders ( & self , scc : ConstraintSccIndex ) -> Option < PlaceholderReachability > {
49+ self [ scc] . reachable_placeholders
50+ }
51+
52+ fn max_nameable_universe ( & self , scc : ConstraintSccIndex ) -> UniverseIndex {
53+ // Note that this is stricter than it might need to be!
54+ self [ scc] . min_max_nameable_universe
55+ }
56+
57+ fn max_placeholder_universe_reached ( & self , scc : ConstraintSccIndex ) -> UniverseIndex {
58+ self [ scc] . reachable_placeholders . map ( |p| p. max_universe . u ) . unwrap_or ( UniverseIndex :: ROOT )
59+ }
60+ }
61+
62+ impl RegionSccs for IndexVec < ConstraintSccIndex , Representative > {
63+ fn representative ( & self , scc : ConstraintSccIndex ) -> RegionVid {
64+ self [ scc] . rvid ( )
65+ }
66+ }
67+
68+ impl FromRegionDefinition for Representative {
69+ fn new ( rvid : RegionVid , definition : & RegionDefinition < ' _ > ) -> Self {
70+ Representative :: new ( rvid, definition)
71+ }
72+ }
73+
2774/// A set of outlives constraints after rewriting to remove
2875/// higher-kinded constraints.
2976pub ( crate ) struct LoweredConstraints < ' tcx > {
3077 pub ( crate ) constraint_sccs : Sccs < RegionVid , ConstraintSccIndex > ,
3178 pub ( crate ) definitions : Frozen < IndexVec < RegionVid , RegionDefinition < ' tcx > > > ,
32- pub ( crate ) scc_annotations : IndexVec < ConstraintSccIndex , RegionTracker > ,
79+ pub ( crate ) scc_annotations : Box < dyn RegionSccs > ,
3380 pub ( crate ) outlives_constraints : Frozen < OutlivesConstraintSet < ' tcx > > ,
3481 pub ( crate ) type_tests : Vec < TypeTest < ' tcx > > ,
3582 pub ( crate ) liveness_constraints : LivenessValues ,
@@ -42,23 +89,28 @@ impl<'d, 'tcx, A: scc::Annotation> SccAnnotations<'d, 'tcx, A> {
4289 }
4390}
4491
92+ trait FromRegionDefinition {
93+ fn new ( rvid : RegionVid , definition : & RegionDefinition < ' _ > ) -> Self ;
94+ }
95+
4596/// A Visitor for SCC annotation construction.
4697pub ( crate ) struct SccAnnotations < ' d , ' tcx , A : scc:: Annotation > {
4798 pub ( crate ) scc_to_annotation : IndexVec < ConstraintSccIndex , A > ,
4899 definitions : & ' d IndexVec < RegionVid , RegionDefinition < ' tcx > > ,
49100}
50-
51- impl scc:: Annotations < RegionVid > for SccAnnotations < ' _ , ' _ , RegionTracker > {
52- fn new ( & self , element : RegionVid ) -> RegionTracker {
53- RegionTracker :: new ( element, & self . definitions [ element] )
101+ impl < A : scc:: Annotation + FromRegionDefinition > scc:: Annotations < RegionVid >
102+ for SccAnnotations < ' _ , ' _ , A >
103+ {
104+ fn new ( & self , element : RegionVid ) -> A {
105+ A :: new ( element, & self . definitions [ element] )
54106 }
55107
56- fn annotate_scc ( & mut self , scc : ConstraintSccIndex , annotation : RegionTracker ) {
108+ fn annotate_scc ( & mut self , scc : ConstraintSccIndex , annotation : A ) {
57109 let idx = self . scc_to_annotation . push ( annotation) ;
58110 assert ! ( idx == scc) ;
59111 }
60112
61- type Ann = RegionTracker ;
113+ type Ann = A ;
62114 type SccIdx = ConstraintSccIndex ;
63115}
64116
@@ -127,8 +179,8 @@ pub(crate) struct RegionTracker {
127179 pub ( crate ) representative : Representative ,
128180}
129181
130- impl RegionTracker {
131- pub ( crate ) fn new ( rvid : RegionVid , definition : & RegionDefinition < ' _ > ) -> Self {
182+ impl FromRegionDefinition for RegionTracker {
183+ fn new ( rvid : RegionVid , definition : & RegionDefinition < ' _ > ) -> Self {
132184 use NllRegionVariableOrigin :: * ;
133185
134186 let min_max_nameable_universe = definition. universe ;
@@ -163,24 +215,12 @@ impl RegionTracker {
163215 } ,
164216 }
165217 }
166-
167- /// The largest universe this SCC can name. It's the smallest
168- /// largest nameable universe of any reachable region, or
169- /// `max_nameable(r) = min (max_nameable(r') for r' reachable from r)`
170- pub ( crate ) fn max_nameable_universe ( self ) -> UniverseIndex {
171- // Note that this is stricter than it might need to be!
172- self . min_max_nameable_universe
173- }
174-
175- pub ( crate ) fn max_placeholder_universe_reached ( self ) -> UniverseIndex {
176- self . reachable_placeholders . map ( |p| p. max_universe . u ) . unwrap_or ( UniverseIndex :: ROOT )
177- }
178218}
179219
180220impl scc:: Annotation for RegionTracker {
181221 fn update_scc ( & mut self , other : & Self ) {
182222 trace ! ( "{:?} << {:?}" , self . representative, other. representative) ;
183- self . representative = self . representative . min ( other. representative ) ;
223+ self . representative . update_scc ( & other. representative ) ;
184224 self . is_placeholder = self . is_placeholder . max ( other. is_placeholder ) ;
185225 self . update_reachable ( other) ; // SCC membership implies reachability.
186226 }
@@ -291,26 +331,32 @@ pub(crate) fn compute_sccs_applying_placeholder_outlives_constraints<'tcx>(
291331 )
292332 } ;
293333
294- let mut scc_annotations = SccAnnotations :: init ( & definitions) ;
295- let constraint_sccs = compute_sccs ( & outlives_constraints, & mut scc_annotations) ;
296-
297- // This code structure is a bit convoluted because it allows for a planned
298- // future change where the early return here has a different type of annotation
299- // that does much less work.
300334 if !has_placeholders {
301335 debug ! ( "No placeholder regions found; skipping rewriting logic!" ) ;
302336
337+ // We skip the extra logic and only record representatives.
338+ let mut scc_annotations: SccAnnotations < ' _ , ' _ , Representative > =
339+ SccAnnotations :: init ( & definitions) ;
340+ let constraint_sccs = ConstraintSccs :: new_with_annotation (
341+ & outlives_constraints
342+ . graph ( definitions. len ( ) )
343+ . region_graph ( & outlives_constraints, fr_static) ,
344+ & mut scc_annotations,
345+ ) ;
346+
303347 return LoweredConstraints {
304348 type_tests,
305349 constraint_sccs,
306- scc_annotations : scc_annotations. scc_to_annotation ,
350+ scc_annotations : Box :: new ( scc_annotations. scc_to_annotation ) ,
307351 definitions,
308352 outlives_constraints : Frozen :: freeze ( outlives_constraints) ,
309353 liveness_constraints,
310354 universe_causes,
311355 } ;
312356 }
313357 debug ! ( "Placeholders present; activating placeholder handling logic!" ) ;
358+ let mut scc_annotations = SccAnnotations :: init ( & definitions) ;
359+ let constraint_sccs = compute_sccs ( & outlives_constraints, & mut scc_annotations) ;
314360
315361 let added_constraints = rewrite_placeholder_outlives (
316362 & constraint_sccs,
@@ -338,7 +384,7 @@ pub(crate) fn compute_sccs_applying_placeholder_outlives_constraints<'tcx>(
338384 LoweredConstraints {
339385 constraint_sccs,
340386 definitions,
341- scc_annotations,
387+ scc_annotations : Box :: new ( scc_annotations ) ,
342388 outlives_constraints : Frozen :: freeze ( outlives_constraints) ,
343389 type_tests,
344390 liveness_constraints,
0 commit comments