build up the placeholder indices as we go

Avoids a linear walk over the regions at the end.
This commit is contained in:
Niko Matsakis 2018-09-28 14:35:43 -04:00
parent 0887456401
commit cdb95b0f21
5 changed files with 43 additions and 31 deletions

View file

@ -107,6 +107,7 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
// Run the MIR type-checker.
let MirTypeckResults {
constraints,
placeholder_indices,
universal_region_relations,
} = type_check::type_check(
infcx,
@ -122,6 +123,8 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
elements,
);
let placeholder_indices = Rc::new(placeholder_indices);
if let Some(all_facts) = &mut all_facts {
all_facts
.universal_region
@ -150,6 +153,7 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
let mut regioncx = RegionInferenceContext::new(
var_origins,
universal_regions,
placeholder_indices,
universal_region_relations,
mir,
outlives_constraints,

View file

@ -183,6 +183,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
pub(crate) fn new(
var_infos: VarInfos,
universal_regions: Rc<UniversalRegions<'tcx>>,
placeholder_indices: Rc<PlaceholderIndices>,
universal_region_relations: Rc<UniversalRegionRelations<'tcx>>,
_mir: &Mir<'tcx>,
outlives_constraints: ConstraintSet,
@ -196,22 +197,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
.map(|info| RegionDefinition::new(info.universe, info.origin))
.collect();
// Compute the max universe used anywhere amongst the regions.
let placeholder_indices: PlaceholderIndices = definitions
.iter()
.filter_map(|d| match d.origin {
NLLRegionVariableOrigin::Placeholder(placeholder) => Some(placeholder),
_ => None,
})
.collect();
let constraints = Rc::new(outlives_constraints); // freeze constraints
let constraint_graph = Rc::new(constraints.graph(definitions.len()));
let fr_static = universal_regions.fr_static;
let constraint_sccs = Rc::new(constraints.compute_sccs(&constraint_graph, fr_static));
let mut scc_values =
RegionValues::new(elements, universal_regions.len(), placeholder_indices);
RegionValues::new(elements, universal_regions.len(), &placeholder_indices);
for region in liveness_constraints.rows() {
let scc = constraint_sccs.scc(region);

View file

@ -302,13 +302,13 @@ impl<N: Idx> RegionValues<N> {
crate fn new(
elements: &Rc<RegionValueElements>,
num_universal_regions: usize,
placeholder_indices: PlaceholderIndices,
placeholder_indices: &Rc<PlaceholderIndices>,
) -> Self {
let num_placeholders = placeholder_indices.len();
Self {
elements: elements.clone(),
points: SparseBitMatrix::new(elements.num_points),
placeholder_indices: Rc::new(placeholder_indices),
placeholder_indices: placeholder_indices.clone(),
free_regions: SparseBitMatrix::new(num_universal_regions),
placeholders: SparseBitMatrix::new(num_placeholders),
}

View file

@ -15,7 +15,9 @@ use borrow_check::borrow_set::BorrowSet;
use borrow_check::location::LocationTable;
use borrow_check::nll::constraints::{ConstraintCategory, ConstraintSet, OutlivesConstraint};
use borrow_check::nll::facts::AllFacts;
use borrow_check::nll::region_infer::values::{LivenessValues, RegionValueElements};
use borrow_check::nll::region_infer::values::LivenessValues;
use borrow_check::nll::region_infer::values::PlaceholderIndices;
use borrow_check::nll::region_infer::values::RegionValueElements;
use borrow_check::nll::region_infer::{ClosureRegionRequirementsExt, TypeTest};
use borrow_check::nll::renumber;
use borrow_check::nll::type_check::free_region_relations::{
@ -42,13 +44,13 @@ use rustc::traits::{ObligationCause, PredicateObligations};
use rustc::ty::fold::TypeFoldable;
use rustc::ty::subst::Subst;
use rustc::ty::{self, CanonicalTy, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind};
use std::{fmt, iter};
use std::rc::Rc;
use std::{fmt, iter};
use syntax_pos::{Span, DUMMY_SP};
use transform::{MirPass, MirSource};
use rustc_data_structures::fx::FxHashSet;
use either::Either;
use rustc_data_structures::fx::FxHashSet;
macro_rules! span_mirbug {
($context:expr, $elem:expr, $($message:tt)*) => ({
@ -128,6 +130,7 @@ pub(crate) fn type_check<'gcx, 'tcx>(
outlives_constraints: ConstraintSet::default(),
type_tests: Vec::default(),
};
let mut placeholder_indices = PlaceholderIndices::default();
let CreateResult {
universal_region_relations,
@ -147,6 +150,7 @@ pub(crate) fn type_check<'gcx, 'tcx>(
borrow_set,
all_facts,
constraints: &mut constraints,
placeholder_indices: &mut placeholder_indices,
};
type_check_internal(
@ -162,12 +166,15 @@ pub(crate) fn type_check<'gcx, 'tcx>(
cx.equate_inputs_and_outputs(mir, universal_regions, &normalized_inputs_and_output);
liveness::generate(cx, mir, elements, flow_inits, move_data, location_table);
cx.borrowck_context.as_mut().map(|bcx| translate_outlives_facts(bcx));
cx.borrowck_context
.as_mut()
.map(|bcx| translate_outlives_facts(bcx));
},
);
MirTypeckResults {
constraints,
placeholder_indices,
universal_region_relations,
}
}
@ -210,21 +217,25 @@ fn type_check_internal<'a, 'gcx, 'tcx, R>(
fn translate_outlives_facts(cx: &mut BorrowCheckContext) {
if let Some(facts) = cx.all_facts {
let location_table = cx.location_table;
facts.outlives.extend(
cx.constraints.outlives_constraints.iter().flat_map(|constraint: &OutlivesConstraint| {
if let Some(from_location) = constraint.locations.from_location() {
Either::Left(iter::once((
constraint.sup,
constraint.sub,
location_table.mid_index(from_location),
)))
} else {
Either::Right(location_table.all_points().map(move |location| {
(constraint.sup, constraint.sub, location)
}))
}
})
);
facts
.outlives
.extend(cx.constraints.outlives_constraints.iter().flat_map(
|constraint: &OutlivesConstraint| {
if let Some(from_location) = constraint.locations.from_location() {
Either::Left(iter::once((
constraint.sup,
constraint.sub,
location_table.mid_index(from_location),
)))
} else {
Either::Right(
location_table
.all_points()
.map(move |location| (constraint.sup, constraint.sub, location)),
)
}
},
));
}
}
@ -718,10 +729,12 @@ struct BorrowCheckContext<'a, 'tcx: 'a> {
all_facts: &'a mut Option<AllFacts>,
borrow_set: &'a BorrowSet<'tcx>,
constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
placeholder_indices: &'a mut PlaceholderIndices,
}
crate struct MirTypeckResults<'tcx> {
crate constraints: MirTypeckRegionConstraints<'tcx>,
crate placeholder_indices: PlaceholderIndices,
crate universal_region_relations: Rc<UniversalRegionRelations<'tcx>>,
}

View file

@ -217,6 +217,9 @@ impl TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, '_, 'tcx> {
fn next_placeholder_region(&mut self, placeholder: ty::Placeholder) -> ty::Region<'tcx> {
let origin = NLLRegionVariableOrigin::Placeholder(placeholder);
if let Some(borrowck_context) = &mut self.borrowck_context {
borrowck_context.placeholder_indices.insert(placeholder);
}
self.infcx.next_nll_region_var(origin)
}