Skip to content

Commit 590ab7c

Browse files
committed
Addressed PR comments.
1 parent 8081609 commit 590ab7c

File tree

10 files changed

+65
-97
lines changed

10 files changed

+65
-97
lines changed

src/librustc_data_structures/bitvec.rs

+6-11
Original file line numberDiff line numberDiff line change
@@ -293,15 +293,12 @@ 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+
self.vector.resize_to_elem(row, || SparseBitSet::new());
296297
if let None = self.vector.get(row) {
297298
self.vector.push(SparseBitSet::new());
298299
}
299300

300-
if let Some(row) = self.vector.get_mut(row) {
301-
row.insert(column)
302-
} else {
303-
false
304-
}
301+
self.vector[row].insert(column)
305302
}
306303

307304
/// Do the bits from `row` contain `column`? Put another way, is
@@ -335,10 +332,8 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
335332

336333
/// Merge a row, `from`, into the `into` row.
337334
pub fn merge_into(&mut self, into: R, from: &SparseBitSet<C>) -> bool {
338-
match self.vector.get_mut(into) {
339-
Some(row) => row.merge_into(from),
340-
None => false,
341-
}
335+
self.vector.resize_to_elem(into, || SparseBitSet::new());
336+
self.vector[into].insert_from(from)
342337
}
343338

344339
/// True if `sub` is a subset of `sup`
@@ -471,8 +466,8 @@ impl<I: Idx> SparseBitSet<I> {
471466
}
472467
}
473468

474-
/// Merge two sparse bit sets.
475-
pub fn merge_into(&mut self, from: &SparseBitSet<I>) -> bool {
469+
/// Insert into bit set from another bit set.
470+
pub fn insert_from(&mut self, from: &SparseBitSet<I>) -> bool {
476471
let mut changed = false;
477472
for read_chunk in from.chunks() {
478473
changed = changed | self.insert_chunk(read_chunk).any();

src/librustc_data_structures/indexed_vec.rs

+6
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,12 @@ impl<I: Idx, T: Clone> IndexVec<I, T> {
522522
pub fn resize(&mut self, new_len: usize, value: T) {
523523
self.raw.resize(new_len, value)
524524
}
525+
526+
#[inline]
527+
pub fn resize_to_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) {
528+
let min_new_len = elem.index() + 1;
529+
self.raw.resize_with(min_new_len, fill_value);
530+
}
525531
}
526532

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

src/librustc_data_structures/lib.rs

+1
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

+1-40
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use borrow_check::borrow_set::BorrowSet;
1212
use borrow_check::location::LocationTable;
1313
use borrow_check::nll::ToRegionVid;
1414
use borrow_check::nll::facts::AllFacts;
15-
use borrow_check::nll::region_infer::{RegionElement, RegionInferenceContext};
15+
use borrow_check::nll::region_infer::RegionInferenceContext;
1616
use rustc::infer::InferCtxt;
1717
use rustc::mir::visit::TyContext;
1818
use rustc::mir::visit::Visitor;
@@ -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>,
@@ -39,8 +38,6 @@ pub(super) fn generate_constraints<'cx, 'gcx, 'tcx>(
3938
all_facts,
4039
};
4140

42-
cg.add_region_liveness_constraints_from_type_check();
43-
4441
for (bb, data) in mir.basic_blocks().iter_enumerated() {
4542
cg.visit_basic_block_data(bb, data);
4643
}
@@ -188,42 +185,6 @@ impl<'cg, 'cx, 'gcx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'gcx
188185
}
189186

