Skip to content

Commit 676d042

Browse files
committed
favor placeholders over existentials when choosing SCC representatives
... even when the existential has the least RegionVid. universal regions (of root universe) > placeholders > existentials The previous behavior, that chooses the minimal RegionVid index, naturally prefers universal regions over others because they always have the least RegionVids, but there was no guranteed ordering between placeholders and existentials.
1 parent 5d5edf0 commit 676d042

File tree

1 file changed

+19
-12
lines changed
  • compiler/rustc_borrowck/src/region_infer

1 file changed

+19
-12
lines changed

compiler/rustc_borrowck/src/region_infer/mod.rs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,11 @@ pub struct RegionInferenceContext<'tcx> {
9797
/// visible from this index.
9898
scc_universes: IndexVec<ConstraintSccIndex, ty::UniverseIndex>,
9999

100-
/// Contains a "representative" from each SCC. This will be the
101-
/// minimal RegionVid belonging to that universe. It is used as a
102-
/// kind of hacky way to manage checking outlives relationships,
100+
/// Contains the "representative" region of each SCC.
101+
/// It is defined as the one with the minimal RegionVid, favoring
102+
/// free regions, then placeholders, then existential regions.
103+
///
104+
/// It is a hacky way to manage checking regions for equality,
103105
/// since we can 'canonicalize' each region to the representative
104106
/// of its SCC and be sure that -- if they have the same repr --
105107
/// they *must* be equal (though not having the same repr does not
@@ -487,22 +489,27 @@ impl<'tcx> RegionInferenceContext<'tcx> {
487489
scc_universes
488490
}
489491

490-
/// For each SCC, we compute a unique `RegionVid` (in fact, the
491-
/// minimal one that belongs to the SCC). See
492+
/// For each SCC, we compute a unique `RegionVid`. See
492493
/// `scc_representatives` field of `RegionInferenceContext` for
493494
/// more details.
494495
fn compute_scc_representatives(
495496
constraints_scc: &Sccs<RegionVid, ConstraintSccIndex>,
496497
definitions: &IndexSlice<RegionVid, RegionDefinition<'tcx>>,
497498
) -> IndexVec<ConstraintSccIndex, ty::RegionVid> {
498499
let num_sccs = constraints_scc.num_sccs();
499-
let next_region_vid = definitions.next_index();
500-
let mut scc_representatives = IndexVec::from_elem_n(next_region_vid, num_sccs);
501-
502-
for region_vid in definitions.indices() {
503-
let scc = constraints_scc.scc(region_vid);
504-
let prev_min = scc_representatives[scc];
505-
scc_representatives[scc] = region_vid.min(prev_min);
500+
let mut scc_representatives = IndexVec::from_elem_n(ty::RegionVid::MAX, num_sccs);
501+
502+
for (vid, def) in definitions.iter_enumerated() {
503+
use NllRegionVariableOrigin as VarOrigin;
504+
let scc = constraints_scc.scc(vid);
505+
let repr = &mut scc_representatives[scc];
506+
if *repr == ty::RegionVid::MAX {
507+
*repr = vid;
508+
} else if matches!(def.origin, VarOrigin::Placeholder(_))
509+
&& matches!(definitions[*repr].origin, VarOrigin::Existential { .. })
510+
{
511+
*repr = vid;
512+
}
506513
}
507514

508515
scc_representatives

0 commit comments

Comments
 (0)