Skip to content

Commit 8b94d16

Browse files
davidtwconikomatsakis
authored andcommittedJul 17, 2018
Generate region values directly to reduce memory usage.
Also modify `SparseBitMatrix` so that it does not require knowing the dimensions in advance, but instead grows on demand.
1 parent bce32b5 commit 8b94d16

File tree

9 files changed

+174
-121
lines changed

9 files changed

+174
-121
lines changed
 

‎src/librustc_data_structures/bitvec.rs

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -281,10 +281,10 @@ where
281281
}
282282

283283
impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
284-
/// Create a new `rows x columns` matrix, initially empty.
285-
pub fn new(rows: R, _columns: C) -> SparseBitMatrix<R, C> {
286-
SparseBitMatrix {
287-
vector: IndexVec::from_elem_n(SparseBitSet::new(), rows.index()),
284+
/// Create a new empty sparse bit matrix with no rows or columns.
285+
pub fn new() -> Self {
286+
Self {
287+
vector: IndexVec::new(),
288288
}
289289
}
290290

@@ -293,6 +293,14 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
293293
///
294294
/// Returns true if this changed the matrix, and false otherwise.
295295
pub fn add(&mut self, row: R, column: C) -> bool {
296+
debug!(
297+
"add(row={:?}, column={:?}, current_len={})",
298+
row,
299+
column,
300+
self.vector.len()
301+
);
302+
self.vector
303+
.ensure_contains_elem(row, || SparseBitSet::new());
296304
self.vector[row].insert(column)
297305
}
298306

@@ -301,7 +309,7 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
301309
/// if the matrix represents (transitive) reachability, can
302310
/// `row` reach `column`?
303311
pub fn contains(&self, row: R, column: C) -> bool {
304-
self.vector[row].contains(column)
312+
self.vector.get(row).map_or(false, |r| r.contains(column))
305313
}
306314

307315
/// Add the bits from row `read` to the bits from row `write`,
@@ -315,16 +323,27 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
315323
let mut changed = false;
316324

317325
if read != write {
318-
let (bit_set_read, bit_set_write) = self.vector.pick2_mut(read, write);
326+
if self.vector.get(read).is_some() {
327+
self.vector
328+
.ensure_contains_elem(write, || SparseBitSet::new());
329+
let (bit_set_read, bit_set_write) = self.vector.pick2_mut(read, write);
319330

320-
for read_chunk in bit_set_read.chunks() {
321-
changed = changed | bit_set_write.insert_chunk(read_chunk).any();
331+
for read_chunk in bit_set_read.chunks() {
332+
changed = changed | bit_set_write.insert_chunk(read_chunk).any();
333+
}
322334
}
323335
}
324336

325337
changed
326338
}
327339

340+
/// Merge a row, `from`, into the `into` row.
341+
pub fn merge_into(&mut self, into: R, from: &SparseBitSet<C>) -> bool {
342+
self.vector
343+
.ensure_contains_elem(into, || SparseBitSet::new());
344+
self.vector[into].insert_from(from)
345+
}
346+
328347
/// True if `sub` is a subset of `sup`
329348
pub fn is_subset(&self, sub: R, sup: R) -> bool {
330349
sub == sup || {
@@ -336,10 +355,20 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
336355
}
337356
}
338357

358+
/// Number of elements in the matrix.
359+
pub fn len(&self) -> usize {
360+
self.vector.len()
361+
}
362+
339363
/// Iterates through all the columns set to true in a given row of
340364
/// the matrix.
341365
pub fn iter<'a>(&'a self, row: R) -> impl Iterator<Item = C> + 'a {
342-
self.vector[row].iter()
366+
self.vector.get(row).into_iter().flat_map(|r| r.iter())
367+
}
368+
369+
/// Iterates through each row and the accompanying bit set.
370+
pub fn iter_enumerated<'a>(&'a self) -> impl Iterator<Item = (R, &'a SparseBitSet<C>)> + 'a {
371+
self.vector.iter_enumerated()
343372
}
344373
}
345374

