Skip to content

Commit 4f384a3

Browse files
committed
Better documentation for min max universe
1 parent 5168732 commit 4f384a3

File tree

4 files changed

+41
-35
lines changed

4 files changed

+41
-35
lines changed

compiler/rustc_borrowck/src/eliminate_placeholders.rs

+32-21
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,11 @@ impl PlaceholderReachability {
125125
/// the values of its elements. This annotates a single SCC.
126126
#[derive(Copy, Debug, Clone)]
127127
pub(crate) struct RegionTracker {
128-
/// The smallest universe reachable (and its region)
129-
min_universe: (UniverseIndex, RegionVid),
128+
/// The smallest maximum universe reachable (and its region).
129+
/// This determines the largest nameable universe from this
130+
/// SCC. Earlier regions in the constraint graph are
131+
/// preferred.
132+
min_max_universe_reached: (UniverseIndex, RegionVid),
130133

131134
/// Metadata about reachable placeholders
132135
reachable_placeholders: PlaceholderReachability,
@@ -149,27 +152,32 @@ impl RegionTracker {
149152
};
150153

151154
Self {
152-
min_universe: (definition.universe, rvid),
155+
// The largest reachable universe from a rvid is its
156+
// declared largest reachable one.
157+
min_max_universe_reached: (definition.universe, rvid),
153158
reachable_placeholders,
154159
representative: Representative::new(rvid, definition),
155160
}
156161
}
157162

158-
/// The smallest-indexed universe reachable from and/or in this SCC.
159-
pub(crate) fn min_universe(self) -> UniverseIndex {
160-
self.min_universe.0
163+
/// The largest universe that can be named from this SCC is the
164+
/// smallest largest nameable universe of anything it reaches in
165+
/// the region constraint graph, or equivalently in logic terms:
166+
/// `max_u(scc) = min(max_u(r) for r in scc: r )`.
167+
pub(crate) fn max_nameable_universe(self) -> UniverseIndex {
168+
self.min_max_universe_reached.0
161169
}
162170

163171
/// Determine if the tracked universes of the two SCCs
164172
/// are compatible.
165173
pub(crate) fn universe_compatible_with(&self, other: Self) -> bool {
166-
self.min_universe().can_name(other.min_universe())
167-
|| other.reachable_placeholders.can_be_named_by(self.min_universe())
174+
self.max_nameable_universe().can_name(other.max_nameable_universe())
175+
|| other.reachable_placeholders.can_be_named_by(self.max_nameable_universe())
168176
}
169177

170178
/// If this SCC reaches an universe that's too large, return it.
171179
fn reaches_too_large_universe(&self) -> Option<(RegionVid, UniverseIndex)> {
172-
let min_u = self.min_universe();
180+
let min_u = self.max_nameable_universe();
173181

174182
let PlaceholderReachability::Placeholders { max_universe: (max_u, max_u_rvid), .. } =
175183
self.reachable_placeholders
@@ -185,28 +193,31 @@ impl RegionTracker {
185193
}
186194
}
187195

196+
/// Pick the smallest universe index out of two, preferring
197+
/// the first argument if they are equal.
198+
#[inline(always)]
199+
fn pick_min_max_universe(a: RegionTracker, b: RegionTracker) -> (UniverseIndex, RegionVid) {
200+
std::cmp::min_by_key(
201+
a.min_max_universe_reached,
202+
b.min_max_universe_reached,
203+
|x: &(UniverseIndex, RegionVid)| x.0,
204+
)
205+
}
206+
188207
impl scc::Annotation for RegionTracker {
189208
fn merge_scc(self, other: Self) -> Self {
190209
trace!("{:?} << {:?}", self.representative, other.representative);
191210

192211
Self {
193212
reachable_placeholders: self.reachable_placeholders.merge(other.reachable_placeholders),
194-
min_universe: std::cmp::min_by_key(
195-
self.min_universe,
196-
other.min_universe,
197-
|x: &(UniverseIndex, RegionVid)| x.0,
198-
),
213+
min_max_universe_reached: pick_min_max_universe(self, other),
199214
representative: self.representative.merge_scc(other.representative),
200215
}
201216
}
202217

203218
fn merge_reached(mut self, other: Self) -> Self {
204219
let already_has_placeholder_violation = self.reaches_too_large_universe().is_some();
205-
self.min_universe = std::cmp::min_by_key(
206-
self.min_universe,
207-
other.min_universe,
208-
|x: &(UniverseIndex, RegionVid)| x.0,
209-
);
220+
self.min_max_universe_reached = pick_min_max_universe(self, other);
210221
// This detail is subtle. We stop early here, because there may be multiple
211222
// illegally reached regions, but they are not equally good as blame candidates.
212223
// In general, the ones with the smallest indices of their RegionVids will
@@ -421,15 +432,15 @@ fn rewrite_outlives<'tcx>(
421432
continue;
422433
};
423434

424-
let min_u = annotation.min_universe();
435+
let min_u = annotation.max_nameable_universe();
425436

426437
debug!(
427438
"Universe {max_u:?} is too large for its SCC, represented by {:?}",
428439
annotation.representative
429440
);
430441
let blame_to = if annotation.representative.rvid() == max_u_rvid {
431442
// We originally had a large enough universe to fit all our reachable
432-
// placeholders, but had it lowered because we also absorbed something
443+
// placeholders, but had it lowered because we also reached something
433444
// small-universed. In this case, that's to blame!
434445
let small_universed_rvid = find_region(
435446
outlives_constraints,

compiler/rustc_borrowck/src/region_infer/dump_mir.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
4646
"| {r:rw$?} | {ui:4?} | {v}",
4747
r = region,
4848
rw = REGION_WIDTH,
49-
ui = self.region_universe(region),
49+
ui = self.max_nameable_universe(self.constraint_sccs.scc(region)),
5050
v = self.region_value_str(region),
5151
)?;
5252
}

compiler/rustc_borrowck/src/region_infer/mod.rs

+7-12
Original file line numberDiff line numberDiff line change
@@ -551,11 +551,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
551551
self.scc_values.placeholders_contained_in(scc)
552552
}
553553

554-
/// Returns access to the value of `r` for debugging purposes.
555-
pub(crate) fn region_universe(&self, r: RegionVid) -> ty::UniverseIndex {
556-
self.scc_universe(self.constraint_sccs.scc(r))
557-
}
558-
559554
/// Once region solving has completed, this function will return the member constraints that
560555
/// were applied to the value of a given SCC `scc`. See `AppliedMemberConstraint`.
561556
pub(crate) fn applied_member_constraints(
@@ -722,7 +717,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
722717

723718
// If the member region lives in a higher universe, we currently choose
724719
// the most conservative option by leaving it unchanged.
725-
if !self.scc_universe(scc).is_root() {
720+
if !self.max_nameable_universe(scc).is_root() {
726721
return;
727722
}
728723

@@ -902,7 +897,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
902897
"lower_bound = {:?} r_scc={:?} universe={:?}",
903898
lower_bound,
904899
r_scc,
905-
self.scc_universe(r_scc)
900+
self.max_nameable_universe(r_scc)
906901
);
907902
// If the type test requires that `T: 'a` where `'a` is a
908903
// placeholder from another universe, that effectively requires
@@ -1380,10 +1375,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
13801375
}
13811376
}
13821377

1383-
/// The minimum universe of any variable reachable from this
1378+
/// The minimum maximum universe of any variable reachable from this
13841379
/// SCC, inside or outside of it.
1385-
fn scc_universe(&self, scc: ConstraintSccIndex) -> UniverseIndex {
1386-
self.scc_annotations[scc].min_universe()
1380+
fn max_nameable_universe(&self, scc: ConstraintSccIndex) -> UniverseIndex {
1381+
self.scc_annotations[scc].max_nameable_universe()
13871382
}
13881383

13891384
/// Checks the final value for the free region `fr` to see if it
@@ -1405,7 +1400,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
14051400

14061401
// Because this free region must be in the ROOT universe, we
14071402
// know it cannot contain any bound universes.
1408-
assert!(self.scc_universe(longer_fr_scc).is_root());
1403+
assert!(self.max_nameable_universe(longer_fr_scc).is_root());
14091404

14101405
// Only check all of the relations for the main representative of each
14111406
// SCC, otherwise just check that we outlive said representative. This
@@ -1754,7 +1749,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
17541749
#[instrument(skip(self), level = "trace", ret)]
17551750
pub(crate) fn find_sub_region_live_at(&self, fr1: RegionVid, location: Location) -> RegionVid {
17561751
trace!(scc = ?self.constraint_sccs.scc(fr1));
1757-
trace!(universe = ?self.region_universe(fr1));
1752+
trace!(universe = ?self.max_nameable_universe(self.constraint_sccs.scc(fr1)));
17581753
self.constraint_path_to(fr1, |r| {
17591754
// Look for some `r` such that `fr1: r` and `r` is live at `location`
17601755
trace!(?r, liveness_constraints=?self.liveness_constraints.pretty_print_live_points(r));

compiler/rustc_borrowck/src/region_infer/opaque_types.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
191191
let scc = self.constraint_sccs.scc(vid);
192192

193193
// Special handling of higher-ranked regions.
194-
if !self.scc_universe(scc).is_root() {
194+
if !self.max_nameable_universe(scc).is_root() {
195195
match self.scc_values.placeholders_contained_in(scc).enumerate().last() {
196196
// If the region contains a single placeholder then they're equal.
197197
Some((0, placeholder)) => {

0 commit comments

Comments
 (0)