Nit: rework region obligations to a snapshotted vector

This commit is contained in:
Niko Matsakis 2017-11-14 15:12:36 -05:00
parent f72259101f
commit 15739b820f
4 changed files with 31 additions and 18 deletions

View File

@ -35,7 +35,7 @@ use std::fmt;
use syntax::ast;
use errors::DiagnosticBuilder;
use syntax_pos::{self, Span, DUMMY_SP};
use util::nodemap::{NodeMap, FxHashMap};
use util::nodemap::FxHashMap;
use arena::DroplessArena;
use self::combine::CombineFields;
@ -179,7 +179,7 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
// for each body-id in this map, which will process the
// obligations within. This is expected to be done 'late enough'
// that all type inference variables have been bound and so forth.
region_obligations: RefCell<NodeMap<Vec<RegionObligation<'tcx>>>>,
region_obligations: RefCell<Vec<(ast::NodeId, RegionObligation<'tcx>)>>,
}
/// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
@ -450,7 +450,7 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
tainted_by_errors_flag: Cell::new(false),
err_count_on_creation: tcx.sess.err_count(),
in_snapshot: Cell::new(false),
region_obligations: RefCell::new(NodeMap()),
region_obligations: RefCell::new(vec![]),
}))
}
}
@ -478,6 +478,7 @@ pub struct CombinedSnapshot<'a, 'tcx:'a> {
int_snapshot: unify::Snapshot<ty::IntVid>,
float_snapshot: unify::Snapshot<ty::FloatVid>,
region_constraints_snapshot: RegionSnapshot,
region_obligations_snapshot: usize,
was_in_snapshot: bool,
_in_progress_tables: Option<Ref<'a, ty::TypeckTables<'tcx>>>,
}
@ -786,6 +787,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
int_snapshot: self.int_unification_table.borrow_mut().snapshot(),
float_snapshot: self.float_unification_table.borrow_mut().snapshot(),
region_constraints_snapshot: self.borrow_region_constraints().start_snapshot(),
region_obligations_snapshot: self.region_obligations.borrow().len(),
was_in_snapshot: in_snapshot,
// Borrow tables "in progress" (i.e. during typeck)
// to ban writes from within a snapshot to them.
@ -802,6 +804,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
int_snapshot,
float_snapshot,
region_constraints_snapshot,
region_obligations_snapshot,
was_in_snapshot,
_in_progress_tables } = snapshot;
@ -819,6 +822,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
self.float_unification_table
.borrow_mut()
.rollback_to(float_snapshot);
self.region_obligations
.borrow_mut()
.truncate(region_obligations_snapshot);
self.borrow_region_constraints()
.rollback_to(region_constraints_snapshot);
}
@ -830,6 +836,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
int_snapshot,
float_snapshot,
region_constraints_snapshot,
region_obligations_snapshot: _,
was_in_snapshot,
_in_progress_tables } = snapshot;

View File

@ -86,9 +86,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
) {
self.region_obligations
.borrow_mut()
.entry(body_id)
.or_insert(vec![])
.push(obligation);
.push((body_id, obligation));
}
/// Process the region obligations that must be proven (during
@ -131,10 +129,16 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
param_env: ty::ParamEnv<'tcx>,
body_id: ast::NodeId,
) {
let region_obligations = match self.region_obligations.borrow_mut().remove(&body_id) {
None => vec![],
Some(vec) => vec,
};
assert!(!self.in_snapshot.get(), "cannot process registered region obligations in a snapshot");
// pull out the region obligations with the given `body_id` (leaving the rest)
let mut my_region_obligations = Vec::with_capacity(self.region_obligations.borrow().len());
{
let mut r_o = self.region_obligations.borrow_mut();
for (_, obligation) in r_o.drain_filter(|(ro_body_id, _)| *ro_body_id == body_id) {
my_region_obligations.push(obligation);
}
}
let outlives =
TypeOutlives::new(self, region_bound_pairs, implicit_region_bound, param_env);
@ -143,7 +147,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
sup_type,
sub_region,
cause,
} in region_obligations
} in my_region_obligations
{
let origin = SubregionOrigin::from_obligation_cause(
&cause,
@ -170,11 +174,13 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
outlives.type_must_outlive(origin, ty, region);
}
/// Ignore the region obligations for a given `body_id`, not bothering to
/// prove them. This function should not really exist; it is used to accommodate some older
/// code for the time being.
pub fn ignore_region_obligations(&self, body_id: ast::NodeId) {
self.region_obligations.borrow_mut().remove(&body_id);
/// Ignore the region obligations, not bothering to prove
/// them. This function should not really exist; it is used to
/// accommodate some older code for the time being.
pub fn ignore_region_obligations(&self) {
assert!(!self.in_snapshot.get(), "cannot ignore registered region obligations in a snapshot");
self.region_obligations.borrow_mut().clear();
}
}

View File

@ -45,6 +45,7 @@
#![feature(conservative_impl_trait)]
#![feature(const_fn)]
#![feature(core_intrinsics)]
#![feature(drain_filter)]
#![feature(i128_type)]
#![feature(match_default_bindings)]
#![feature(inclusive_range_syntax)]

View File

@ -511,7 +511,6 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
unnormalized_env.reveal);
tcx.infer_ctxt().enter(|infcx| {
let body_id = cause.body_id;
let predicates = match fully_normalize(
&infcx,
cause,
@ -546,7 +545,7 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// properly, and that code is currently largely confined to
// regionck (though I made some efforts to extract it
// out). -nmatsakis
let _ = infcx.ignore_region_obligations(body_id);
let _ = infcx.ignore_region_obligations();
infcx.resolve_regions_and_report_errors(region_context, &region_scope_tree, &free_regions);
let predicates = match infcx.fully_resolve(&predicates) {