@@ -445,6 +474,15 @@ impl<I: Idx> SparseBitSet<I> {
445474
}
446475
}
447476

477+
/// Insert into bit set from another bit set.
478+
pub fn insert_from(&mut self, from: &SparseBitSet<I>) -> bool {
479+
let mut changed = false;
480+
for read_chunk in from.chunks() {
481+
changed = changed | self.insert_chunk(read_chunk).any();
482+
}
483+
changed
484+
}
485+
448486
pub fn remove_chunk(&mut self, chunk: SparseChunk<I>) -> SparseChunk<I> {
449487
if chunk.bits == 0 {
450488
return chunk;

‎src/librustc_data_structures/indexed_vec.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,10 +518,28 @@ impl<I: Idx, T> IndexVec<I, T> {
518518
}
519519

520520
impl<I: Idx, T: Clone> IndexVec<I, T> {
521+
/// Grows the index vector so that it contains an entry for
522+
/// `elem`; if that is already true, then has no
523+
/// effect. Otherwise, inserts new values as needed by invoking
524+
/// `fill_value`.
525+
#[inline]
526+
pub fn ensure_contains_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) {
527+
let min_new_len = elem.index() + 1;
528+
if self.len() < min_new_len {
529+
self.raw.resize_with(min_new_len, fill_value);
530+
}
531+
}
532+
521533
#[inline]
522534
pub fn resize(&mut self, new_len: usize, value: T) {
523535
self.raw.resize(new_len, value)
524536
}
537+
538+
#[inline]
539+
pub fn resize_to_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) {
540+
let min_new_len = elem.index() + 1;
541+
self.raw.resize_with(min_new_len, fill_value);
542+
}
525543
}
526544

