Skip to content

Commit af75e13

Browse files
committed
Use an enum for SCC representatives
1 parent dbc6b67 commit af75e13

File tree

2 files changed

+57
-40
lines changed

2 files changed

+57
-40
lines changed

compiler/rustc_borrowck/src/eliminate_placeholders.rs

+14-38
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::consumers::OutlivesConstraint;
1818
use crate::diagnostics::UniverseInfo;
1919
use crate::member_constraints::MemberConstraintSet;
2020
use crate::region_infer::values::{LivenessValues, PlaceholderIndices};
21-
use crate::region_infer::{ConstraintSccs, RegionDefinition, TypeTest};
21+
use crate::region_infer::{ConstraintSccs, RegionDefinition, Representative, TypeTest};
2222
use crate::ty::VarianceDiagInfo;
2323
use crate::type_check::free_region_relations::UniversalRegionRelations;
2424
use crate::type_check::{Locations, MirTypeckRegionConstraints};
@@ -76,36 +76,23 @@ pub(crate) struct RegionTracker {
7676
/// The smallest universe index reachable form the nodes of this SCC.
7777
min_reachable_universe: UniverseIndex,
7878

79-
/// The representative Region Variable Id for this SCC. We prefer
80-
/// placeholders over existentially quantified variables, otherwise
81-
/// it's the one with the smallest Region Variable ID.
82-
pub(crate) representative: RegionVid,
83-
84-
/// Is the current representative a placeholder?
85-
representative_is_placeholder: bool,
86-
87-
/// Is the current representative existentially quantified?
88-
representative_is_existential: bool,
79+
/// The representative Region Variable Id for this SCC.
80+
pub(crate) representative: Representative,
8981
}
9082

9183
impl RegionTracker {
9284
pub(crate) fn new(rvid: RegionVid, definition: &RegionDefinition<'_>) -> Self {
93-
let (representative_is_placeholder, representative_is_existential) = match definition.origin
94-
{
95-
NllRegionVariableOrigin::FreeRegion => (false, false),
96-
NllRegionVariableOrigin::Placeholder(_) => (true, false),
97-
NllRegionVariableOrigin::Existential { .. } => (false, true),
98-
};
99-
10085
let placeholder_universe =
101-
if representative_is_placeholder { definition.universe } else { UniverseIndex::ROOT };
86+
if matches!(definition.origin, NllRegionVariableOrigin::Placeholder(_)) {
87+
definition.universe
88+
} else {
89+
UniverseIndex::ROOT
90+
};
10291

10392
Self {
10493
max_placeholder_universe_reached: placeholder_universe,
10594
min_reachable_universe: definition.universe,
106-
representative: rvid,
107-
representative_is_placeholder,
108-
representative_is_existential,
95+
representative: Representative::new(rvid, definition),
10996
}
11097
}
11198

@@ -139,21 +126,10 @@ impl RegionTracker {
139126
}
140127

141128
impl scc::Annotation for RegionTracker {
142-
fn merge_scc(mut self, mut other: Self) -> Self {
143-
// Prefer any placeholder over any existential
144-
if other.representative_is_placeholder && self.representative_is_existential {
145-
other.merge_min_max_seen(&self);
146-
return other;
147-
}
148-
149-
if self.representative_is_placeholder && other.representative_is_existential
150-
|| (self.representative <= other.representative)
151-
{
152-
self.merge_min_max_seen(&other);
153-
return self;
154-
}
155-
other.merge_min_max_seen(&self);
156-
other
129+
fn merge_scc(mut self, other: Self) -> Self {
130+
self.representative = self.representative.merge_scc(other.representative);
131+
self.merge_min_max_seen(&other);
132+
self
157133
}
158134

159135
fn merge_reached(mut self, other: Self) -> Self {
@@ -356,7 +332,7 @@ fn rewrite_outlives<'tcx>(
356332
// outlive static.
357333
outlives_static.insert(scc);
358334
let scc_representative_outlives_static = OutlivesConstraint {
359-
sup: annotation.representative,
335+
sup: annotation.representative.rvid(),
360336
sub: fr_static,
361337
category: ConstraintCategory::IllegalUniverse,
362338
locations: Locations::All(rustc_span::DUMMY_SP),

compiler/rustc_borrowck/src/region_infer/mod.rs

+43-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::rc::Rc;
44
use rustc_data_structures::binary_search_util;
55
use rustc_data_structures::frozen::Frozen;
66
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
7-
use rustc_data_structures::graph::scc::Sccs;
7+
use rustc_data_structures::graph::scc::{self, Sccs};
88
use rustc_errors::Diag;
99
use rustc_hir::def_id::CRATE_DEF_ID;
1010
use rustc_index::IndexVec;
@@ -50,6 +50,47 @@ mod reverse_sccs;
5050

5151
pub(crate) mod values;
5252

53+
/// The representative region variable for an SCC, tagged by its origin.
54+
/// We prefer placeholders over existentially quantified variables, otherwise
55+
/// it's the one with the smallest Region Variable ID. In other words,
56+
/// the order of this enumeration really matters!
57+
#[derive(Copy, Debug, Clone, PartialEq, PartialOrd, Eq, Ord)]
58+
pub(crate) enum Representative {
59+
FreeRegion(RegionVid),
60+
Placeholder(RegionVid),
61+
Existential(RegionVid),
62+
}
63+
64+
impl Representative {
65+
pub(crate) fn rvid(&self) -> RegionVid {
66+
match self {
67+
Representative::FreeRegion(region_vid) => *region_vid,
68+
Representative::Placeholder(region_vid) => *region_vid,
69+
Representative::Existential(region_vid) => *region_vid,
70+
}
71+
}
72+
73+
pub(crate) fn new(r: RegionVid, definition: &RegionDefinition<'_>) -> Self {
74+
match definition.origin {
75+
NllRegionVariableOrigin::FreeRegion => Representative::FreeRegion(r),
76+
NllRegionVariableOrigin::Placeholder(_) => Representative::Placeholder(r),
77+
NllRegionVariableOrigin::Existential { .. } => Representative::Existential(r),
78+
}
79+
}
80+
}
81+
82+
impl scc::Annotation for Representative {
83+
fn merge_scc(self, other: Self) -> Self {
84+
// Just pick the smallest one. Note that we order by tag first!
85+
std::cmp::min(self, other)
86+
}
87+
88+
// For reachability, we do nothing since the representative doesn't change.
89+
fn merge_reached(self, _other: Self) -> Self {
90+
self
91+
}
92+
}
93+
5394
pub(crate) type ConstraintSccs = Sccs<RegionVid, ConstraintSccIndex>;
5495

5596
pub struct RegionInferenceContext<'tcx> {
@@ -2086,7 +2127,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
20862127
/// they *must* be equal (though not having the same repr does not
20872128
/// mean they are unequal).
20882129
fn scc_representative(&self, scc: ConstraintSccIndex) -> RegionVid {
2089-
self.scc_annotations[scc].representative
2130+
self.scc_annotations[scc].representative.rvid()
20902131
}
20912132

20922133
pub(crate) fn liveness_constraints(&self) -> &LivenessValues {

0 commit comments

Comments
 (0)