extract the tcx out from RegionVarBindings

This commit is contained in:
Niko Matsakis 2017-11-05 06:07:22 -05:00
parent daceedf314
commit 63d658d87c
10 changed files with 89 additions and 80 deletions

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(origin, a, b))
Ok(self.fields.infcx.region_vars.glb_regions(self.tcx(), origin, a, b))
}
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)

View file

@ -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(debruijn)
infcx.region_vars.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(&snapshot.region_vars_snapshot, r, directions)
self.region_vars.tainted(self.tcx, &snapshot.region_vars_snapshot, r, directions)
}
fn region_vars_confined_to_snapshot(&self,
@ -581,7 +581,7 @@ 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(br, &snapshot.region_vars_snapshot)
self.region_vars.push_skolemized(self.tcx, br, &snapshot.region_vars_snapshot)
});
debug!("skolemize_bound_regions(binder={:?}, result={:?}, map={:?})",
@ -766,7 +766,7 @@ 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(&skol_regions, &snapshot.region_vars_snapshot);
self.region_vars.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

@ -57,12 +57,13 @@ graphs will be printed. \n\
}
pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>(
region_vars: &RegionVarBindings<'a, 'gcx, 'tcx>,
region_vars: &RegionVarBindings<'tcx>,
region_rels: &RegionRelations<'a, 'gcx, 'tcx>)
{
let tcx = region_rels.tcx;
let context = region_rels.context;
if !region_vars.tcx.sess.opts.debugging_opts.print_region_graph {
if !tcx.sess.opts.debugging_opts.print_region_graph {
return;
}
@ -117,7 +118,7 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>(
Ok(()) => {}
Err(e) => {
let msg = format!("io error dumping region constraints: {}", e);
region_vars.tcx.sess.err(&msg)
tcx.sess.err(&msg)
}
}
}

View file

@ -21,7 +21,7 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::graph::{self, Direction, NodeIndex, OUTGOING};
use std::fmt;
use std::u32;
use ty;
use ty::{self, TyCtxt};
use ty::{Region, RegionVid};
use ty::{ReEarlyBound, ReEmpty, ReErased, ReFree, ReStatic};
use ty::{ReLateBound, ReScope, ReSkolemized, ReVar};
@ -73,7 +73,7 @@ struct RegionAndOrigin<'tcx> {
type RegionGraph<'tcx> = graph::Graph<(), Constraint<'tcx>>;
impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
impl<'tcx> RegionVarBindings<'tcx> {
/// This function performs the actual region resolution. It must be
/// called after all constraints have been added. It performs a
/// fixed-point iteration to find region values which satisfy all
@ -81,7 +81,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
/// errors are reported.
pub fn resolve_regions(
&self,
region_rels: &RegionRelations<'a, 'gcx, 'tcx>,
region_rels: &RegionRelations<'_, '_, 'tcx>,
) -> (
LexicalRegionResolutions<'tcx>,
Vec<RegionResolutionError<'tcx>>,
@ -94,10 +94,11 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
fn lub_concrete_regions(
&self,
region_rels: &RegionRelations<'a, 'gcx, 'tcx>,
region_rels: &RegionRelations<'_, '_, 'tcx>,
a: Region<'tcx>,
b: Region<'tcx>,
) -> Region<'tcx> {
let tcx = region_rels.tcx;
match (a, b) {
(&ReLateBound(..), _) | (_, &ReLateBound(..)) | (&ReErased, _) | (_, &ReErased) => {
bug!("cannot relate region: LUB({:?}, {:?})", a, b);
@ -130,10 +131,10 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
// reasonably compare free regions and scopes:
let fr_scope = match (a, b) {
(&ReEarlyBound(ref br), _) | (_, &ReEarlyBound(ref br)) => {
region_rels.region_scope_tree.early_free_scope(self.tcx, br)
region_rels.region_scope_tree.early_free_scope(region_rels.tcx, br)
}
(&ReFree(ref fr), _) | (_, &ReFree(ref fr)) => {
region_rels.region_scope_tree.free_scope(self.tcx, fr)
region_rels.region_scope_tree.free_scope(region_rels.tcx, fr)
}
_ => bug!(),
};
@ -153,7 +154,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
// otherwise, we don't know what the free region is,
// so we must conservatively say the LUB is static:
self.tcx.types.re_static
tcx.types.re_static
}
(&ReScope(a_id), &ReScope(b_id)) => {
@ -163,7 +164,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
let lub = region_rels
.region_scope_tree
.nearest_common_ancestor(a_id, b_id);
self.tcx.mk_region(ReScope(lub))
tcx.mk_region(ReScope(lub))
}
(&ReEarlyBound(_), &ReEarlyBound(_)) |
@ -176,17 +177,17 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
(&ReSkolemized(..), _) | (_, &ReSkolemized(..)) => if a == b {
a
} else {
self.tcx.types.re_static
tcx.types.re_static
},
}
}
fn infer_variable_values(
&self,
region_rels: &RegionRelations<'a, 'gcx, 'tcx>,
region_rels: &RegionRelations<'_, '_, 'tcx>,
errors: &mut Vec<RegionResolutionError<'tcx>>,
) -> LexicalRegionResolutions<'tcx> {
let mut var_data = self.construct_var_data();
let mut var_data = self.construct_var_data(region_rels.tcx);
// Dorky hack to cause `dump_constraints` to only get called
// if debug mode is enabled:
@ -205,16 +206,18 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
var_data
}
fn construct_var_data(&self) -> LexicalRegionResolutions<'tcx> {
/// Initially, the value for all variables is set to `'empty`, the
/// empty region. The `expansion` phase will grow this larger.
fn construct_var_data(&self, tcx: TyCtxt<'_, '_, 'tcx>) -> LexicalRegionResolutions<'tcx> {
LexicalRegionResolutions {
error_region: self.tcx.types.re_static,
error_region: tcx.types.re_static,
values: (0..self.num_vars() as usize)
.map(|_| VarValue::Value(self.tcx.types.re_empty))
.map(|_| VarValue::Value(tcx.types.re_empty))
.collect(),
}
}
fn dump_constraints(&self, free_regions: &RegionRelations<'a, 'gcx, 'tcx>) {
fn dump_constraints(&self, free_regions: &RegionRelations<'_, '_, 'tcx>) {
debug!(
"----() Start constraint listing (context={:?}) ()----",
free_regions.context
@ -251,7 +254,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
fn expansion(
&self,
region_rels: &RegionRelations<'a, 'gcx, 'tcx>,
region_rels: &RegionRelations<'_, '_, 'tcx>,
var_values: &mut LexicalRegionResolutions<'tcx>,
) {
self.iterate_until_fixed_point("Expansion", |constraint, origin| {
@ -279,7 +282,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
fn expand_node(
&self,
region_rels: &RegionRelations<'a, 'gcx, 'tcx>,
region_rels: &RegionRelations<'_, '_, 'tcx>,
a_region: Region<'tcx>,
b_vid: RegionVid,
b_data: &mut VarValue<'tcx>,
@ -326,7 +329,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
/// and check that they are satisfied.
fn collect_errors(
&self,
region_rels: &RegionRelations<'a, 'gcx, 'tcx>,
region_rels: &RegionRelations<'_, '_, 'tcx>,
var_data: &mut LexicalRegionResolutions<'tcx>,
errors: &mut Vec<RegionResolutionError<'tcx>>,
) {
@ -423,7 +426,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
/// and create a `RegionResolutionError` for each of them.
fn collect_var_errors(
&self,
region_rels: &RegionRelations<'a, 'gcx, 'tcx>,
region_rels: &RegionRelations<'_, '_, 'tcx>,
var_data: &LexicalRegionResolutions<'tcx>,
graph: &RegionGraph<'tcx>,
errors: &mut Vec<RegionResolutionError<'tcx>>,
@ -528,7 +531,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
fn collect_error_for_expanding_node(
&self,
region_rels: &RegionRelations<'a, 'gcx, 'tcx>,
region_rels: &RegionRelations<'_, '_, 'tcx>,
graph: &RegionGraph<'tcx>,
dup_vec: &mut [u32],
node_idx: RegionVid,
@ -642,8 +645,8 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
} = state;
return (result, dup_found);
fn process_edges<'a, 'gcx, 'tcx>(
this: &RegionVarBindings<'a, 'gcx, 'tcx>,
fn process_edges<'tcx>(
this: &RegionVarBindings<'tcx>,
state: &mut WalkState<'tcx>,
graph: &RegionGraph<'tcx>,
source_vid: RegionVid,
@ -710,10 +713,10 @@ impl<'tcx> fmt::Debug for RegionAndOrigin<'tcx> {
}
impl<'a, 'gcx, 'tcx> VerifyBound<'tcx> {
impl<'tcx> VerifyBound<'tcx> {
fn is_met(
&self,
region_rels: &RegionRelations<'a, 'gcx, 'tcx>,
region_rels: &RegionRelations<'_, '_, 'tcx>,
var_values: &LexicalRegionResolutions<'tcx>,
min: ty::Region<'tcx>,
) -> bool {

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(origin, a, b))
Ok(self.fields.infcx.region_vars.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<'a, 'gcx, 'tcx>,
region_vars: 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(tcx),
region_vars: RegionVarBindings::new(),
lexical_region_resolutions: RefCell::new(None),
selection_cache: traits::SelectionCache::new(),
evaluation_cache: traits::EvaluationCache::new(),
@ -1087,10 +1087,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
})
}
pub fn fresh_bound_region(&self, debruijn: ty::DebruijnIndex) -> ty::Region<'tcx> {
self.region_vars.new_bound(debruijn)
}
/// True if errors have been reported since this infcx was
/// created. This is sometimes used as a heuristic to skip
/// reporting errors that often occur as a result of earlier

View file

@ -144,8 +144,7 @@ enum CombineMapType {
type CombineMap<'tcx> = FxHashMap<TwoRegions<'tcx>, RegionVid>;
pub struct RegionVarBindings<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
pub(in infer) tcx: TyCtxt<'a, 'gcx, 'tcx>,
pub struct RegionVarBindings<'tcx> {
pub(in infer) var_origins: RefCell<Vec<RegionVariableOrigin>>,
/// Constraints of the form `A <= B` introduced by the region
@ -244,10 +243,9 @@ impl TaintDirections {
}
}
impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> RegionVarBindings<'a, 'gcx, 'tcx> {
impl<'tcx> RegionVarBindings<'tcx> {
pub fn new() -> RegionVarBindings<'tcx> {
RegionVarBindings {
tcx,
var_origins: RefCell::new(Vec::new()),
constraints: RefCell::new(BTreeMap::new()),
verifys: RefCell::new(Vec::new()),
@ -397,21 +395,30 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
/// The `snapshot` argument to this function is not really used;
/// 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, br: ty::BoundRegion, snapshot: &RegionSnapshot) -> Region<'tcx> {
pub fn push_skolemized(
&self,
tcx: TyCtxt<'_, '_, 'tcx>,
br: ty::BoundRegion,
snapshot: &RegionSnapshot,
) -> Region<'tcx> {
assert!(self.in_snapshot());
assert!(self.undo_log.borrow()[snapshot.length] == OpenSnapshot);
let sc = self.skolemization_count.get();
self.skolemization_count.set(sc + 1);
self.tcx
.mk_region(ReSkolemized(ty::SkolemizedRegionVid { index: sc }, br))
tcx.mk_region(ReSkolemized(ty::SkolemizedRegionVid { index: sc }, br))
}
/// Removes all the edges to/from the skolemized regions that are
/// in `skols`. This is used after a higher-ranked operation
/// completes to remove all trace of the skolemized regions
/// created in that time.
pub fn pop_skolemized(&self, skols: &FxHashSet<ty::Region<'tcx>>, snapshot: &RegionSnapshot) {
pub fn pop_skolemized(
&self,
_tcx: TyCtxt<'_, '_, 'tcx>,
skols: &FxHashSet<ty::Region<'tcx>>,
snapshot: &RegionSnapshot,
) {
debug!("pop_skolemized_regions(skols={:?})", skols);
assert!(self.in_snapshot());
@ -489,7 +496,11 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
}
}
pub fn new_bound(&self, debruijn: ty::DebruijnIndex) -> Region<'tcx> {
pub fn new_bound(
&self,
tcx: TyCtxt<'_, '_, 'tcx>,
debruijn: ty::DebruijnIndex,
) -> Region<'tcx> {
// Creates a fresh bound variable for use in GLB computations.
// See discussion of GLB computation in the large comment at
// the top of this file for more details.
@ -515,7 +526,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
bug!("rollover in RegionInference new_bound()");
}
self.tcx.mk_region(ReLateBound(debruijn, BrFresh(sc)))
tcx.mk_region(ReLateBound(debruijn, BrFresh(sc)))
}
fn add_constraint(&self, constraint: Constraint<'tcx>, origin: SubregionOrigin<'tcx>) {
@ -643,6 +654,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
pub fn lub_regions(
&self,
tcx: TyCtxt<'_, '_, 'tcx>,
origin: SubregionOrigin<'tcx>,
a: Region<'tcx>,
b: Region<'tcx>,
@ -658,18 +670,13 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
a // LUB(a,a) = a
}
_ => self.combine_vars(
Lub,
a,
b,
origin.clone(),
|this, old_r, new_r| this.make_subregion(origin.clone(), old_r, new_r),
),
_ => self.combine_vars(tcx, Lub, a, b, origin.clone()),
}
}
pub fn glb_regions(
&self,
tcx: TyCtxt<'_, '_, 'tcx>,
origin: SubregionOrigin<'tcx>,
a: Region<'tcx>,
b: Region<'tcx>,
@ -685,19 +692,17 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
a // GLB(a,a) = a
}
_ => self.combine_vars(
Glb,
a,
b,
origin.clone(),
|this, old_r, new_r| this.make_subregion(origin.clone(), new_r, old_r),
),
_ => self.combine_vars(tcx, Glb, a, b, origin.clone()),
}
}
pub fn opportunistic_resolve_var(&self, rid: RegionVid) -> ty::Region<'tcx> {
pub fn opportunistic_resolve_var(
&self,
tcx: TyCtxt<'_, '_, 'tcx>,
rid: RegionVid,
) -> ty::Region<'tcx> {
let vid = self.unification_table.borrow_mut().find_value(rid).min_vid;
self.tcx.mk_region(ty::ReVar(vid))
tcx.mk_region(ty::ReVar(vid))
}
fn combine_map(&self, t: CombineMapType) -> &RefCell<CombineMap<'tcx>> {
@ -707,30 +712,32 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
}
}
fn combine_vars<F>(
fn combine_vars(
&self,
tcx: TyCtxt<'_, '_, 'tcx>,
t: CombineMapType,
a: Region<'tcx>,
b: Region<'tcx>,
origin: SubregionOrigin<'tcx>,
mut relate: F,
) -> Region<'tcx>
where
F: FnMut(&RegionVarBindings<'a, 'gcx, 'tcx>, Region<'tcx>, Region<'tcx>),
{
) -> Region<'tcx> {
let vars = TwoRegions { a: a, b: b };
if let Some(&c) = self.combine_map(t).borrow().get(&vars) {
return self.tcx.mk_region(ReVar(c));
return tcx.mk_region(ReVar(c));
}
let c = self.new_region_var(MiscVariable(origin.span()));
self.combine_map(t).borrow_mut().insert(vars, c);
if self.in_snapshot() {
self.undo_log.borrow_mut().push(AddCombination(t, vars));
}
relate(self, a, self.tcx.mk_region(ReVar(c)));
relate(self, b, self.tcx.mk_region(ReVar(c)));
let new_r = tcx.mk_region(ReVar(c));
for &old_r in &[a, b] {
match t {
Glb => self.make_subregion(origin.clone(), new_r, old_r),
Lub => self.make_subregion(origin.clone(), old_r, new_r),
}
}
debug!("combine_vars() c={:?}", c);
self.tcx.mk_region(ReVar(c))
new_r
}
pub fn vars_created_since_snapshot(&self, mark: &RegionSnapshot) -> Vec<RegionVid> {
@ -753,6 +760,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
/// related to other regions.
pub fn tainted(
&self,
tcx: TyCtxt<'_, '_, 'tcx>,
mark: &RegionSnapshot,
r0: Region<'tcx>,
directions: TaintDirections,
@ -769,7 +777,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
// is not a terribly efficient implementation.
let mut taint_set = taint::TaintSet::new(directions, r0);
taint_set.fixed_point(
self.tcx,
tcx,
&self.undo_log.borrow()[mark.length..],
&self.verifys.borrow(),
);

View file

@ -16,7 +16,7 @@ pub(super) struct TaintSet<'tcx> {
regions: FxHashSet<ty::Region<'tcx>>
}
impl<'a, 'gcx, 'tcx> TaintSet<'tcx> {
impl<'tcx> TaintSet<'tcx> {
pub(super) fn new(directions: TaintDirections,
initial_region: ty::Region<'tcx>)
-> Self {
@ -26,7 +26,7 @@ impl<'a, 'gcx, 'tcx> TaintSet<'tcx> {
}
pub(super) fn fixed_point(&mut self,
tcx: TyCtxt<'a, 'gcx, 'tcx>,
tcx: TyCtxt<'_, '_, 'tcx>,
undo_log: &[UndoLogEntry<'tcx>],
verifys: &[Verify<'tcx>]) {
let mut prev_len = 0;

View file

@ -74,7 +74,7 @@ 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(rid),
ty::ReVar(rid) => self.infcx.region_vars.opportunistic_resolve_var(self.tcx(), rid),
_ => r,
}
}

View file

@ -58,6 +58,7 @@
#![feature(slice_patterns)]
#![feature(specialization)]
#![feature(unboxed_closures)]
#![feature(underscore_lifetimes)]
#![feature(trace_macros)]
#![feature(test)]
#![feature(const_atomic_bool_new)]