527545
impl<I: Idx, T: Ord> IndexVec<I, T> {

‎src/librustc_data_structures/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#![feature(optin_builtin_traits)]
3131
#![feature(macro_vis_matcher)]
3232
#![feature(allow_internal_unstable)]
33+
#![feature(vec_resize_with)]
3334

3435
#![cfg_attr(unix, feature(libc))]
3536
#![cfg_attr(test, feature(test))]

‎src/librustc_mir/borrow_check/nll/constraint_generation.rs

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ use rustc::mir::{Local, Statement, Terminator};
2121
use rustc::ty::fold::TypeFoldable;
2222
use rustc::ty::subst::Substs;
2323
use rustc::ty::{self, CanonicalTy, ClosureSubsts, GeneratorSubsts};
24-
use std::iter;
2524

2625
pub(super) fn generate_constraints<'cx, 'gcx, 'tcx>(
2726
infcx: &InferCtxt<'cx, 'gcx, 'tcx>,
@@ -30,7 +29,6 @@ pub(super) fn generate_constraints<'cx, 'gcx, 'tcx>(
3029
location_table: &LocationTable,
3130
mir: &Mir<'tcx>,
3231
borrow_set: &BorrowSet<'tcx>,
33-
liveness_set_from_typeck: &[(ty::Region<'tcx>, Location)],
3432
) {
3533
let mut cg = ConstraintGeneration {
3634
borrow_set,
@@ -40,8 +38,6 @@ pub(super) fn generate_constraints<'cx, 'gcx, 'tcx>(
4038
all_facts,
4139
};
4240

43-
cg.add_region_liveness_constraints_from_type_check(liveness_set_from_typeck);
44-
4541
for (bb, data) in mir.basic_blocks().iter_enumerated() {
4642
cg.visit_basic_block_data(bb, data);
4743
}
@@ -189,42 +185,6 @@ impl<'cg, 'cx, 'gcx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'gcx
189185
}
190186

191187
impl<'cx, 'cg, 'gcx, 'tcx> ConstraintGeneration<'cx, 'cg, 'gcx, 'tcx> {
192-
/// The MIR type checker generates region liveness constraints
193-
/// that we also have to respect.
194-
fn add_region_liveness_constraints_from_type_check(
195-
&mut self,
196-
liveness_set: &[(ty::Region<'tcx>, Location)],
197-
) {
198-
debug!(
199-
"add_region_liveness_constraints_from_type_check(liveness_set={} items)",
200-
liveness_set.len(),
201-
);
202-
203-
let ConstraintGeneration {
204-
regioncx,
205-
location_table,
206-
all_facts,
207-
..
208-
} = self;
209-
210-
for (region, location) in liveness_set {
211-
debug!("generate: {:#?} is live at {:#?}", region, location);
212-
let region_vid = regioncx.to_region_vid(region);
213-
regioncx.add_live_element(region_vid, *location);
214-
}
215-
216-
if let Some(all_facts) = all_facts {
217-
all_facts
218-
.region_live_at
219-
.extend(liveness_set.into_iter().flat_map(|(region, location)| {
220-
let r = regioncx.to_region_vid(region);
221-
let p1 = location_table.start_index(*location);
222-
let p2 = location_table.mid_index(*location);
223-
iter::once((r, p1)).chain(iter::once((r, p2)))
224-
}));
225-
}
226-
}
227-
228188
/// Some variable with type `live_ty` is "regular live" at
229189
/// `location` -- i.e., it may be used later. This means that all
230190
/// regions appearing in the type `live_ty` must be live at

‎src/librustc_mir/borrow_check/nll/mod.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use borrow_check::borrow_set::BorrowSet;
1212
use borrow_check::location::{LocationIndex, LocationTable};
1313
use borrow_check::nll::facts::AllFactsExt;
1414
use borrow_check::nll::type_check::MirTypeckRegionConstraints;
15+
use borrow_check::nll::region_infer::values::RegionValueElements;
1516
use dataflow::indexes::BorrowIndex;
1617
use dataflow::move_paths::MoveData;
1718
use dataflow::FlowAtLocation;
@@ -99,6 +100,8 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
99100
None
100101
};
101102

103+
let elements = &Rc::new(RegionValueElements::new(mir, universal_regions.len()));
104+
102105
// Run the MIR type-checker.
103106
let liveness = &LivenessResults::compute(mir);
104107
let constraint_sets = type_check::type_check(
@@ -113,6 +116,7 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
113116
&mut all_facts,
114117
flow_inits,
115118
move_data,
119+
elements,
116120
);
117121

118122
if let Some(all_facts) = &mut all_facts {
@@ -126,7 +130,7 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
126130
// base constraints generated by the type-check.
127131
let var_origins = infcx.take_region_var_origins();
128132
let MirTypeckRegionConstraints {
129-
liveness_set,
133+
liveness_constraints,
130134
outlives_constraints,
131135
type_tests,
132136
} = constraint_sets;
@@ -136,6 +140,8 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
136140
mir,
137141
outlives_constraints,
138142
type_tests,
143+
liveness_constraints,
144+
elements,
139145
);
140146

141147
// Generate various additional constraints.
@@ -146,7 +152,6 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
146152
location_table,
147153
&mir,
148154
borrow_set,
149-
&liveness_set,
150155
);
151156
invalidation::generate_invalidates(
152157
infcx,

‎src/librustc_mir/borrow_check/nll/region_infer/mod.rs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ mod annotation;
3737
mod dump_mir;
3838
mod error_reporting;
3939
mod graphviz;
40-
mod values;
40+
pub mod values;
4141
use self::values::{RegionValueElements, RegionValues};
4242

4343
use super::ToRegionVid;
@@ -66,8 +66,8 @@ pub struct RegionInferenceContext<'tcx> {
6666
/// the SCC (see `constraint_sccs`) and for error reporting.
6767
constraint_graph: Rc<ConstraintGraph>,
6868

69-
/// The SCC computed from `constraints` and
70-
/// `constraint_graph`. Used to compute the values of each region.
69+
/// The SCC computed from `constraints` and the constraint graph. Used to compute the values
70+
/// of each region.
7171
constraint_sccs: Rc<Sccs<RegionVid, ConstraintSccIndex>>,
7272

7373
/// The final inferred values of the region variables; we compute
@@ -207,15 +207,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
207207
pub(crate) fn new(
208208
var_infos: VarInfos,
209209
universal_regions: UniversalRegions<'tcx>,
210-
mir: &Mir<'tcx>,
210+
_mir: &Mir<'tcx>,
211211
outlives_constraints: ConstraintSet,
212212
type_tests: Vec<TypeTest<'tcx>>,
213+
liveness_constraints: RegionValues<RegionVid>,
214+
elements: &Rc<RegionValueElements>,
213215
) -> Self {
214216
let universal_regions = Rc::new(universal_regions);
215-
let num_region_variables = var_infos.len();
216-
let num_universal_regions = universal_regions.len();
217-
218-
let elements = &Rc::new(RegionValueElements::new(mir, num_universal_regions));
219217

220218
// Create a RegionDefinition for each inference variable.
221219
let definitions: IndexVec<_, _> = var_infos
@@ -227,15 +225,20 @@ impl<'tcx> RegionInferenceContext<'tcx> {
227225
let constraint_graph = Rc::new(constraints.graph(definitions.len()));
228226
let constraint_sccs = Rc::new(constraints.compute_sccs(&constraint_graph));
229227

230-
let scc_values = RegionValues::new(elements, constraint_sccs.num_sccs());
228+
let mut scc_values = RegionValues::new(elements);
229+
230+
for (region, location_set) in liveness_constraints.iter_enumerated() {
231+
let scc = constraint_sccs.scc(region);
232+
scc_values.merge_into(scc, location_set);
233+
}
231234

232235
let mut result = Self {
233236
definitions,
234237
elements: elements.clone(),
235-
liveness_constraints: RegionValues::new(elements, num_region_variables),
238+
liveness_constraints,
236239
constraints,
237-
constraint_sccs,
238240
constraint_graph,
241+
constraint_sccs,
239242
scc_values,
240243
type_tests,
241244
universal_regions,
@@ -414,7 +417,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
414417
constraints
415418
});
416419

417-
// To propagate constriants, we walk the DAG induced by the
420+
// To propagate constraints, we walk the DAG induced by the
418421
// SCC. For each SCC, we visit its successors and compute
419422
// their values, then we union all those values to get our
420423
// own.

‎src/librustc_mir/borrow_check/nll/region_infer/values.rs

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
use rustc::mir::{BasicBlock, Location, Mir};
1212
use rustc::ty::RegionVid;
13-
use rustc_data_structures::bitvec::SparseBitMatrix;
13+
use rustc_data_structures::bitvec::{SparseBitMatrix, SparseBitSet};
1414
use rustc_data_structures::indexed_vec::Idx;
1515
use rustc_data_structures::indexed_vec::IndexVec;
1616
use std::fmt::Debug;
@@ -55,11 +55,6 @@ impl RegionValueElements {
5555
}
5656
}
5757

58-
/// Total number of element indices that exist.
59-
crate fn num_elements(&self) -> usize {
60-
self.num_points + self.num_universal_regions
61-
}
62-
6358
/// Converts an element of a region value into a `RegionElementIndex`.
6459
crate fn index<T: ToElementIndex>(&self, elem: T) -> RegionElementIndex {
6560
elem.to_element_index(self)
@@ -188,18 +183,10 @@ impl<N: Idx> RegionValues<N> {
188183
/// Creates a new set of "region values" that tracks causal information.
189184
/// Each of the regions in num_region_variables will be initialized with an
190185
/// empty set of points and no causal information.
191-
crate fn new(elements: &Rc<RegionValueElements>, num_region_variables: usize) -> Self {
192-
assert!(
193-
elements.num_universal_regions <= num_region_variables,
194-
"universal regions are a subset of the region variables"
195-
);
196-
186+
crate fn new(elements: &Rc<RegionValueElements>) -> Self {
197187
Self {
198188
elements: elements.clone(),
199-
matrix: SparseBitMatrix::new(
200-
N::new(num_region_variables),
201-
RegionElementIndex::new(elements.num_elements()),
202-
),
189+
matrix: SparseBitMatrix::new(),
203190
}
204191
}
205192

@@ -227,6 +214,18 @@ impl<N: Idx> RegionValues<N> {
227214
self.matrix.contains(r, i)
228215
}
229216

217+
/// Iterates through each row and the accompanying bit set.
218+
pub fn iter_enumerated<'a>(
219+
&'a self
220+
) -> impl Iterator<Item = (N, &'a SparseBitSet<RegionElementIndex>)> + 'a {
221+
self.matrix.iter_enumerated()
222+
}
223+
224+
/// Merge a row, `from`, originating in another `RegionValues` into the `into` row.
225+
pub fn merge_into(&mut self, into: N, from: &SparseBitSet<RegionElementIndex>) -> bool {
226+
self.matrix.merge_into(into, from)
227+
}
228+
230229
/// True if `sup_region` contains all the CFG points that
231230
/// `sub_region` contains. Ignores universal regions.
232231
crate fn contains_points(&self, sup_region: N, sub_region: N) -> bool {

‎src/librustc_mir/borrow_check/nll/type_check/liveness.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,18 @@ impl<'gen, 'typeck, 'flow, 'gcx, 'tcx> TypeLivenessGenerator<'gen, 'typeck, 'flo
168168
);
169169

170170
cx.tcx().for_each_free_region(&value, |live_region| {
171-
cx.constraints.liveness_set.push((live_region, location));
171+
if let Some(ref mut borrowck_context) = cx.borrowck_context {
172+
let region_vid = borrowck_context.universal_regions.to_region_vid(live_region);
173+
borrowck_context.constraints.liveness_constraints.add_element(region_vid, location);
174+
175+
if let Some(all_facts) = borrowck_context.all_facts {
176+
let start_index = borrowck_context.location_table.start_index(location);
177+
all_facts.region_live_at.push((region_vid, start_index));
178+
179+
let mid_index = borrowck_context.location_table.mid_index(location);
180+
all_facts.region_live_at.push((region_vid, mid_index));
181+
}
182+
}
172183
});
173184
}
174185

‎src/librustc_mir/borrow_check/nll/type_check/mod.rs

Lines changed: 59 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use borrow_check::location::LocationTable;
1616
use borrow_check::nll::constraints::{ConstraintSet, OutlivesConstraint};
1717
use borrow_check::nll::facts::AllFacts;
1818
use borrow_check::nll::region_infer::{ClosureRegionRequirementsExt, TypeTest};
19+
use borrow_check::nll::region_infer::values::{RegionValues, RegionValueElements};
1920
use borrow_check::nll::universal_regions::UniversalRegions;
2021
use borrow_check::nll::ToRegionVid;
2122
use dataflow::move_paths::MoveData;
@@ -33,8 +34,9 @@ use rustc::mir::*;
3334
use rustc::traits::query::type_op;
3435
use rustc::traits::query::{Fallible, NoSolution};
3536
use rustc::ty::fold::TypeFoldable;
36-
use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeVariants};
37+
use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeVariants, RegionVid};
3738
use std::fmt;
39+
use std::rc::Rc;
3840
use syntax_pos::{Span, DUMMY_SP};
3941
use transform::{MirPass, MirSource};
4042
use util::liveness::LivenessResults;
@@ -111,39 +113,55 @@ pub(crate) fn type_check<'gcx, 'tcx>(
111113
all_facts: &mut Option<AllFacts>,
112114
flow_inits: &mut FlowAtLocation<MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
113115
move_data: &MoveData<'tcx>,
116+
elements: &Rc<RegionValueElements>,
114117
) -> MirTypeckRegionConstraints<'tcx> {
115118
let implicit_region_bound = infcx.tcx.mk_region(ty::ReVar(universal_regions.fr_fn_body));
116-
type_check_internal(
117-
infcx,
118-
mir_def_id,
119-
param_env,
120-
mir,
121-
&universal_regions.region_bound_pairs,
122-
Some(implicit_region_bound),
123-
Some(BorrowCheckContext {
119+
let mut constraints = MirTypeckRegionConstraints {
120+
liveness_constraints: RegionValues::new(elements),
121+
outlives_constraints: ConstraintSet::default(),
122+
type_tests: Vec::default(),
123+
};
124+
125+
{
126+
let mut borrowck_context = BorrowCheckContext {
124127
universal_regions,
125128
location_table,
126129
borrow_set,
127130
all_facts,
128-
}),
129-
&mut |cx| {
130-
liveness::generate(cx, mir, liveness, flow_inits, move_data);
131+
constraints: &mut constraints,
132+
};
133+
134+
type_check_internal(
135+
infcx,
136+
mir_def_id,
137+
param_env,
138+
mir,
139+
&universal_regions.region_bound_pairs,
140+
Some(implicit_region_bound),
141+
Some(&mut borrowck_context),
142+
|cx| {
143+
liveness::generate(cx, mir, liveness, flow_inits, move_data);
131144

132-
cx.equate_inputs_and_outputs(mir, mir_def_id, universal_regions);
133-
},
134-
)
145+
cx.equate_inputs_and_outputs(mir, mir_def_id, universal_regions);
146+
},
147+
);
148+
}
149+
150+
constraints
135151
}
136152

137-
fn type_check_internal<'gcx, 'tcx>(
138-
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
153+
fn type_check_internal<'a, 'gcx, 'tcx, F>(
154+
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
139155
mir_def_id: DefId,
140156
param_env: ty::ParamEnv<'gcx>,
141-
mir: &Mir<'tcx>,
142-
region_bound_pairs: &[(ty::Region<'tcx>, GenericKind<'tcx>)],
157+
mir: &'a Mir<'tcx>,
158+
region_bound_pairs: &'a [(ty::Region<'tcx>, GenericKind<'tcx>)],
143159
implicit_region_bound: Option<ty::Region<'tcx>>,
144-
borrowck_context: Option<BorrowCheckContext<'_, 'tcx>>,
145-
extra: &mut dyn FnMut(&mut TypeChecker<'_, 'gcx, 'tcx>),
146-
) -> MirTypeckRegionConstraints<'tcx> {
160+
borrowck_context: Option<&'a mut BorrowCheckContext<'a, 'tcx>>,
161+
mut extra: F,
162+
)
163+
where F: FnMut(&mut TypeChecker<'a, 'gcx, 'tcx>)
164+
{
147165
let mut checker = TypeChecker::new(
148166
infcx,
149167
mir,
@@ -165,8 +183,6 @@ fn type_check_internal<'gcx, 'tcx>(
165183
}
166184

167185
extra(&mut checker);
168-
169-
checker.constraints
170186
}
171187

172188
fn mirbug(tcx: TyCtxt, span: Span, msg: &str) {
@@ -603,20 +619,19 @@ struct TypeChecker<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
603619
region_bound_pairs: &'a [(ty::Region<'tcx>, GenericKind<'tcx>)],
604620
implicit_region_bound: Option<ty::Region<'tcx>>,
605621
reported_errors: FxHashSet<(Ty<'tcx>, Span)>,
606-
constraints: MirTypeckRegionConstraints<'tcx>,
607-
borrowck_context: Option<BorrowCheckContext<'a, 'tcx>>,
622+
borrowck_context: Option<&'a mut BorrowCheckContext<'a, 'tcx>>,
608623
}
609624

610625
struct BorrowCheckContext<'a, 'tcx: 'a> {
611626
universal_regions: &'a UniversalRegions<'tcx>,
612627
location_table: &'a LocationTable,
613628
all_facts: &'a mut Option<AllFacts>,
614629
borrow_set: &'a BorrowSet<'tcx>,
630+
constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
615631
}
616632

617633
/// A collection of region constraints that must be satisfied for the
618634
/// program to be considered well-typed.
619-
#[derive(Default)]
620635
crate struct MirTypeckRegionConstraints<'tcx> {
621636
/// In general, the type-checker is not responsible for enforcing
622637
/// liveness constraints; this job falls to the region inferencer,
@@ -625,7 +640,7 @@ crate struct MirTypeckRegionConstraints<'tcx> {
625640
/// not otherwise appear in the MIR -- in particular, the
626641
/// late-bound regions that it instantiates at call-sites -- and
627642
/// hence it must report on their liveness constraints.
628-
crate liveness_set: Vec<(ty::Region<'tcx>, Location)>,
643+
crate liveness_constraints: RegionValues<RegionVid>,
629644

630645
crate outlives_constraints: ConstraintSet,
631646

@@ -717,7 +732,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
717732
param_env: ty::ParamEnv<'gcx>,
718733
region_bound_pairs: &'a [(ty::Region<'tcx>, GenericKind<'tcx>)],
719734
implicit_region_bound: Option<ty::Region<'tcx>>,
720-
borrowck_context: Option<BorrowCheckContext<'a, 'tcx>>,
735+
borrowck_context: Option<&'a mut BorrowCheckContext<'a, 'tcx>>,
721736
) -> Self {
722737
TypeChecker {
723738
infcx,
@@ -729,7 +744,6 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
729744
implicit_region_bound,
730745
borrowck_context,
731746
reported_errors: FxHashSet(),
732-
constraints: MirTypeckRegionConstraints::default(),
733747
}
734748
}
735749

@@ -767,7 +781,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
767781
locations, data
768782
);
769783

770-
if let Some(borrowck_context) = &mut self.borrowck_context {
784+
if let Some(ref mut borrowck_context) = self.borrowck_context {
771785
constraint_conversion::ConstraintConversion::new(
772786
self.infcx.tcx,
773787
borrowck_context.universal_regions,
@@ -776,8 +790,8 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
776790
self.implicit_region_bound,
777791
self.param_env,
778792
locations,
779-
&mut self.constraints.outlives_constraints,
780-
&mut self.constraints.type_tests,
793+
&mut borrowck_context.constraints.outlives_constraints,
794+
&mut borrowck_context.constraints.type_tests,
781795
&mut borrowck_context.all_facts,
782796
).convert_all(&data);
783797
}
@@ -993,9 +1007,13 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
9931007
// output) types in the signature must be live, since
9941008
// all the inputs that fed into it were live.
9951009
for &late_bound_region in map.values() {
996-
self.constraints
997-
.liveness_set
998-
.push((late_bound_region, term_location));
1010+
if let Some(ref mut borrowck_context) = self.borrowck_context {
1011+
let region_vid = borrowck_context.universal_regions.to_region_vid(
1012+
late_bound_region);
1013+
borrowck_context.constraints
1014+
.liveness_constraints
1015+
.add_element(region_vid, term_location);
1016+
}
9991017
}
10001018

10011019
self.check_call_inputs(mir, term, &sig, args, term_location);
@@ -1487,9 +1505,10 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
14871505
borrow_set,
14881506
location_table,
14891507
all_facts,
1508+
constraints,
14901509
..
1491-
} = match &mut self.borrowck_context {
1492-
Some(borrowck_context) => borrowck_context,
1510+
} = match self.borrowck_context {
1511+
Some(ref mut borrowck_context) => borrowck_context,
14931512
None => return,
14941513
};
14951514

@@ -1531,7 +1550,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
15311550
debug!("add_reborrow_constraint - base_ty = {:?}", base_ty);
15321551
match base_ty.sty {
15331552
ty::TyRef(ref_region, _, mutbl) => {
1534-
self.constraints
1553+
constraints
15351554
.outlives_constraints
15361555
.push(OutlivesConstraint {
15371556
sup: ref_region.to_region_vid(),
@@ -1792,8 +1811,7 @@ impl MirPass for TypeckMir {
17921811

17931812
let param_env = tcx.param_env(def_id);
17941813
tcx.infer_ctxt().enter(|infcx| {
1795-
let _ =
1796-
type_check_internal(&infcx, def_id, param_env, mir, &[], None, None, &mut |_| ());
1814+
type_check_internal(&infcx, def_id, param_env, mir, &[], None, None, |_| ());
17971815

17981816
// For verification purposes, we just ignore the resulting
17991817
// region constraint sets. Not our problem. =)

0 commit comments

Comments
 (0)
Please sign in to comment.