move refcells out from RegionVarBindings and up into InferCtxt

This commit is contained in:
Niko Matsakis 2017-11-05 06:25:23 -05:00
parent 63d658d87c
commit cff191d444
11 changed files with 151 additions and 156 deletions

View File

@ -104,7 +104,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
a,
b);
let origin = Subtype(self.fields.trace.clone());
self.fields.infcx.region_vars.make_eqregion(origin, a, b);
self.fields.infcx.region_vars.borrow_mut().make_eqregion(origin, a, b);
Ok(a)
}

View File

@ -78,7 +78,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
self.type_variables.borrow_mut().types_created_since_snapshot(
&snapshot.type_snapshot);
let region_vars =
self.region_vars.vars_created_since_snapshot(
self.region_vars.borrow().vars_created_since_snapshot(
&snapshot.region_vars_snapshot);
Ok((type_variables, region_vars, value))

View File

@ -67,7 +67,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
b);
let origin = Subtype(self.fields.trace.clone());
Ok(self.fields.infcx.region_vars.glb_regions(self.tcx(), origin, a, b))
Ok(self.fields.infcx.region_vars.borrow_mut().glb_regions(self.tcx(), origin, a, b))
}
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)

View File

@ -176,9 +176,9 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
.filter(|&r| r != representative)
{
let origin = SubregionOrigin::Subtype(self.trace.clone());
self.infcx.region_vars.make_eqregion(origin,
*representative,
*region);
self.infcx.region_vars.borrow_mut().make_eqregion(origin,
*representative,
*region);
}
}
@ -427,7 +427,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
fn fresh_bound_variable<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
debruijn: ty::DebruijnIndex)
-> ty::Region<'tcx> {
infcx.region_vars.new_bound(infcx.tcx, debruijn)
infcx.region_vars.borrow_mut().new_bound(infcx.tcx, debruijn)
}
}
}
@ -481,7 +481,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
r: ty::Region<'tcx>,
directions: TaintDirections)
-> FxHashSet<ty::Region<'tcx>> {
self.region_vars.tainted(self.tcx, &snapshot.region_vars_snapshot, r, directions)
self.region_vars.borrow().tainted(self.tcx, &snapshot.region_vars_snapshot, r, directions)
}
fn region_vars_confined_to_snapshot(&self,
@ -539,7 +539,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
*/
let mut region_vars =
self.region_vars.vars_created_since_snapshot(&snapshot.region_vars_snapshot);
self.region_vars.borrow().vars_created_since_snapshot(&snapshot.region_vars_snapshot);
let escaping_types =
self.type_variables.borrow_mut().types_escaping_snapshot(&snapshot.type_snapshot);
@ -581,7 +581,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
where T : TypeFoldable<'tcx>
{
let (result, map) = self.tcx.replace_late_bound_regions(binder, |br| {
self.region_vars.push_skolemized(self.tcx, br, &snapshot.region_vars_snapshot)
self.region_vars.borrow_mut().push_skolemized(self.tcx,
br,
&snapshot.region_vars_snapshot)
});
debug!("skolemize_bound_regions(binder={:?}, result={:?}, map={:?})",
@ -766,7 +768,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
{
debug!("pop_skolemized({:?})", skol_map);
let skol_regions: FxHashSet<_> = skol_map.values().cloned().collect();
self.region_vars.pop_skolemized(self.tcx, &skol_regions, &snapshot.region_vars_snapshot);
self.region_vars.borrow_mut().pop_skolemized(self.tcx,
&skol_regions,
&snapshot.region_vars_snapshot);
if !skol_map.is_empty() {
self.projection_cache.borrow_mut().rollback_skolemized(
&snapshot.projection_cache_snapshot);

View File

@ -113,8 +113,7 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>(
}
};
let constraints = &*region_vars.constraints.borrow();
match dump_region_constraints_to(region_rels, constraints, &output_path) {
match dump_region_constraints_to(region_rels, &region_vars.constraints, &output_path) {
Ok(()) => {}
Err(e) => {
let msg = format!("io error dumping region constraints: {}", e);

View File

@ -80,7 +80,7 @@ impl<'tcx> RegionVarBindings<'tcx> {
/// constraints, assuming such values can be found; if they cannot,
/// errors are reported.
pub fn resolve_regions(
&self,
&mut self,
region_rels: &RegionRelations<'_, '_, 'tcx>,
) -> (
LexicalRegionResolutions<'tcx>,
@ -114,7 +114,7 @@ impl<'tcx> RegionVarBindings<'tcx> {
(&ReVar(v_id), _) | (_, &ReVar(v_id)) => {
span_bug!(
(*self.var_origins.borrow())[v_id.index as usize].span(),
self.var_origins[v_id.index as usize].span(),
"lub_concrete_regions invoked with non-concrete \
regions: {:?}, {:?}",
a,
@ -183,7 +183,7 @@ impl<'tcx> RegionVarBindings<'tcx> {
}
fn infer_variable_values(
&self,
&mut self,
region_rels: &RegionRelations<'_, '_, 'tcx>,
errors: &mut Vec<RegionResolutionError<'tcx>>,
) -> LexicalRegionResolutions<'tcx> {
@ -222,12 +222,12 @@ impl<'tcx> RegionVarBindings<'tcx> {
"----() Start constraint listing (context={:?}) ()----",
free_regions.context
);
for (idx, (constraint, _)) in self.constraints.borrow().iter().enumerate() {
for (idx, (constraint, _)) in self.constraints.iter().enumerate() {
debug!("Constraint {} => {:?}", idx, constraint);
}
}
fn expand_givens(&self, graph: &RegionGraph) {
fn expand_givens(&mut self, graph: &RegionGraph) {
// Givens are a kind of horrible hack to account for
// constraints like 'c <= '0 that are known to hold due to
// closure signatures (see the comment above on the `givens`
@ -238,15 +238,14 @@ impl<'tcx> RegionVarBindings<'tcx> {
// and '0 <= '1
// then 'c <= '1
let mut givens = self.givens.borrow_mut();
let seeds: Vec<_> = givens.iter().cloned().collect();
let seeds: Vec<_> = self.givens.iter().cloned().collect();
for (r, vid) in seeds {
let seed_index = NodeIndex(vid.index as usize);
for succ_index in graph.depth_traverse(seed_index, OUTGOING) {
let succ_index = succ_index.0 as u32;
if succ_index < self.num_vars() {
let succ_vid = RegionVid { index: succ_index };
givens.insert((r, succ_vid));
self.givens.insert((r, succ_vid));
}
}
}
@ -292,7 +291,7 @@ impl<'tcx> RegionVarBindings<'tcx> {
// Check if this relationship is implied by a given.
match *a_region {
ty::ReEarlyBound(_) | ty::ReFree(_) => {
if self.givens.borrow().contains(&(a_region, b_vid)) {
if self.givens.contains(&(a_region, b_vid)) {
debug!("given");
return false;
}
@ -333,8 +332,7 @@ impl<'tcx> RegionVarBindings<'tcx> {
var_data: &mut LexicalRegionResolutions<'tcx>,
errors: &mut Vec<RegionResolutionError<'tcx>>,
) {
let constraints = self.constraints.borrow();
for (constraint, origin) in constraints.iter() {
for (constraint, origin) in &self.constraints {
debug!(
"collect_errors: constraint={:?} origin={:?}",
constraint,
@ -392,7 +390,7 @@ impl<'tcx> RegionVarBindings<'tcx> {
}
}
for verify in self.verifys.borrow().iter() {
for verify in &self.verifys {
debug!("collect_errors: verify={:?}", verify);
let sub = var_data.normalize(verify.region);
@ -488,8 +486,6 @@ impl<'tcx> RegionVarBindings<'tcx> {
fn construct_graph(&self) -> RegionGraph<'tcx> {
let num_vars = self.num_vars();
let constraints = self.constraints.borrow();
let mut graph = graph::Graph::new();
for _ in 0..num_vars {
@ -504,7 +500,7 @@ impl<'tcx> RegionVarBindings<'tcx> {
let dummy_source = graph.add_node(());
let dummy_sink = graph.add_node(());
for (constraint, _) in constraints.iter() {
for (constraint, _) in &self.constraints {
match *constraint {
Constraint::VarSubVar(a_id, b_id) => {
graph.add_edge(
@ -564,7 +560,7 @@ impl<'tcx> RegionVarBindings<'tcx> {
for lower_bound in &lower_bounds {
for upper_bound in &upper_bounds {
if !region_rels.is_subregion_of(lower_bound.region, upper_bound.region) {
let origin = (*self.var_origins.borrow())[node_idx.index as usize].clone();
let origin = self.var_origins[node_idx.index as usize].clone();
debug!(
"region inference error at {:?} for {:?}: SubSupConflict sub: {:?} \
sup: {:?}",
@ -586,7 +582,7 @@ impl<'tcx> RegionVarBindings<'tcx> {
}
span_bug!(
(*self.var_origins.borrow())[node_idx.index as usize].span(),
self.var_origins[node_idx.index as usize].span(),
"collect_error_for_expanding_node() could not find \
error for var {:?}, lower_bounds={:?}, \
upper_bounds={:?}",
@ -671,7 +667,7 @@ impl<'tcx> RegionVarBindings<'tcx> {
Constraint::RegSubVar(region, _) | Constraint::VarSubReg(_, region) => {
state.result.push(RegionAndOrigin {
region,
origin: this.constraints.borrow().get(&edge.data).unwrap().clone(),
origin: this.constraints.get(&edge.data).unwrap().clone(),
});
}
@ -694,7 +690,7 @@ impl<'tcx> RegionVarBindings<'tcx> {
changed = false;
iteration += 1;
debug!("---- {} Iteration {}{}", "#", tag, iteration);
for (constraint, origin) in self.constraints.borrow().iter() {
for (constraint, origin) in &self.constraints {
let edge_changed = body(constraint, origin);
if edge_changed {
debug!("Updated due to constraint {:?}", constraint);

View File

@ -67,7 +67,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
b);
let origin = Subtype(self.fields.trace.clone());
Ok(self.fields.infcx.region_vars.lub_regions(self.tcx(), origin, a, b))
Ok(self.fields.infcx.region_vars.borrow_mut().lub_regions(self.tcx(), origin, a, b))
}
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)

View File

@ -104,7 +104,7 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
float_unification_table: RefCell<UnificationTable<ty::FloatVid>>,
// For region variables.
region_vars: RegionVarBindings<'tcx>,
region_vars: RefCell<RegionVarBindings<'tcx>>,
// Once region inference is done, the values for each variable.
lexical_region_resolutions: RefCell<Option<LexicalRegionResolutions<'tcx>>>,
@ -424,7 +424,7 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
type_variables: RefCell::new(type_variable::TypeVariableTable::new()),
int_unification_table: RefCell::new(UnificationTable::new()),
float_unification_table: RefCell::new(UnificationTable::new()),
region_vars: RegionVarBindings::new(),
region_vars: RefCell::new(RegionVarBindings::new()),
lexical_region_resolutions: RefCell::new(None),
selection_cache: traits::SelectionCache::new(),
evaluation_cache: traits::EvaluationCache::new(),
@ -767,7 +767,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
type_snapshot: self.type_variables.borrow_mut().snapshot(),
int_snapshot: self.int_unification_table.borrow_mut().snapshot(),
float_snapshot: self.float_unification_table.borrow_mut().snapshot(),
region_vars_snapshot: self.region_vars.start_snapshot(),
region_vars_snapshot: self.region_vars.borrow_mut().start_snapshot(),
was_in_snapshot: in_snapshot,
// Borrow tables "in progress" (i.e. during typeck)
// to ban writes from within a snapshot to them.
@ -802,6 +802,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
.borrow_mut()
.rollback_to(float_snapshot);
self.region_vars
.borrow_mut()
.rollback_to(region_vars_snapshot);
}
@ -830,6 +831,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
.borrow_mut()
.commit(float_snapshot);
self.region_vars
.borrow_mut()
.commit(region_vars_snapshot);
}
@ -885,7 +887,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
sub: ty::Region<'tcx>,
sup: ty::RegionVid)
{
self.region_vars.add_given(sub, sup);
self.region_vars.borrow_mut().add_given(sub, sup);
}
pub fn can_sub<T>(&self,
@ -925,7 +927,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
a: ty::Region<'tcx>,
b: ty::Region<'tcx>) {
debug!("sub_regions({:?} <: {:?})", a, b);
self.region_vars.make_subregion(origin, a, b);
self.region_vars.borrow_mut().make_subregion(origin, a, b);
}
pub fn equality_predicate(&self,
@ -1028,7 +1030,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
pub fn next_region_var(&self, origin: RegionVariableOrigin)
-> ty::Region<'tcx> {
self.tcx.mk_region(ty::ReVar(self.region_vars.new_region_var(origin)))
self.tcx.mk_region(ty::ReVar(self.region_vars.borrow_mut().new_region_var(origin)))
}
/// Create a region inference variable for the given
@ -1124,7 +1126,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
region_context,
region_map,
free_regions);
let (lexical_region_resolutions, errors) = self.region_vars.resolve_regions(&region_rels);
let (lexical_region_resolutions, errors) =
self.region_vars.borrow_mut().resolve_regions(&region_rels);
let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions));
assert!(old_value.is_none());
@ -1362,7 +1365,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
a,
bound);
self.region_vars.verify_generic_bound(origin, kind, a, bound);
self.region_vars.borrow_mut().verify_generic_bound(origin, kind, a, bound);
}
pub fn type_moves_by_default(&self,

View File

@ -24,7 +24,6 @@ use ty::ReStatic;
use ty::{BrFresh, ReLateBound, ReSkolemized, ReVar};
use std::collections::BTreeMap;
use std::cell::{Cell, RefCell};
use std::fmt;
use std::mem;
use std::u32;
@ -145,7 +144,7 @@ enum CombineMapType {
type CombineMap<'tcx> = FxHashMap<TwoRegions<'tcx>, RegionVid>;
pub struct RegionVarBindings<'tcx> {
pub(in infer) var_origins: RefCell<Vec<RegionVariableOrigin>>,
pub(in infer) var_origins: Vec<RegionVariableOrigin>,
/// Constraints of the form `A <= B` introduced by the region
/// checker. Here at least one of `A` and `B` must be a region
@ -156,14 +155,14 @@ pub struct RegionVarBindings<'tcx> {
/// which in turn affects the way that region errors are reported,
/// leading to small variations in error output across runs and
/// platforms.
pub(in infer) constraints: RefCell<BTreeMap<Constraint<'tcx>, SubregionOrigin<'tcx>>>,
pub(in infer) constraints: BTreeMap<Constraint<'tcx>, SubregionOrigin<'tcx>>,
/// A "verify" is something that we need to verify after inference is
/// done, but which does not directly affect inference in any way.
///
/// An example is a `A <= B` where neither `A` nor `B` are
/// inference variables.
pub(in infer) verifys: RefCell<Vec<Verify<'tcx>>>,
pub(in infer) verifys: Vec<Verify<'tcx>>,
/// A "given" is a relationship that is known to hold. In particular,
/// we often know from closure fn signatures that a particular free
@ -182,12 +181,12 @@ pub struct RegionVarBindings<'tcx> {
/// record the fact that `'a <= 'b` is implied by the fn signature,
/// and then ignore the constraint when solving equations. This is
/// a bit of a hack but seems to work.
pub(in infer) givens: RefCell<FxHashSet<(Region<'tcx>, ty::RegionVid)>>,
pub(in infer) givens: FxHashSet<(Region<'tcx>, ty::RegionVid)>,
lubs: RefCell<CombineMap<'tcx>>,
glbs: RefCell<CombineMap<'tcx>>,
skolemization_count: Cell<u32>,
bound_count: Cell<u32>,
lubs: CombineMap<'tcx>,
glbs: CombineMap<'tcx>,
skolemization_count: u32,
bound_count: u32,
/// The undo log records actions that might later be undone.
///
@ -198,9 +197,9 @@ pub struct RegionVarBindings<'tcx> {
/// otherwise we end up adding entries for things like the lower
/// bound on a variable and so forth, which can never be rolled
/// back.
undo_log: RefCell<Vec<UndoLogEntry<'tcx>>>,
undo_log: Vec<UndoLogEntry<'tcx>>,
unification_table: RefCell<UnificationTable<ty::RegionVid>>,
unification_table: UnificationTable<ty::RegionVid>,
}
pub struct RegionSnapshot {
@ -246,73 +245,70 @@ impl TaintDirections {
impl<'tcx> RegionVarBindings<'tcx> {
pub fn new() -> RegionVarBindings<'tcx> {
RegionVarBindings {
var_origins: RefCell::new(Vec::new()),
constraints: RefCell::new(BTreeMap::new()),
verifys: RefCell::new(Vec::new()),
givens: RefCell::new(FxHashSet()),
lubs: RefCell::new(FxHashMap()),
glbs: RefCell::new(FxHashMap()),
skolemization_count: Cell::new(0),
bound_count: Cell::new(0),
undo_log: RefCell::new(Vec::new()),
unification_table: RefCell::new(UnificationTable::new()),
var_origins: Vec::new(),
constraints: BTreeMap::new(),
verifys: Vec::new(),
givens: FxHashSet(),
lubs: FxHashMap(),
glbs: FxHashMap(),
skolemization_count: 0,
bound_count: 0,
undo_log: Vec::new(),
unification_table: UnificationTable::new(),
}
}
fn in_snapshot(&self) -> bool {
!self.undo_log.borrow().is_empty()
!self.undo_log.is_empty()
}
pub fn start_snapshot(&self) -> RegionSnapshot {
let length = self.undo_log.borrow().len();
pub fn start_snapshot(&mut self) -> RegionSnapshot {
let length = self.undo_log.len();
debug!("RegionVarBindings: start_snapshot({})", length);
self.undo_log.borrow_mut().push(OpenSnapshot);
self.undo_log.push(OpenSnapshot);
RegionSnapshot {
length,
region_snapshot: self.unification_table.borrow_mut().snapshot(),
skolemization_count: self.skolemization_count.get(),
region_snapshot: self.unification_table.snapshot(),
skolemization_count: self.skolemization_count,
}
}
pub fn commit(&self, snapshot: RegionSnapshot) {
pub fn commit(&mut self, snapshot: RegionSnapshot) {
debug!("RegionVarBindings: commit({})", snapshot.length);
assert!(self.undo_log.borrow().len() > snapshot.length);
assert!((*self.undo_log.borrow())[snapshot.length] == OpenSnapshot);
assert!(self.undo_log.len() > snapshot.length);
assert!(self.undo_log[snapshot.length] == OpenSnapshot);
assert!(
self.skolemization_count.get() == snapshot.skolemization_count,
self.skolemization_count == snapshot.skolemization_count,
"failed to pop skolemized regions: {} now vs {} at start",
self.skolemization_count.get(),
self.skolemization_count,
snapshot.skolemization_count
);
let mut undo_log = self.undo_log.borrow_mut();
if snapshot.length == 0 {
undo_log.truncate(0);
self.undo_log.truncate(0);
} else {
(*undo_log)[snapshot.length] = CommitedSnapshot;
(*self.undo_log)[snapshot.length] = CommitedSnapshot;
}
self.unification_table
.borrow_mut()
.commit(snapshot.region_snapshot);
}
pub fn rollback_to(&self, snapshot: RegionSnapshot) {
pub fn rollback_to(&mut self, snapshot: RegionSnapshot) {
debug!("RegionVarBindings: rollback_to({:?})", snapshot);
let mut undo_log = self.undo_log.borrow_mut();
assert!(undo_log.len() > snapshot.length);
assert!((*undo_log)[snapshot.length] == OpenSnapshot);
while undo_log.len() > snapshot.length + 1 {
self.rollback_undo_entry(undo_log.pop().unwrap());
assert!(self.undo_log.len() > snapshot.length);
assert!(self.undo_log[snapshot.length] == OpenSnapshot);
while self.undo_log.len() > snapshot.length + 1 {
let undo_entry = self.undo_log.pop().unwrap();
self.rollback_undo_entry(undo_entry);
}
let c = undo_log.pop().unwrap();
let c = self.undo_log.pop().unwrap();
assert!(c == OpenSnapshot);
self.skolemization_count.set(snapshot.skolemization_count);
self.skolemization_count = snapshot.skolemization_count;
self.unification_table
.borrow_mut()
.rollback_to(snapshot.region_snapshot);
}
fn rollback_undo_entry(&self, undo_entry: UndoLogEntry<'tcx>) {
fn rollback_undo_entry(&mut self, undo_entry: UndoLogEntry<'tcx>) {
match undo_entry {
OpenSnapshot => {
panic!("Failure to observe stack discipline");
@ -321,48 +317,46 @@ impl<'tcx> RegionVarBindings<'tcx> {
// nothing to do here
}
AddVar(vid) => {
let mut var_origins = self.var_origins.borrow_mut();
var_origins.pop().unwrap();
assert_eq!(var_origins.len(), vid.index as usize);
self.var_origins.pop().unwrap();
assert_eq!(self.var_origins.len(), vid.index as usize);
}
AddConstraint(ref constraint) => {
self.constraints.borrow_mut().remove(constraint);
self.constraints.remove(constraint);
}
AddVerify(index) => {
self.verifys.borrow_mut().pop();
assert_eq!(self.verifys.borrow().len(), index);
self.verifys.pop();
assert_eq!(self.verifys.len(), index);
}
AddGiven(sub, sup) => {
self.givens.borrow_mut().remove(&(sub, sup));
self.givens.remove(&(sub, sup));
}
AddCombination(Glb, ref regions) => {
self.glbs.borrow_mut().remove(regions);
self.glbs.remove(regions);
}
AddCombination(Lub, ref regions) => {
self.lubs.borrow_mut().remove(regions);
self.lubs.remove(regions);
}
}
}
pub fn num_vars(&self) -> u32 {
let len = self.var_origins.borrow().len();
let len = self.var_origins.len();
// enforce no overflow
assert!(len as u32 as usize == len);
len as u32
}
pub fn new_region_var(&self, origin: RegionVariableOrigin) -> RegionVid {
pub fn new_region_var(&mut self, origin: RegionVariableOrigin) -> RegionVid {
let vid = RegionVid {
index: self.num_vars(),
};
self.var_origins.borrow_mut().push(origin.clone());
self.var_origins.push(origin.clone());
let u_vid = self.unification_table
.borrow_mut()
.new_key(unify_key::RegionVidKey { min_vid: vid });
assert_eq!(vid, u_vid);
if self.in_snapshot() {
self.undo_log.borrow_mut().push(AddVar(vid));
self.undo_log.push(AddVar(vid));
}
debug!(
"created new region variable {:?} with origin {:?}",
@ -373,7 +367,7 @@ impl<'tcx> RegionVarBindings<'tcx> {
}
pub fn var_origin(&self, vid: RegionVid) -> RegionVariableOrigin {
self.var_origins.borrow()[vid.index as usize].clone()
self.var_origins[vid.index as usize].clone()
}
/// Creates a new skolemized region. Skolemized regions are fresh
@ -396,16 +390,16 @@ impl<'tcx> RegionVarBindings<'tcx> {
/// it's just there to make it explicit which snapshot bounds the
/// skolemized region that results. It should always be the top-most snapshot.
pub fn push_skolemized(
&self,
&mut self,
tcx: TyCtxt<'_, '_, 'tcx>,
br: ty::BoundRegion,
snapshot: &RegionSnapshot,
) -> Region<'tcx> {
assert!(self.in_snapshot());
assert!(self.undo_log.borrow()[snapshot.length] == OpenSnapshot);
assert!(self.undo_log[snapshot.length] == OpenSnapshot);
let sc = self.skolemization_count.get();
self.skolemization_count.set(sc + 1);
let sc = self.skolemization_count;
self.skolemization_count = sc + 1;
tcx.mk_region(ReSkolemized(ty::SkolemizedRegionVid { index: sc }, br))
}
@ -414,7 +408,7 @@ impl<'tcx> RegionVarBindings<'tcx> {
/// completes to remove all trace of the skolemized regions
/// created in that time.
pub fn pop_skolemized(
&self,
&mut self,
_tcx: TyCtxt<'_, '_, 'tcx>,
skols: &FxHashSet<ty::Region<'tcx>>,
snapshot: &RegionSnapshot,
@ -422,23 +416,23 @@ impl<'tcx> RegionVarBindings<'tcx> {
debug!("pop_skolemized_regions(skols={:?})", skols);
assert!(self.in_snapshot());
assert!(self.undo_log.borrow()[snapshot.length] == OpenSnapshot);
assert!(self.undo_log[snapshot.length] == OpenSnapshot);
assert!(
self.skolemization_count.get() as usize >= skols.len(),
self.skolemization_count as usize >= skols.len(),
"popping more skolemized variables than actually exist, \
sc now = {}, skols.len = {}",
self.skolemization_count.get(),
self.skolemization_count,
skols.len()
);
let last_to_pop = self.skolemization_count.get();
let last_to_pop = self.skolemization_count;
let first_to_pop = last_to_pop - (skols.len() as u32);
assert!(
first_to_pop >= snapshot.skolemization_count,
"popping more regions than snapshot contains, \
sc now = {}, sc then = {}, skols.len = {}",
self.skolemization_count.get(),
self.skolemization_count,
snapshot.skolemization_count,
skols.len()
);
@ -453,13 +447,11 @@ impl<'tcx> RegionVarBindings<'tcx> {
}),
"invalid skolemization keys or keys out of range ({}..{}): {:?}",
snapshot.skolemization_count,
self.skolemization_count.get(),
self.skolemization_count,
skols
}
let mut undo_log = self.undo_log.borrow_mut();
let constraints_to_kill: Vec<usize> = undo_log
let constraints_to_kill: Vec<usize> = self.undo_log
.iter()
.enumerate()
.rev()
@ -468,11 +460,11 @@ impl<'tcx> RegionVarBindings<'tcx> {
.collect();
for index in constraints_to_kill {
let undo_entry = mem::replace(&mut undo_log[index], Purged);
let undo_entry = mem::replace(&mut self.undo_log[index], Purged);
self.rollback_undo_entry(undo_entry);
}
self.skolemization_count.set(snapshot.skolemization_count);
self.skolemization_count = snapshot.skolemization_count;
return;
fn kill_constraint<'tcx>(
@ -497,7 +489,7 @@ impl<'tcx> RegionVarBindings<'tcx> {
}
pub fn new_bound(
&self,
&mut self,
tcx: TyCtxt<'_, '_, 'tcx>,
debruijn: ty::DebruijnIndex,
) -> Region<'tcx> {
@ -519,35 +511,36 @@ impl<'tcx> RegionVarBindings<'tcx> {
// changing the representation of bound regions in a fn
// declaration
let sc = self.bound_count.get();
self.bound_count.set(sc + 1);
let sc = self.bound_count;
self.bound_count = sc + 1;
if sc >= self.bound_count.get() {
if sc >= self.bound_count {
bug!("rollover in RegionInference new_bound()");
}
tcx.mk_region(ReLateBound(debruijn, BrFresh(sc)))
}
fn add_constraint(&self, constraint: Constraint<'tcx>, origin: SubregionOrigin<'tcx>) {
fn add_constraint(&mut self, constraint: Constraint<'tcx>, origin: SubregionOrigin<'tcx>) {
// cannot add constraints once regions are resolved
debug!("RegionVarBindings: add_constraint({:?})", constraint);
// never overwrite an existing (constraint, origin) - only insert one if it isn't
// present in the map yet. This prevents origins from outside the snapshot being
// replaced with "less informative" origins e.g. during calls to `can_eq`
let in_snapshot = self.in_snapshot();
let undo_log = &mut self.undo_log;
self.constraints
.borrow_mut()
.entry(constraint)
.or_insert_with(|| {
if self.in_snapshot() {
self.undo_log.borrow_mut().push(AddConstraint(constraint));
if in_snapshot {
undo_log.push(AddConstraint(constraint));
}
origin
});
}
fn add_verify(&self, verify: Verify<'tcx>) {
fn add_verify(&mut self, verify: Verify<'tcx>) {
// cannot add verifys once regions are resolved
debug!("RegionVarBindings: add_verify({:?})", verify);
@ -559,26 +552,24 @@ impl<'tcx> RegionVarBindings<'tcx> {
_ => {}
}
let mut verifys = self.verifys.borrow_mut();
let index = verifys.len();
verifys.push(verify);
let index = self.verifys.len();
self.verifys.push(verify);
if self.in_snapshot() {
self.undo_log.borrow_mut().push(AddVerify(index));
self.undo_log.push(AddVerify(index));
}
}
pub fn add_given(&self, sub: Region<'tcx>, sup: ty::RegionVid) {
pub fn add_given(&mut self, sub: Region<'tcx>, sup: ty::RegionVid) {
// cannot add givens once regions are resolved
let mut givens = self.givens.borrow_mut();
if givens.insert((sub, sup)) {
if self.givens.insert((sub, sup)) {
debug!("add_given({:?} <= {:?})", sub, sup);
self.undo_log.borrow_mut().push(AddGiven(sub, sup));
self.undo_log.push(AddGiven(sub, sup));
}
}
pub fn make_eqregion(
&self,
&mut self,
origin: SubregionOrigin<'tcx>,
sub: Region<'tcx>,
sup: Region<'tcx>,
@ -590,13 +581,13 @@ impl<'tcx> RegionVarBindings<'tcx> {
self.make_subregion(origin, sup, sub);
if let (ty::ReVar(sub), ty::ReVar(sup)) = (*sub, *sup) {
self.unification_table.borrow_mut().union(sub, sup);
self.unification_table.union(sub, sup);
}
}
}
pub fn make_subregion(
&self,
&mut self,
origin: SubregionOrigin<'tcx>,
sub: Region<'tcx>,
sup: Region<'tcx>,
@ -638,7 +629,7 @@ impl<'tcx> RegionVarBindings<'tcx> {
/// See `Verify::VerifyGenericBound`
pub fn verify_generic_bound(
&self,
&mut self,
origin: SubregionOrigin<'tcx>,
kind: GenericKind<'tcx>,
sub: Region<'tcx>,
@ -653,7 +644,7 @@ impl<'tcx> RegionVarBindings<'tcx> {
}
pub fn lub_regions(
&self,
&mut self,
tcx: TyCtxt<'_, '_, 'tcx>,
origin: SubregionOrigin<'tcx>,
a: Region<'tcx>,
@ -675,7 +666,7 @@ impl<'tcx> RegionVarBindings<'tcx> {
}
pub fn glb_regions(
&self,
&mut self,
tcx: TyCtxt<'_, '_, 'tcx>,
origin: SubregionOrigin<'tcx>,
a: Region<'tcx>,
@ -697,23 +688,23 @@ impl<'tcx> RegionVarBindings<'tcx> {
}
pub fn opportunistic_resolve_var(
&self,
&mut self,
tcx: TyCtxt<'_, '_, 'tcx>,
rid: RegionVid,
) -> ty::Region<'tcx> {
let vid = self.unification_table.borrow_mut().find_value(rid).min_vid;
let vid = self.unification_table.find_value(rid).min_vid;
tcx.mk_region(ty::ReVar(vid))
}
fn combine_map(&self, t: CombineMapType) -> &RefCell<CombineMap<'tcx>> {
fn combine_map(&mut self, t: CombineMapType) -> &mut CombineMap<'tcx> {
match t {
Glb => &self.glbs,
Lub => &self.lubs,
Glb => &mut self.glbs,
Lub => &mut self.lubs,
}
}
fn combine_vars(
&self,
&mut self,
tcx: TyCtxt<'_, '_, 'tcx>,
t: CombineMapType,
a: Region<'tcx>,
@ -721,13 +712,13 @@ impl<'tcx> RegionVarBindings<'tcx> {
origin: SubregionOrigin<'tcx>,
) -> Region<'tcx> {
let vars = TwoRegions { a: a, b: b };
if let Some(&c) = self.combine_map(t).borrow().get(&vars) {
if let Some(&c) = self.combine_map(t).get(&vars) {
return tcx.mk_region(ReVar(c));
}
let c = self.new_region_var(MiscVariable(origin.span()));
self.combine_map(t).borrow_mut().insert(vars, c);
self.combine_map(t).insert(vars, c);
if self.in_snapshot() {
self.undo_log.borrow_mut().push(AddCombination(t, vars));
self.undo_log.push(AddCombination(t, vars));
}
let new_r = tcx.mk_region(ReVar(c));
for &old_r in &[a, b] {
@ -741,7 +732,7 @@ impl<'tcx> RegionVarBindings<'tcx> {
}
pub fn vars_created_since_snapshot(&self, mark: &RegionSnapshot) -> Vec<RegionVid> {
self.undo_log.borrow()[mark.length..]
self.undo_log[mark.length..]
.iter()
.filter_map(|&elt| match elt {
AddVar(vid) => Some(vid),
@ -778,8 +769,8 @@ impl<'tcx> RegionVarBindings<'tcx> {
let mut taint_set = taint::TaintSet::new(directions, r0);
taint_set.fixed_point(
tcx,
&self.undo_log.borrow()[mark.length..],
&self.verifys.borrow(),
&self.undo_log[mark.length..],
&self.verifys,
);
debug!("tainted: result={:?}", taint_set);
return taint_set.into_set();

View File

@ -74,8 +74,10 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticTypeAndRegionResolv
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
match *r {
ty::ReVar(rid) => self.infcx.region_vars.opportunistic_resolve_var(self.tcx(), rid),
_ => r,
ty::ReVar(rid) =>
self.infcx.region_vars.borrow_mut().opportunistic_resolve_var(self.tcx(), rid),
_ =>
r,
}
}
}

View File

@ -137,7 +137,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
// from the "cause" field, we could perhaps give more tailored
// error messages.
let origin = SubregionOrigin::Subtype(self.fields.trace.clone());
self.fields.infcx.region_vars.make_subregion(origin, a, b);
self.fields.infcx.region_vars.borrow_mut().make_subregion(origin, a, b);
Ok(a)
}