@@ -95,9 +95,11 @@ pub struct RegionInferenceContext<'tcx> {
95
95
/// visible from this index.
96
96
scc_universes : IndexVec < ConstraintSccIndex , ty:: UniverseIndex > ,
97
97
98
- /// Contains a "representative" from each SCC. This will be the
99
- /// minimal RegionVid belonging to that universe. It is used as a
100
- /// kind of hacky way to manage checking outlives relationships,
98
+ /// Contains the "representative" region of each SCC.
99
+ /// It is defined as the one with the minimal RegionVid, favoring
100
+ /// free regions, then placeholders, then existential regions.
101
+ ///
102
+ /// It is a hacky way to manage checking regions for equality,
101
103
/// since we can 'canonicalize' each region to the representative
102
104
/// of its SCC and be sure that -- if they have the same repr --
103
105
/// they *must* be equal (though not having the same repr does not
@@ -481,22 +483,28 @@ impl<'tcx> RegionInferenceContext<'tcx> {
481
483
scc_universes
482
484
}
483
485
484
- /// For each SCC, we compute a unique `RegionVid` (in fact, the
485
- /// minimal one that belongs to the SCC). See
486
+ /// For each SCC, we compute a unique `RegionVid`. See the
486
487
/// `scc_representatives` field of `RegionInferenceContext` for
487
488
/// more details.
488
489
fn compute_scc_representatives (
489
490
constraints_scc : & Sccs < RegionVid , ConstraintSccIndex > ,
490
491
definitions : & IndexSlice < RegionVid , RegionDefinition < ' tcx > > ,
491
492
) -> IndexVec < ConstraintSccIndex , ty:: RegionVid > {
492
493
let num_sccs = constraints_scc. num_sccs ( ) ;
493
- let next_region_vid = definitions. next_index ( ) ;
494
- let mut scc_representatives = IndexVec :: from_elem_n ( next_region_vid, num_sccs) ;
495
-
496
- for region_vid in definitions. indices ( ) {
497
- let scc = constraints_scc. scc ( region_vid) ;
498
- let prev_min = scc_representatives[ scc] ;
499
- scc_representatives[ scc] = region_vid. min ( prev_min) ;
494
+ let mut scc_representatives = IndexVec :: from_elem_n ( RegionVid :: MAX , num_sccs) ;
495
+
496
+ // Iterate over all RegionVids *in-order* and pick the least RegionVid as the
497
+ // representative of its SCC. This naturally prefers free regions over others.
498
+ for ( vid, def) in definitions. iter_enumerated ( ) {
499
+ let repr = & mut scc_representatives[ constraints_scc. scc ( vid) ] ;
500
+ if * repr == ty:: RegionVid :: MAX {
501
+ * repr = vid;
502
+ } else if matches ! ( def. origin, NllRegionVariableOrigin :: Placeholder ( _) )
503
+ && matches ! ( definitions[ * repr] . origin, NllRegionVariableOrigin :: Existential { .. } )
504
+ {
505
+ // Pick placeholders over existentials even if they have a greater RegionVid.
506
+ * repr = vid;
507
+ }
500
508
}
501
509
502
510
scc_representatives
0 commit comments