190187
impl<'cx, 'cg, 'gcx, 'tcx> ConstraintGeneration<'cx, 'cg, 'gcx, 'tcx> {
191-
/// The MIR type checker generates region liveness constraints
192-
/// that we also have to respect.
193-
fn add_region_liveness_constraints_from_type_check(&mut self) {
194-
let ConstraintGeneration {
195-
regioncx,
196-
location_table,
197-
all_facts,
198-
..
199-
} = self;
200-
201-
debug!(
202-
"add_region_liveness_constraints_from_type_check(liveness_constraints={} items)",
203-
regioncx.number_of_liveness_constraints(),
204-
);
205-
206-
if let Some(all_facts) = all_facts {
207-
for (r, _) in regioncx.liveness_constraints() {
208-
all_facts
209-
.region_live_at
210-
.extend(regioncx.elements_contained_in(r)
211-
.filter_map(|region_element| {
212-
if let RegionElement::Location(location) = region_element {
213-
Some(location)
214-
} else {
215-
None
216-
}
217-
})
218-
.flat_map(|location| {
219-
let p1 = location_table.start_index(location);
220-
let p2 = location_table.mid_index(location);
221-
iter::once((r, p1)).chain(iter::once((r, p2)))
222-
}));
223-
}
224-
}
225-
}
226-
227188
/// Some variable with type `live_ty` is "regular live" at
228189
/// `location` -- i.e., it may be used later. This means that all
229190
/// regions appearing in the type `live_ty` must be live at

src/librustc_mir/borrow_check/nll/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +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::RegionValueElements;
15+
use borrow_check::nll::region_infer::values::RegionValueElements;
1616
use dataflow::indexes::BorrowIndex;
1717
use dataflow::move_paths::MoveData;
1818
use dataflow::FlowAtLocation;

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

+14
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,20 @@ impl<'tcx> RegionInferenceContext<'tcx> {
9494
}
9595
return;
9696
}
97+
98+
for constraint in self.constraint_graph.outgoing_edges(current_region) {
99+
assert_eq!(self.constraints[constraint].sup, current_region);
100+
stack.push(constraint);
101+
self.find_constraint_paths_between_regions_helper(
102+
from_region,
103+
self.constraints[constraint].sub,
104+
target_test,
105+
visited,
106+
stack,
107+
results,
108+
);
109+
stack.pop();
110+
}
97111
}
98112

99113
/// This function will return true if a constraint is interesting and false if a constraint

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

+9-23
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use super::universal_regions::UniversalRegions;
1212
use borrow_check::nll::constraints::{
1313
ConstraintIndex, ConstraintSccIndex, ConstraintSet, OutlivesConstraint,
1414
};
15+
use borrow_check::nll::constraints::graph::ConstraintGraph;
1516
use borrow_check::nll::region_infer::values::ToElementIndex;
1617
use borrow_check::nll::type_check::Locations;
1718
use rustc::hir::def_id::DefId;
@@ -26,7 +27,6 @@ use rustc::mir::{
2627
};
2728
use rustc::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable};
2829
use rustc::util::common;
29-
use rustc_data_structures::bitvec::SparseBitSet;
3030
use rustc_data_structures::graph::scc::Sccs;
3131
use rustc_data_structures::indexed_set::{IdxSet, IdxSetBuf};
3232
use rustc_data_structures::indexed_vec::IndexVec;
@@ -37,8 +37,8 @@ mod annotation;
3737
mod dump_mir;
3838
mod error_reporting;
3939
mod graphviz;
40-
mod values;
41-
crate use self::values::{RegionElement, RegionElementIndex, RegionValueElements, RegionValues};
40+
pub mod values;
41+
use self::values::{RegionValueElements, RegionValues};
4242

4343
use super::ToRegionVid;
4444

@@ -61,6 +61,11 @@ pub struct RegionInferenceContext<'tcx> {
6161
/// The outlives constraints computed by the type-check.
6262
constraints: Rc<ConstraintSet>,
6363

64+
/// The constraint-set, but in graph form, making it easy to traverse
65+
/// the constraints adjacent to a particular region. Used to construct
66+
/// the SCC (see `constraint_sccs`) and for error reporting.
67+
constraint_graph: Rc<ConstraintGraph>,
68+
6469
/// The SCC computed from `constraints` and the constraint graph. Used to compute the values
6570
/// of each region.
6671
constraint_sccs: Rc<Sccs<RegionVid, ConstraintSccIndex>>,
@@ -232,6 +237,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
232237
elements: elements.clone(),
233238
liveness_constraints,
234239
constraints,
240+
constraint_graph,
235241
constraint_sccs,
236242
scc_values,
237243
type_tests,
@@ -301,26 +307,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
301307
self.definitions.indices()
302308
}
303309

