Skip to content

Commit 274b524

Browse files
committed
Auto merge of #117880 - lqd:liveness-values, r=cjgillot
Refactor borrowck liveness values This PR starts cleaning up `rustc_borrowck`, in particular around liveness values: - refactors simple names that make no sense anymore: either referring to older structures using region elements, or to bitset containers and values. - improves comments and fixes others - removes unused return values and unneeded generic arguments r? `@matthewjasper`
2 parents 9529a5d + d203476 commit 274b524

File tree

6 files changed

+67
-62
lines changed

6 files changed

+67
-62
lines changed

Diff for: compiler/rustc_borrowck/src/constraint_generation.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_middle::mir::{
99
};
1010
use rustc_middle::ty::visit::TypeVisitable;
1111
use rustc_middle::ty::GenericArgsRef;
12-
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt};
12+
use rustc_middle::ty::{self, Ty, TyCtxt};
1313

1414
use crate::{
1515
borrow_set::BorrowSet, facts::AllFacts, location::LocationTable, places_conflict,
@@ -18,7 +18,7 @@ use crate::{
1818

1919
pub(super) fn generate_constraints<'tcx>(
2020
infcx: &InferCtxt<'tcx>,
21-
liveness_constraints: &mut LivenessValues<RegionVid>,
21+
liveness_constraints: &mut LivenessValues,
2222
all_facts: &mut Option<AllFacts>,
2323
location_table: &LocationTable,
2424
body: &Body<'tcx>,
@@ -43,7 +43,7 @@ struct ConstraintGeneration<'cg, 'tcx> {
4343
infcx: &'cg InferCtxt<'tcx>,
4444
all_facts: &'cg mut Option<AllFacts>,
4545
location_table: &'cg LocationTable,
46-
liveness_constraints: &'cg mut LivenessValues<RegionVid>,
46+
liveness_constraints: &'cg mut LivenessValues,
4747
borrow_set: &'cg BorrowSet<'tcx>,
4848
body: &'cg Body<'tcx>,
4949
}
@@ -167,7 +167,7 @@ impl<'cx, 'tcx> ConstraintGeneration<'cx, 'tcx> {
167167

168168
self.infcx.tcx.for_each_free_region(&live_ty, |live_region| {
169169
let vid = live_region.as_var();
170-
self.liveness_constraints.add_element(vid, location);
170+
self.liveness_constraints.add_location(vid, location);
171171
});
172172
}
173173

Diff for: compiler/rustc_borrowck/src/region_infer/dump_mir.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
6767
with_msg: &mut dyn FnMut(&str) -> io::Result<()>,
6868
) -> io::Result<()> {
6969
for region in self.definitions.indices() {
70-
let value = self.liveness_constraints.region_value_str(region);
70+
let value = self.liveness_constraints.pretty_print_live_points(region);
7171
if value != "{}" {
7272
with_msg(&format!("{region:?} live at {value}"))?;
7373
}

Diff for: compiler/rustc_borrowck/src/region_infer/mod.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ pub struct RegionInferenceContext<'tcx> {
5959
/// regions, these start out empty and steadily grow, though for
6060
/// each universally quantified region R they start out containing
6161
/// the entire CFG and `end(R)`.
62-
liveness_constraints: LivenessValues<RegionVid>,
62+
liveness_constraints: LivenessValues,
6363

6464
/// The outlives constraints computed by the type-check.
6565
constraints: Frozen<OutlivesConstraintSet<'tcx>>,
@@ -333,7 +333,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
333333
member_constraints_in: MemberConstraintSet<'tcx, RegionVid>,
334334
universe_causes: FxIndexMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
335335
type_tests: Vec<TypeTest<'tcx>>,
336-
liveness_constraints: LivenessValues<RegionVid>,
336+
liveness_constraints: LivenessValues,
337337
elements: &Rc<RegionValueElements>,
338338
live_loans: SparseBitMatrix<PointIndex, BorrowIndex>,
339339
) -> Self {
@@ -360,7 +360,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
360360
let mut scc_values =
361361
RegionValues::new(elements, universal_regions.len(), &placeholder_indices);
362362

363-
for region in liveness_constraints.rows() {
363+
for region in liveness_constraints.regions() {
364364
let scc = constraint_sccs.scc(region);
365365
scc_values.merge_liveness(scc, region, &liveness_constraints);
366366
}
@@ -1972,15 +1972,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
19721972
None
19731973
}
19741974

1975-
/// Finds some region R such that `fr1: R` and `R` is live at `elem`.
1975+
/// Finds some region R such that `fr1: R` and `R` is live at `location`.
19761976
#[instrument(skip(self), level = "trace", ret)]
1977-
pub(crate) fn find_sub_region_live_at(&self, fr1: RegionVid, elem: Location) -> RegionVid {
1977+
pub(crate) fn find_sub_region_live_at(&self, fr1: RegionVid, location: Location) -> RegionVid {
19781978
trace!(scc = ?self.constraint_sccs.scc(fr1));
19791979
trace!(universe = ?self.scc_universes[self.constraint_sccs.scc(fr1)]);
19801980
self.find_constraint_paths_between_regions(fr1, |r| {
1981-
// First look for some `r` such that `fr1: r` and `r` is live at `elem`
1982-
trace!(?r, liveness_constraints=?self.liveness_constraints.region_value_str(r));
1983-
self.liveness_constraints.contains(r, elem)
1981+
// First look for some `r` such that `fr1: r` and `r` is live at `location`
1982+
trace!(?r, liveness_constraints=?self.liveness_constraints.pretty_print_live_points(r));
1983+
self.liveness_constraints.is_live_at(r, location)
19841984
})
19851985
.or_else(|| {
19861986
// If we fail to find that, we may find some `r` such that

Diff for: compiler/rustc_borrowck/src/region_infer/values.rs

+45-40
Original file line numberDiff line numberDiff line change
@@ -117,65 +117,68 @@ pub(crate) enum RegionElement {
117117
PlaceholderRegion(ty::PlaceholderRegion),
118118
}
119119

120-
/// When we initially compute liveness, we use an interval matrix storing
121-
/// liveness ranges for each region-vid.
122-
pub(crate) struct LivenessValues<N: Idx> {
120+
/// Records the CFG locations where each region is live. When we initially compute liveness, we use
121+
/// an interval matrix storing liveness ranges for each region-vid.
122+
pub(crate) struct LivenessValues {
123123
elements: Rc<RegionValueElements>,
124-
points: SparseIntervalMatrix<N, PointIndex>,
124+
points: SparseIntervalMatrix<RegionVid, PointIndex>,
125125
}
126126

127-
impl<N: Idx> LivenessValues<N> {
128-
/// Creates a new set of "region values" that tracks causal information.
129-
/// Each of the regions in num_region_variables will be initialized with an
130-
/// empty set of points and no causal information.
127+
impl LivenessValues {
128+
/// Create an empty map of regions to locations where they're live.
131129
pub(crate) fn new(elements: Rc<RegionValueElements>) -> Self {
132130
Self { points: SparseIntervalMatrix::new(elements.num_points), elements }
133131
}
134132

135133
/// Iterate through each region that has a value in this set.
136-
pub(crate) fn rows(&self) -> impl Iterator<Item = N> {
134+
pub(crate) fn regions(&self) -> impl Iterator<Item = RegionVid> {
137135
self.points.rows()
138136
}
139137

140-
/// Adds the given element to the value for the given region. Returns whether
141-
/// the element is newly added (i.e., was not already present).
142-
pub(crate) fn add_element(&mut self, row: N, location: Location) -> bool {
143-
debug!("LivenessValues::add(r={:?}, location={:?})", row, location);
144-
let index = self.elements.point_from_location(location);
145-
self.points.insert(row, index)
138+
/// Records `region` as being live at the given `location`.
139+
pub(crate) fn add_location(&mut self, region: RegionVid, location: Location) {
140+
debug!("LivenessValues::add_location(region={:?}, location={:?})", region, location);
141+
let point = self.elements.point_from_location(location);
142+
self.points.insert(region, point);
146143
}
147144

148-
/// Adds all the elements in the given bit array into the given
149-
/// region. Returns whether any of them are newly added.
150-
pub(crate) fn add_elements(&mut self, row: N, locations: &IntervalSet<PointIndex>) -> bool {
151-
debug!("LivenessValues::add_elements(row={:?}, locations={:?})", row, locations);
152-
self.points.union_row(row, locations)
145+
/// Records `region` as being live at all the given `points`.
146+
pub(crate) fn add_points(&mut self, region: RegionVid, points: &IntervalSet<PointIndex>) {
147+
debug!("LivenessValues::add_points(region={:?}, points={:?})", region, points);
148+
self.points.union_row(region, points);
153149
}
154150

155-
/// Adds all the control-flow points to the values for `r`.
156-
pub(crate) fn add_all_points(&mut self, row: N) {
157-
self.points.insert_all_into_row(row);
151+
/// Records `region` as being live at all the control-flow points.
152+
pub(crate) fn add_all_points(&mut self, region: RegionVid) {
153+
self.points.insert_all_into_row(region);
158154
}
159155

160-
/// Returns `true` if the region `r` contains the given element.
161-
pub(crate) fn contains(&self, row: N, location: Location) -> bool {
162-
let index = self.elements.point_from_location(location);
163-
self.points.row(row).is_some_and(|r| r.contains(index))
156+
/// Returns whether `region` is marked live at the given `location`.
157+
pub(crate) fn is_live_at(&self, region: RegionVid, location: Location) -> bool {
158+
let point = self.elements.point_from_location(location);
159+
self.points.row(region).is_some_and(|r| r.contains(point))
160+
}
161+
162+
/// Returns whether `region` is marked live at any location.
163+
pub(crate) fn is_live_anywhere(&self, region: RegionVid) -> bool {
164+
self.live_points(region).next().is_some()
164165
}
165166

166-
/// Returns an iterator of all the elements contained by the region `r`
167-
pub(crate) fn get_elements(&self, row: N) -> impl Iterator<Item = Location> + '_ {
167+
/// Returns an iterator of all the points where `region` is live.
168+
fn live_points(&self, region: RegionVid) -> impl Iterator<Item = PointIndex> + '_ {
168169
self.points
169-
.row(row)
170+
.row(region)
170171
.into_iter()
171172
.flat_map(|set| set.iter())
172-
.take_while(move |&p| self.elements.point_in_range(p))
173-
.map(move |p| self.elements.to_location(p))
173+
.take_while(|&p| self.elements.point_in_range(p))
174174
}
175175

176-
/// Returns a "pretty" string value of the region. Meant for debugging.
177-
pub(crate) fn region_value_str(&self, r: N) -> String {
178-
region_value_str(self.get_elements(r).map(RegionElement::Location))
176+
/// For debugging purposes, returns a pretty-printed string of the points where the `region` is
177+
/// live.
178+
pub(crate) fn pretty_print_live_points(&self, region: RegionVid) -> String {
179+
pretty_print_region_elements(
180+
self.live_points(region).map(|p| RegionElement::Location(self.elements.to_location(p))),
181+
)
179182
}
180183

181184
#[inline]
@@ -308,7 +311,7 @@ impl<N: Idx> RegionValues<N> {
308311
/// `self[to] |= values[from]`, essentially: that is, take all the
309312
/// elements for the region `from` from `values` and add them to
310313
/// the region `to` in `self`.
311-
pub(crate) fn merge_liveness<M: Idx>(&mut self, to: N, from: M, values: &LivenessValues<M>) {
314+
pub(crate) fn merge_liveness(&mut self, to: N, from: RegionVid, values: &LivenessValues) {
312315
if let Some(set) = values.points.row(from) {
313316
self.points.union_row(to, set);
314317
}
@@ -377,7 +380,7 @@ impl<N: Idx> RegionValues<N> {
377380

378381
/// Returns a "pretty" string value of the region. Meant for debugging.
379382
pub(crate) fn region_value_str(&self, r: N) -> String {
380-
region_value_str(self.elements_contained_in(r))
383+
pretty_print_region_elements(self.elements_contained_in(r))
381384
}
382385
}
383386

@@ -421,11 +424,12 @@ impl ToElementIndex for ty::PlaceholderRegion {
421424
}
422425
}
423426

424-
pub(crate) fn location_set_str(
427+
/// For debugging purposes, returns a pretty-printed string of the given points.
428+
pub(crate) fn pretty_print_points(
425429
elements: &RegionValueElements,
426430
points: impl IntoIterator<Item = PointIndex>,
427431
) -> String {
428-
region_value_str(
432+
pretty_print_region_elements(
429433
points
430434
.into_iter()
431435
.take_while(|&p| elements.point_in_range(p))
@@ -434,7 +438,8 @@ pub(crate) fn location_set_str(
434438
)
435439
}
436440

437-
fn region_value_str(elements: impl IntoIterator<Item = RegionElement>) -> String {
441+
/// For debugging purposes, returns a pretty-printed string of the given region elements.
442+
fn pretty_print_region_elements(elements: impl IntoIterator<Item = RegionElement>) -> String {
438443
let mut result = String::new();
439444
result.push('{');
440445

Diff for: compiler/rustc_borrowck/src/type_check/liveness/trace.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
550550
dropped_local,
551551
dropped_ty,
552552
drop_locations,
553-
values::location_set_str(self.elements, live_at.iter()),
553+
values::pretty_print_points(self.elements, live_at.iter()),
554554
);
555555

556556
let drop_data = self.drop_data.entry(dropped_ty).or_insert_with({
@@ -599,7 +599,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
599599
debug!("make_all_regions_live(value={:?})", value);
600600
debug!(
601601
"make_all_regions_live: live_at={}",
602-
values::location_set_str(elements, live_at.iter()),
602+
values::pretty_print_points(elements, live_at.iter()),
603603
);
604604

605605
// When using `-Zpolonius=next`, we want to record the loans that flow into this value's
@@ -618,7 +618,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
618618
.borrowck_context
619619
.constraints
620620
.liveness_constraints
621-
.add_elements(live_region_vid, live_at);
621+
.add_points(live_region_vid, live_at);
622622

623623
// There can only be inflowing loans for this region when we are using
624624
// `-Zpolonius=next`.

Diff for: compiler/rustc_borrowck/src/type_check/mod.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
318318
.borrowck_context
319319
.constraints
320320
.liveness_constraints
321-
.add_element(live_region_vid, location);
321+
.add_location(live_region_vid, location);
322322
});
323323

324324
// HACK(compiler-errors): Constants that are gathered into Body.required_consts
@@ -592,16 +592,16 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
592592
}
593593
self.cx.borrowck_context.constraints.outlives_constraints.push(constraint)
594594
}
595-
for region in liveness_constraints.rows() {
595+
for region in liveness_constraints.regions() {
596596
// If the region is live at at least one location in the promoted MIR,
597597
// then add a liveness constraint to the main MIR for this region
598598
// at the location provided as an argument to this method
599-
if liveness_constraints.get_elements(region).next().is_some() {
599+
if liveness_constraints.is_live_anywhere(region) {
600600
self.cx
601601
.borrowck_context
602602
.constraints
603603
.liveness_constraints
604-
.add_element(region, location);
604+
.add_location(region, location);
605605
}
606606
}
607607
}
@@ -899,7 +899,7 @@ pub(crate) struct MirTypeckRegionConstraints<'tcx> {
899899
/// not otherwise appear in the MIR -- in particular, the
900900
/// late-bound regions that it instantiates at call-sites -- and
901901
/// hence it must report on their liveness constraints.
902-
pub(crate) liveness_constraints: LivenessValues<RegionVid>,
902+
pub(crate) liveness_constraints: LivenessValues,
903903

904904
pub(crate) outlives_constraints: OutlivesConstraintSet<'tcx>,
905905

@@ -1443,7 +1443,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
14431443
self.borrowck_context
14441444
.constraints
14451445
.liveness_constraints
1446-
.add_element(region_vid, term_location);
1446+
.add_location(region_vid, term_location);
14471447
}
14481448

14491449
self.check_call_inputs(body, term, func, &sig, args, term_location, *call_source);

0 commit comments

Comments
 (0)