Skip to content

Commit 6e88db9

Browse files
committed
finish filling polonius context
transpose liveness matrix and record live regions at the end of MIR typeck
1 parent cbdac2f commit 6e88db9

File tree

4 files changed

+40
-8
lines changed

4 files changed

+40
-8
lines changed

compiler/rustc_borrowck/src/polonius/liveness_constraints.rs

+22
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
use std::collections::BTreeMap;
22

3+
use rustc_index::bit_set::SparseBitMatrix;
4+
use rustc_index::interval::SparseIntervalMatrix;
35
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
46
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeVisitable};
7+
use rustc_mir_dataflow::points::PointIndex;
58

69
use super::{ConstraintDirection, PoloniusContext};
710
use crate::universal_regions::UniversalRegions;
@@ -22,6 +25,25 @@ impl PoloniusContext {
2225
};
2326
extractor.relate(value, value).expect("Can't have a type error relating to itself");
2427
}
28+
29+
/// Unlike NLLs, in polonius we traverse the cfg to look for regions live across an edge, so we
30+
/// need to transpose the "points where each region is live" matrix to a "live regions per point"
31+
/// matrix.
32+
// FIXME: avoid this conversion by always storing liveness data in this shape in the rest of
33+
// borrowck.
34+
pub(crate) fn record_live_regions_per_point(
35+
&mut self,
36+
num_regions: usize,
37+
points_per_live_region: &SparseIntervalMatrix<RegionVid, PointIndex>,
38+
) {
39+
let mut live_regions_per_point = SparseBitMatrix::new(num_regions);
40+
for region in points_per_live_region.rows() {
41+
for point in points_per_live_region.row(region).unwrap().iter() {
42+
live_regions_per_point.insert(point, region);
43+
}
44+
}
45+
self.live_regions = Some(live_regions_per_point);
46+
}
2547
}
2648

2749
/// Extracts variances for regions contained within types. Follows the same structure as

compiler/rustc_borrowck/src/polonius/mod.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ use crate::universal_regions::UniversalRegions;
5757
pub(crate) struct PoloniusContext {
5858
/// The set of regions that are live at a given point in the CFG, used to create localized
5959
/// outlives constraints between regions that are live at connected points in the CFG.
60-
live_regions: SparseBitMatrix<PointIndex, RegionVid>,
60+
live_regions: Option<SparseBitMatrix<PointIndex, RegionVid>>,
6161

6262
/// The expected edge direction per live region: the kind of directed edge we'll create as
6363
/// liveness constraints depends on the variance of types with respect to each contained region.
@@ -79,11 +79,8 @@ enum ConstraintDirection {
7979
}
8080

8181
impl PoloniusContext {
82-
pub(crate) fn new(num_regions: usize) -> PoloniusContext {
83-
Self {
84-
live_region_variances: BTreeMap::new(),
85-
live_regions: SparseBitMatrix::new(num_regions),
86-
}
82+
pub(crate) fn new() -> PoloniusContext {
83+
Self { live_region_variances: BTreeMap::new(), live_regions: None }
8784
}
8885

8986
/// Creates a constraint set for `-Zpolonius=next` by:

compiler/rustc_borrowck/src/region_infer/values.rs

+8
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,14 @@ impl LivenessValues {
9999
}
100100
}
101101

102+
/// Returns the liveness matrix of points where each region is live. Panics if the liveness
103+
/// values have been created without any per-point data (that is, for promoteds).
104+
pub(crate) fn points(&self) -> &SparseIntervalMatrix<RegionVid, PointIndex> {
105+
self.points
106+
.as_ref()
107+
.expect("this `LivenessValues` wasn't created using `with_specific_points`")
108+
}
109+
102110
/// Iterate through each region that has a value in this set.
103111
pub(crate) fn regions(&self) -> impl Iterator<Item = RegionVid> + '_ {
104112
self.points.as_ref().expect("use with_specific_points").rows()

compiler/rustc_borrowck/src/type_check/mod.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,7 @@ pub(crate) fn type_check<'a, 'tcx>(
150150
debug!(?normalized_inputs_and_output);
151151

152152
let mut polonius_context = if infcx.tcx.sess.opts.unstable_opts.polonius.is_next_enabled() {
153-
let num_regions = infcx.num_region_vars();
154-
Some(PoloniusContext::new(num_regions))
153+
Some(PoloniusContext::new())
155154
} else {
156155
None
157156
};
@@ -187,6 +186,12 @@ pub(crate) fn type_check<'a, 'tcx>(
187186
let opaque_type_values =
188187
opaque_types::take_opaques_and_register_member_constraints(&mut typeck);
189188

189+
if let Some(polonius_context) = typeck.polonius_context.as_mut() {
190+
let num_regions = infcx.num_region_vars();
191+
let points_per_live_region = typeck.constraints.liveness_constraints.points();
192+
polonius_context.record_live_regions_per_point(num_regions, points_per_live_region);
193+
}
194+
190195
MirTypeckResults {
191196
constraints,
192197
universal_region_relations,

0 commit comments

Comments
 (0)