304-
/// Iterates through each row and the accompanying bit set.
305-
pub fn liveness_constraints<'a>(
306-
&'a self
307-
) -> impl Iterator<Item = (RegionVid, &'a SparseBitSet<RegionElementIndex>)> + 'a {
308-
self.liveness_constraints.iter_enumerated()
309-
}
310-
311-
/// Number of liveness constaints in region inference context.
312-
pub fn number_of_liveness_constraints(&self) -> usize {
313-
self.liveness_constraints.len()
314-
}
315-
316-
/// Returns all the elements contained in a given region's value.
317-
crate fn elements_contained_in<'a>(
318-
&'a self,
319-
r: RegionVid,
320-
) -> impl Iterator<Item = RegionElement> + 'a {
321-
self.liveness_constraints.elements_contained_in(r)
322-
}
323-
324310
/// Given a universal region in scope on the MIR, returns the
325311
/// corresponding index.
326312
///

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

-5
Original file line numberDiff line numberDiff line change
@@ -214,11 +214,6 @@ impl<N: Idx> RegionValues<N> {
214214
self.matrix.contains(r, i)
215215
}
216216

217-
/// Number of region values.
218-
crate fn len(&self) -> usize {
219-
self.matrix.len()
220-
}
221-
222217
/// Iterates through each row and the accompanying bit set.
223218
pub fn iter_enumerated<'a>(
224219
&'a self

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

+9-1
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,17 @@ impl<'gen, 'typeck, 'flow, 'gcx, 'tcx> TypeLivenessGenerator<'gen, 'typeck, 'flo
168168
);
169169

170170
cx.tcx().for_each_free_region(&value, |live_region| {
171-
if let Some(borrowck_context) = cx.borrowck_context {
171+
if let Some(ref mut borrowck_context) = cx.borrowck_context {
172172
let region_vid = borrowck_context.universal_regions.to_region_vid(live_region);
173173
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+
}
174182
}
175183
});
176184
}

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

+18-16
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ use borrow_check::borrow_set::BorrowSet;
1515
use borrow_check::location::LocationTable;
1616
use borrow_check::nll::constraints::{ConstraintSet, OutlivesConstraint};
1717
use borrow_check::nll::facts::AllFacts;
18-
use borrow_check::nll::region_infer::{ClosureRegionRequirementsExt, TypeTest, RegionValues};
19-
use borrow_check::nll::region_infer::{RegionValueElements};
18+
use borrow_check::nll::region_infer::{ClosureRegionRequirementsExt, TypeTest};
19+
use borrow_check::nll::region_infer::values::{RegionValues, RegionValueElements};
2020
use borrow_check::nll::universal_regions::UniversalRegions;
2121
use borrow_check::nll::ToRegionVid;
2222
use dataflow::move_paths::MoveData;
@@ -123,7 +123,7 @@ pub(crate) fn type_check<'gcx, 'tcx>(
123123
};
124124

125125
{
126-
let borrowck_context = BorrowCheckContext {
126+
let mut borrowck_context = BorrowCheckContext {
127127
universal_regions,
128128
location_table,
129129
borrow_set,
@@ -138,8 +138,8 @@ pub(crate) fn type_check<'gcx, 'tcx>(
138138
mir,
139139
&universal_regions.region_bound_pairs,
140140
Some(implicit_region_bound),
141-
&mut Some(borrowck_context),
142-
&mut |cx| {
141+
Some(&mut borrowck_context),
142+
|cx| {
143143
liveness::generate(cx, mir, liveness, flow_inits, move_data);
144144

145145
cx.equate_inputs_and_outputs(mir, mir_def_id, universal_regions);
@@ -150,16 +150,18 @@ pub(crate) fn type_check<'gcx, 'tcx>(
150150
constraints
151151
}
152152

153-
fn type_check_internal<'a, 'gcx, 'tcx>(
153+
fn type_check_internal<'a, 'gcx, 'tcx, F>(
154154
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
155155
mir_def_id: DefId,
156156
param_env: ty::ParamEnv<'gcx>,
157157
mir: &'a Mir<'tcx>,
158158
region_bound_pairs: &'a [(ty::Region<'tcx>, GenericKind<'tcx>)],
159159
implicit_region_bound: Option<ty::Region<'tcx>>,
160-
borrowck_context: &'a mut Option<BorrowCheckContext<'a, 'tcx>>,
161-
extra: &'a mut dyn FnMut(&mut TypeChecker<'a, 'gcx, 'tcx>),
162-
) {
160+
borrowck_context: Option<&'a mut BorrowCheckContext<'a, 'tcx>>,
161+
mut extra: F,
162+
)
163+
where F: FnMut(&mut TypeChecker<'a, 'gcx, 'tcx>)
164+
{
163165
let mut checker = TypeChecker::new(
164166
infcx,
165167
mir,
@@ -617,7 +619,7 @@ struct TypeChecker<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
617619
region_bound_pairs: &'a [(ty::Region<'tcx>, GenericKind<'tcx>)],
618620
implicit_region_bound: Option<ty::Region<'tcx>>,
619621
reported_errors: FxHashSet<(Ty<'tcx>, Span)>,
620-
borrowck_context: &'a mut Option<BorrowCheckContext<'a, 'tcx>>,
622+
borrowck_context: Option<&'a mut BorrowCheckContext<'a, 'tcx>>,
621623
}
622624

623625
struct BorrowCheckContext<'a, 'tcx: 'a> {
@@ -730,7 +732,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
730732
param_env: ty::ParamEnv<'gcx>,
731733
region_bound_pairs: &'a [(ty::Region<'tcx>, GenericKind<'tcx>)],
732734
implicit_region_bound: Option<ty::Region<'tcx>>,
733-
borrowck_context: &'a mut Option<BorrowCheckContext<'a, 'tcx>>,
735+
borrowck_context: Option<&'a mut BorrowCheckContext<'a, 'tcx>>,
734736
) -> Self {
735737
TypeChecker {
736738
infcx,
@@ -779,7 +781,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
779781
locations, data
780782
);
781783

782-
if let Some(borrowck_context) = &mut self.borrowck_context {
784+
if let Some(ref mut borrowck_context) = self.borrowck_context {
783785
constraint_conversion::ConstraintConversion::new(
784786
self.infcx.tcx,
785787
borrowck_context.universal_regions,
@@ -1005,7 +1007,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
10051007
// output) types in the signature must be live, since
10061008
// all the inputs that fed into it were live.
10071009
for &late_bound_region in map.values() {
1008-
if let Some(borrowck_context) = self.borrowck_context {
1010+
if let Some(ref mut borrowck_context) = self.borrowck_context {
10091011
let region_vid = borrowck_context.universal_regions.to_region_vid(
10101012
late_bound_region);
10111013
borrowck_context.constraints
@@ -1505,8 +1507,8 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
15051507
all_facts,
15061508
constraints,
15071509
..
1508-
} = match &mut self.borrowck_context {
1509-
Some(borrowck_context) => borrowck_context,
1510+
} = match self.borrowck_context {
1511+
Some(ref mut borrowck_context) => borrowck_context,
15101512
None => return,
15111513
};
15121514

@@ -1809,7 +1811,7 @@ impl MirPass for TypeckMir {
18091811

18101812
let param_env = tcx.param_env(def_id);
18111813
tcx.infer_ctxt().enter(|infcx| {
1812-
type_check_internal(&infcx, def_id, param_env, mir, &[], None, &mut None, &mut |_| ());
1814+
type_check_internal(&infcx, def_id, param_env, mir, &[], None, None, |_| ());
18131815

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

0 commit comments

Comments
 (0)