drop(variables);
self.relate(&u, &u)
}
- TypeVariableValue::Unknown { .. } => {
+ TypeVariableValue::Unknown { universe } => {
match self.ambient_variance {
// Invariant: no need to make a fresh type variable.
ty::Invariant => return Ok(t),
}
let origin = *variables.var_origin(vid);
- let new_var_id = variables.new_var(false, origin);
+ let new_var_id = variables.new_var(universe, false, origin);
let u = self.tcx().mk_var(new_var_id);
debug!("generalize: replacing original vid={:?} with new={:?}",
vid, u);
// Second, we instantiate each bound region in the supertype with a
// fresh concrete region.
let (b_prime, skol_map) =
- self.infcx.skolemize_late_bound_regions(b, snapshot);
+ self.infcx.skolemize_late_bound_regions(b);
debug!("a_prime={:?}", a_prime);
debug!("b_prime={:?}", b_prime);
// First, we instantiate each bound region in the matcher
// with a skolemized region.
let ((a_match, a_value), skol_map) =
- self.infcx.skolemize_late_bound_regions(a_pair, snapshot);
+ self.infcx.skolemize_late_bound_regions(a_pair);
debug!("higher_ranked_match: a_match={:?}", a_match);
debug!("higher_ranked_match: skol_map={:?}", skol_map);
///
/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-hrtb.html
pub fn skolemize_late_bound_regions<T>(&self,
- binder: &ty::Binder<T>,
- snapshot: &CombinedSnapshot<'a, 'tcx>)
+ binder: &ty::Binder<T>)
-> (T, SkolemizationMap<'tcx>)
where T : TypeFoldable<'tcx>
{
let (result, map) = self.tcx.replace_late_bound_regions(binder, |br| {
- self.borrow_region_constraints()
- .push_skolemized(self.tcx, br, &snapshot.region_constraints_snapshot)
+ self.universe.set(self.universe().subuniverse());
+ self.tcx.mk_region(ty::ReSkolemized(self.universe(), br))
});
debug!("skolemize_bound_regions(binder={:?}, result={:?}, map={:?})",
debug!("pop_skolemized({:?})", skol_map);
let skol_regions: FxHashSet<_> = skol_map.values().cloned().collect();
self.borrow_region_constraints()
- .pop_skolemized(self.tcx, &skol_regions, &snapshot.region_constraints_snapshot);
+ .pop_skolemized(self.universe(), &skol_regions, &snapshot.region_constraints_snapshot);
+ self.universe.set(snapshot.universe);
if !skol_map.is_empty() {
self.projection_cache.borrow_mut().rollback_skolemized(
&snapshot.projection_cache_snapshot);
use infer::region_constraints::Constraint;
use infer::region_constraints::GenericKind;
use infer::region_constraints::RegionConstraintData;
-use infer::region_constraints::VarOrigins;
+use infer::region_constraints::VarInfos;
use infer::region_constraints::VerifyBound;
use middle::free_region::RegionRelations;
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
/// all the variables as well as a set of errors that must be reported.
pub fn resolve<'tcx>(
region_rels: &RegionRelations<'_, '_, 'tcx>,
- var_origins: VarOrigins,
+ var_infos: VarInfos,
data: RegionConstraintData<'tcx>,
) -> (
LexicalRegionResolutions<'tcx>,
let mut errors = vec![];
let mut resolver = LexicalResolver {
region_rels,
- var_origins,
+ var_infos,
data,
};
let values = resolver.infer_variable_values(&mut errors);
struct LexicalResolver<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
region_rels: &'cx RegionRelations<'cx, 'gcx, 'tcx>,
- var_origins: VarOrigins,
+ var_infos: VarInfos,
data: RegionConstraintData<'tcx>,
}
}
fn num_vars(&self) -> usize {
- self.var_origins.len()
+ self.var_infos.len()
}
/// Initially, the value for all variables is set to `'empty`, the
(&ReVar(v_id), _) | (_, &ReVar(v_id)) => {
span_bug!(
- self.var_origins[v_id].span(),
+ self.var_infos[v_id].origin.span(),
"lub_concrete_regions invoked with non-concrete \
regions: {:?}, {:?}",
a,
if !self.region_rels
.is_subregion_of(lower_bound.region, upper_bound.region)
{
- let origin = self.var_origins[node_idx].clone();
+ let origin = self.var_infos[node_idx].origin.clone();
debug!(
"region inference error at {:?} for {:?}: SubSupConflict sub: {:?} \
sup: {:?}",
}
span_bug!(
- self.var_origins[node_idx].span(),
+ self.var_infos[node_idx].origin.span(),
"collect_error_for_expanding_node() could not find \
error for var {:?}, lower_bounds={:?}, \
upper_bounds={:?}",
use self::combine::CombineFields;
use self::higher_ranked::HrMatchResult;
use self::region_constraints::{RegionConstraintCollector, RegionSnapshot};
-use self::region_constraints::{GenericKind, VerifyBound, RegionConstraintData, VarOrigins};
+use self::region_constraints::{GenericKind, VerifyBound, RegionConstraintData, VarInfos};
use self::lexical_region_resolve::LexicalRegionResolutions;
use self::outlives::env::OutlivesEnvironment;
use self::type_variable::TypeVariableOrigin;
// obligations within. This is expected to be done 'late enough'
// that all type inference variables have been bound and so forth.
pub region_obligations: RefCell<Vec<(ast::NodeId, RegionObligation<'tcx>)>>,
+
+ /// What is the innermost universe we have created? Starts out as
+ /// `UniverseIndex::root()` but grows from there as we enter
+ /// universal quantifiers.
+ ///
+ /// NB: At present, we exclude the universal quantifiers on the
+ /// item we are type-checking, and just consider those names as
+ /// part of the root universe. So this would only get incremented
+ /// when we enter into a higher-ranked (`for<..>`) type or trait
+ /// bound.
+ universe: Cell<ty::UniverseIndex>,
}
/// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
err_count_on_creation: tcx.sess.err_count(),
in_snapshot: Cell::new(false),
region_obligations: RefCell::new(vec![]),
+ universe: Cell::new(ty::UniverseIndex::ROOT),
}))
}
}
float_snapshot: ut::Snapshot<ut::InPlace<ty::FloatVid>>,
region_constraints_snapshot: RegionSnapshot,
region_obligations_snapshot: usize,
+ universe: ty::UniverseIndex,
was_in_snapshot: bool,
_in_progress_tables: Option<Ref<'a, ty::TypeckTables<'tcx>>>,
}
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(),
+ universe: self.universe(),
was_in_snapshot: in_snapshot,
// Borrow tables "in progress" (i.e. during typeck)
// to ban writes from within a snapshot to them.
float_snapshot,
region_constraints_snapshot,
region_obligations_snapshot,
+ universe,
was_in_snapshot,
_in_progress_tables } = snapshot;
self.in_snapshot.set(was_in_snapshot);
+ self.universe.set(universe);
self.projection_cache
.borrow_mut()
float_snapshot,
region_constraints_snapshot,
region_obligations_snapshot: _,
+ universe: _,
was_in_snapshot,
_in_progress_tables } = snapshot;
Some(self.commit_if_ok(|snapshot| {
let (ty::SubtypePredicate { a_is_expected, a, b}, skol_map) =
- self.skolemize_late_bound_regions(predicate, snapshot);
+ self.skolemize_late_bound_regions(predicate);
let cause_span = cause.span;
let ok = self.at(cause, param_env).sub_exp(a_is_expected, a, b)?;
{
self.commit_if_ok(|snapshot| {
let (ty::OutlivesPredicate(r_a, r_b), skol_map) =
- self.skolemize_late_bound_regions(predicate, snapshot);
+ self.skolemize_late_bound_regions(predicate);
let origin =
SubregionOrigin::from_obligation_cause(cause,
|| RelateRegionParamBound(cause.span));
pub fn next_ty_var_id(&self, diverging: bool, origin: TypeVariableOrigin) -> TyVid {
self.type_variables
.borrow_mut()
- .new_var(diverging, origin)
+ .new_var(self.universe(), diverging, origin)
}
pub fn next_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> {
/// during diagnostics / error-reporting.
pub fn next_region_var(&self, origin: RegionVariableOrigin)
-> ty::Region<'tcx> {
- self.tcx.mk_region(ty::ReVar(self.borrow_region_constraints().new_region_var(origin)))
+ let region_var = self.borrow_region_constraints()
+ .new_region_var(self.universe(), origin);
+ self.tcx.mk_region(ty::ReVar(region_var))
}
/// Number of region variables created so far.
pub fn num_region_vars(&self) -> usize {
- self.borrow_region_constraints().var_origins().len()
+ self.borrow_region_constraints().num_region_vars()
}
/// Just a convenient wrapper of `next_region_var` for using during NLL.
-> Ty<'tcx> {
let ty_var_id = self.type_variables
.borrow_mut()
- .new_var(false,
+ .new_var(self.universe(),
+ false,
TypeVariableOrigin::TypeParameterDefinition(span, def.name));
self.tcx.mk_var(ty_var_id)
region_context,
region_map,
outlives_env.free_region_map());
- let (var_origins, data) = self.region_constraints.borrow_mut()
+ let (var_infos, data) = self.region_constraints.borrow_mut()
.take()
.expect("regions already resolved")
- .into_origins_and_data();
+ .into_infos_and_data();
let (lexical_region_resolutions, errors) =
- lexical_region_resolve::resolve(region_rels, var_origins, data);
+ lexical_region_resolve::resolve(region_rels, var_infos, data);
let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions));
assert!(old_value.is_none());
/// hence that `resolve_regions_and_report_errors` can never be
/// called. This is used only during NLL processing to "hand off" ownership
/// of the set of region vairables into the NLL region context.
- pub fn take_region_var_origins(&self) -> VarOrigins {
- let (var_origins, data) = self.region_constraints.borrow_mut()
+ pub fn take_region_var_origins(&self) -> VarInfos {
+ let (var_infos, data) = self.region_constraints.borrow_mut()
.take()
.expect("regions already resolved")
- .into_origins_and_data();
+ .into_infos_and_data();
assert!(data.is_empty());
- var_origins
+ var_infos
}
pub fn ty_to_string(&self, t: Ty<'tcx>) -> String {
self.evaluation_cache.clear();
self.projection_cache.borrow_mut().clear();
}
+
+ fn universe(&self) -> ty::UniverseIndex {
+ self.universe.get()
+ }
}
impl<'a, 'gcx, 'tcx> TypeTrace<'tcx> {
use ty::{self, Ty, TyCtxt};
use ty::{Region, RegionVid};
use ty::ReStatic;
-use ty::{BrFresh, ReLateBound, ReSkolemized, ReVar};
+use ty::{BrFresh, ReLateBound, ReVar};
use std::collections::BTreeMap;
-use std::fmt;
-use std::mem;
-use std::u32;
+use std::{cmp, fmt, mem, u32};
mod taint;
pub struct RegionConstraintCollector<'tcx> {
/// For each `RegionVid`, the corresponding `RegionVariableOrigin`.
- var_origins: IndexVec<RegionVid, RegionVariableOrigin>,
+ var_infos: IndexVec<RegionVid, RegionVariableInfo>,
data: RegionConstraintData<'tcx>,
/// exist). This prevents us from making many such regions.
glbs: CombineMap<'tcx>,
- /// Number of skolemized variables currently active.
- skolemization_count: u32,
-
/// Global counter used during the GLB algorithm to create unique
/// names for fresh bound regions
bound_count: u32,
unification_table: ut::UnificationTable<ut::InPlace<ty::RegionVid>>,
}
-pub type VarOrigins = IndexVec<RegionVid, RegionVariableOrigin>;
+pub type VarInfos = IndexVec<RegionVid, RegionVariableInfo>;
/// The full set of region constraints gathered up by the collector.
/// Describes constraints between the region variables and other
type CombineMap<'tcx> = FxHashMap<TwoRegions<'tcx>, RegionVid>;
+#[derive(Debug, Clone, Copy)]
+pub struct RegionVariableInfo {
+ pub origin: RegionVariableOrigin,
+ pub universe: ty::UniverseIndex,
+}
+
pub struct RegionSnapshot {
length: usize,
region_snapshot: ut::Snapshot<ut::InPlace<ty::RegionVid>>,
- skolemization_count: u32,
}
/// When working with skolemized regions, we often wish to find all of
impl<'tcx> RegionConstraintCollector<'tcx> {
pub fn new() -> RegionConstraintCollector<'tcx> {
RegionConstraintCollector {
- var_origins: VarOrigins::default(),
+ var_infos: VarInfos::default(),
data: RegionConstraintData::default(),
lubs: FxHashMap(),
glbs: FxHashMap(),
- skolemization_count: 0,
bound_count: 0,
undo_log: Vec::new(),
unification_table: ut::UnificationTable::new(),
}
}
- pub fn var_origins(&self) -> &VarOrigins {
- &self.var_origins
+ pub fn num_region_vars(&self) -> usize {
+ self.var_infos.len()
}
pub fn region_constraint_data(&self) -> &RegionConstraintData<'tcx> {
/// Once all the constraints have been gathered, extract out the final data.
///
/// Not legal during a snapshot.
- pub fn into_origins_and_data(self) -> (VarOrigins, RegionConstraintData<'tcx>) {
+ pub fn into_infos_and_data(self) -> (VarInfos, RegionConstraintData<'tcx>) {
assert!(!self.in_snapshot());
- (self.var_origins, self.data)
+ (self.var_infos, self.data)
}
/// Takes (and clears) the current set of constraints. Note that
// should think carefully about whether it needs to be cleared
// or updated in some way.
let RegionConstraintCollector {
- var_origins,
+ var_infos,
data,
lubs,
glbs,
- skolemization_count,
bound_count: _,
undo_log: _,
unification_table,
} = self;
- assert_eq!(*skolemization_count, 0);
-
// Clear the tables of (lubs, glbs), so that we will create
// fresh regions if we do a LUB operation. As it happens,
// LUB/GLB are not performed by the MIR type-checker, which is
// also insert `a <= b` and a `b <= a` edges, so the
// `RegionConstraintData` contains the relationship here.
*unification_table = ut::UnificationTable::new();
- for vid in var_origins.indices() {
+ for vid in var_infos.indices() {
unification_table.new_key(unify_key::RegionVidKey { min_vid: vid });
}
RegionSnapshot {
length,
region_snapshot: self.unification_table.snapshot(),
- skolemization_count: self.skolemization_count,
}
}
debug!("RegionConstraintCollector: commit({})", snapshot.length);
assert!(self.undo_log.len() > snapshot.length);
assert!(self.undo_log[snapshot.length] == OpenSnapshot);
- assert!(
- self.skolemization_count == snapshot.skolemization_count,
- "failed to pop skolemized regions: {} now vs {} at start",
- self.skolemization_count,
- snapshot.skolemization_count
- );
if snapshot.length == 0 {
self.undo_log.truncate(0);
}
let c = self.undo_log.pop().unwrap();
assert!(c == OpenSnapshot);
- self.skolemization_count = snapshot.skolemization_count;
self.unification_table.rollback_to(snapshot.region_snapshot);
}
// nothing to do here
}
AddVar(vid) => {
- self.var_origins.pop().unwrap();
- assert_eq!(self.var_origins.len(), vid.index() as usize);
+ self.var_infos.pop().unwrap();
+ assert_eq!(self.var_infos.len(), vid.index() as usize);
}
AddConstraint(ref constraint) => {
self.data.constraints.remove(constraint);
}
}
- pub fn new_region_var(&mut self, origin: RegionVariableOrigin) -> RegionVid {
- let vid = self.var_origins.push(origin.clone());
+ pub fn new_region_var(&mut self,
+ universe: ty::UniverseIndex,
+ origin: RegionVariableOrigin) -> RegionVid {
+ let vid = self.var_infos.push(RegionVariableInfo {
+ origin,
+ universe,
+ });
let u_vid = self.unification_table
.new_key(unify_key::RegionVidKey { min_vid: vid });
return vid;
}
- /// Returns the origin for the given variable.
- pub fn var_origin(&self, vid: RegionVid) -> RegionVariableOrigin {
- self.var_origins[vid].clone()
+ /// Returns the universe for the given variable.
+ pub fn var_universe(&self, vid: RegionVid) -> ty::UniverseIndex {
+ self.var_infos[vid].universe
}
- /// Creates a new skolemized region. Skolemized regions are fresh
- /// regions used when performing higher-ranked computations. They
- /// must be used in a very particular way and are never supposed
- /// to "escape" out into error messages or the code at large.
- ///
- /// The idea is to always create a snapshot. Skolemized regions
- /// can be created in the context of this snapshot, but before the
- /// snapshot is committed or rolled back, they must be popped
- /// (using `pop_skolemized_regions`), so that their numbers can be
- /// recycled. Normally you don't have to think about this: you use
- /// the APIs in `higher_ranked/mod.rs`, such as
- /// `skolemize_late_bound_regions` and `plug_leaks`, which will
- /// guide you on this path (ensure that the `SkolemizationMap` is
- /// consumed and you are good). For more info on how skolemization
- /// for HRTBs works, see the [rustc guide].
- ///
- /// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-hrtb.html
- ///
- /// 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(
- &mut self,
- tcx: TyCtxt<'_, '_, 'tcx>,
- br: ty::BoundRegion,
- snapshot: &RegionSnapshot,
- ) -> Region<'tcx> {
- assert!(self.in_snapshot());
- assert!(self.undo_log[snapshot.length] == OpenSnapshot);
-
- let sc = self.skolemization_count;
- self.skolemization_count = sc + 1;
- tcx.mk_region(ReSkolemized(ty::SkolemizedRegionVid { index: sc }, br))
+ /// Returns the origin for the given variable.
+ pub fn var_origin(&self, vid: RegionVid) -> RegionVariableOrigin {
+ self.var_infos[vid].origin
}
/// Removes all the edges to/from the skolemized regions that are
/// created in that time.
pub fn pop_skolemized(
&mut self,
- _tcx: TyCtxt<'_, '_, 'tcx>,
+ skolemization_count: ty::UniverseIndex,
skols: &FxHashSet<ty::Region<'tcx>>,
snapshot: &RegionSnapshot,
) {
assert!(self.in_snapshot());
assert!(self.undo_log[snapshot.length] == OpenSnapshot);
assert!(
- self.skolemization_count as usize >= skols.len(),
+ skolemization_count.as_usize() >= skols.len(),
"popping more skolemized variables than actually exist, \
- sc now = {}, skols.len = {}",
- self.skolemization_count,
+ sc now = {:?}, skols.len = {:?}",
+ skolemization_count,
skols.len()
);
- let last_to_pop = self.skolemization_count;
- let first_to_pop = last_to_pop - (skols.len() as u32);
+ let last_to_pop = skolemization_count.subuniverse();
+ let first_to_pop = ty::UniverseIndex::from(last_to_pop.as_u32() - 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,
- snapshot.skolemization_count,
- skols.len()
- );
debug_assert! {
skols.iter()
.all(|&k| match *k {
- ty::ReSkolemized(index, _) =>
- index.index >= first_to_pop &&
- index.index < last_to_pop,
+ ty::ReSkolemized(universe, _) =>
+ universe >= first_to_pop &&
+ universe < last_to_pop,
_ =>
false
}),
- "invalid skolemization keys or keys out of range ({}..{}): {:?}",
- snapshot.skolemization_count,
- self.skolemization_count,
+ "invalid skolemization keys or keys out of range ({:?}..{:?}): {:?}",
+ first_to_pop,
+ last_to_pop,
skols
}
self.rollback_undo_entry(undo_entry);
}
- self.skolemization_count = snapshot.skolemization_count;
return;
fn kill_constraint<'tcx>(
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()));
+ let a_universe = self.universe(a);
+ let b_universe = self.universe(b);
+ let c_universe = cmp::max(a_universe, b_universe);
+ let c = self.new_region_var(c_universe, MiscVariable(origin.span()));
self.combine_map(t).insert(vars, c);
if self.in_snapshot() {
self.undo_log.push(AddCombination(t, vars));
new_r
}
+ fn universe(&self, region: Region<'tcx>) -> ty::UniverseIndex {
+ match *region {
+ ty::ReScope(..) |
+ ty::ReStatic |
+ ty::ReEmpty |
+ ty::ReErased |
+ ty::ReFree(..) |
+ ty::ReEarlyBound(..) => ty::UniverseIndex::ROOT,
+ ty::ReSkolemized(universe, _) => universe,
+ ty::ReClosureBound(vid) |
+ ty::ReVar(vid) => self.var_universe(vid),
+ ty::ReLateBound(..) =>
+ bug!("universe(): encountered bound region {:?}", region),
+ ty::ReCanonical(..) =>
+ bug!("region_universe(): encountered canonical region {:?}", region),
+ }
+ }
+
pub fn vars_created_since_snapshot(&self, mark: &RegionSnapshot) -> Vec<RegionVid> {
self.undo_log[mark.length..]
.iter()
impl fmt::Debug for RegionSnapshot {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(
- f,
- "RegionSnapshot(length={},skolemization={})",
- self.length,
- self.skolemization_count
- )
+ write!(f, "RegionSnapshot(length={})", self.length)
}
}
#[derive(Copy, Clone, Debug)]
pub enum TypeVariableValue<'tcx> {
Known { value: Ty<'tcx> },
- Unknown,
+ Unknown { universe: ty::UniverseIndex },
}
impl<'tcx> TypeVariableValue<'tcx> {
+ /// If this value is known, returns the type it is known to be.
+ /// Otherwise, `None`.
pub fn known(&self) -> Option<Ty<'tcx>> {
match *self {
TypeVariableValue::Unknown { .. } => None,
/// The code in this module doesn't care, but it can be useful
/// for improving error messages.
pub fn new_var(&mut self,
+ universe: ty::UniverseIndex,
diverging: bool,
origin: TypeVariableOrigin)
-> ty::TyVid {
- let eq_key = self.eq_relations.new_key(TypeVariableValue::Unknown);
+ let eq_key = self.eq_relations.new_key(TypeVariableValue::Unknown { universe });
let sub_key = self.sub_relations.new_key(());
assert_eq!(eq_key.vid, sub_key);
(&TypeVariableValue::Unknown { .. }, &TypeVariableValue::Known { .. }) => Ok(*value2),
// If both sides are *unknown*, it hardly matters, does it?
- (&TypeVariableValue::Unknown, &TypeVariableValue::Unknown) => Ok(*value1),
+ (&TypeVariableValue::Unknown { universe: universe1 },
+ &TypeVariableValue::Unknown { universe: universe2 }) => {
+ // If we unify two unbound variables, ?T and ?U, then whatever
+ // value they wind up taking (which must be the same value) must
+ // be nameable by both universes. Therefore, the resulting
+ // universe is the minimum of the two universes, because that is
+ // the one which contains the fewest names in scope.
+ let universe = cmp::min(universe1, universe2);
+ Ok(TypeVariableValue::Unknown { universe })
+ }
}
}
}
let infcx = selcx.infcx();
infcx.commit_if_ok(|snapshot| {
let (skol_predicate, skol_map) =
- infcx.skolemize_late_bound_regions(&obligation.predicate, snapshot);
+ infcx.skolemize_late_bound_regions(&obligation.predicate);
let skol_obligation = obligation.with(skol_predicate);
let r = match project_and_unify_type(selcx, &skol_obligation) {
let poly_trait_predicate =
self.infcx().resolve_type_vars_if_possible(&obligation.predicate);
let (skol_trait_predicate, skol_map) =
- self.infcx().skolemize_late_bound_regions(&poly_trait_predicate, snapshot);
+ self.infcx().skolemize_late_bound_regions(&poly_trait_predicate);
debug!("match_projection_obligation_against_definition_bounds: \
skol_trait_predicate={:?} skol_map={:?}",
skol_trait_predicate,
self.in_snapshot(|this, snapshot| {
let (skol_ty, skol_map) =
- this.infcx().skolemize_late_bound_regions(&ty, snapshot);
+ this.infcx().skolemize_late_bound_regions(&ty);
let Normalized { value: normalized_ty, mut obligations } =
project::normalize_with_depth(this,
param_env,
let trait_obligations = self.in_snapshot(|this, snapshot| {
let poly_trait_ref = obligation.predicate.to_poly_trait_ref();
let (trait_ref, skol_map) =
- this.infcx().skolemize_late_bound_regions(&poly_trait_ref, snapshot);
+ this.infcx().skolemize_late_bound_regions(&poly_trait_ref);
let cause = obligation.derived_cause(ImplDerivedObligation);
this.impl_or_trait_obligations(cause,
obligation.recursion_depth + 1,
}
let (skol_obligation, skol_map) = self.infcx().skolemize_late_bound_regions(
- &obligation.predicate,
- snapshot);
+ &obligation.predicate);
let skol_obligation_trait_ref = skol_obligation.trait_ref;
let impl_substs = self.infcx.fresh_substs_for_item(obligation.cause.span,
pub use self::sty::{ExistentialProjection, PolyExistentialProjection, Const};
pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region};
pub use self::sty::RegionKind;
-pub use self::sty::{TyVid, IntVid, FloatVid, RegionVid, SkolemizedRegionVid};
+pub use self::sty::{TyVid, IntVid, FloatVid, RegionVid};
pub use self::sty::BoundRegion::*;
pub use self::sty::InferTy::*;
pub use self::sty::RegionKind::*;
/// type name in a non-zero universe is a skolemized type -- an
/// idealized representative of "types in general" that we use for
/// checking generic functions.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub struct UniverseIndex(u32);
impl UniverseIndex {
/// The root universe, where things that the user defined are
/// visible.
- pub fn root() -> UniverseIndex {
- UniverseIndex(0)
- }
+ pub const ROOT: Self = UniverseIndex(0);
/// A "subuniverse" corresponds to being inside a `forall` quantifier.
/// So, for example, suppose we have this type in universe `U`:
/// region `'a`, but that region was not nameable from `U` because
/// it was not in scope there.
pub fn subuniverse(self) -> UniverseIndex {
- UniverseIndex(self.0 + 1)
+ UniverseIndex(self.0.checked_add(1).unwrap())
+ }
+
+ pub fn as_u32(&self) -> u32 {
+ self.0
+ }
+
+ pub fn as_usize(&self) -> usize {
+ self.0 as usize
+ }
+}
+
+impl From<u32> for UniverseIndex {
+ fn from(index: u32) -> Self {
+ UniverseIndex(index)
}
}
/// A skolemized region - basically the higher-ranked version of ReFree.
/// Should not exist after typeck.
- ReSkolemized(SkolemizedRegionVid, BoundRegion),
+ ReSkolemized(ty::UniverseIndex, BoundRegion),
/// Empty lifetime is for data that is never accessed.
/// Bottom in the region lattice. We treat ReEmpty somewhat
DEBUG_FORMAT = custom,
});
-#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, PartialOrd, Ord)]
-pub struct SkolemizedRegionVid {
- pub index: u32,
-}
-
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum InferTy {
TyVar(TyVid),
write!(f, "'?{}", c.index())
}
- ty::ReSkolemized(id, ref bound_region) => {
- write!(f, "ReSkolemized({}, {:?})", id.index, bound_region)
+ ty::ReSkolemized(universe, ref bound_region) => {
+ write!(f, "ReSkolemized({:?}, {:?})", universe, bound_region)
}
ty::ReEmpty => write!(f, "ReEmpty"),
use rustc::infer::RegionVariableOrigin;
use rustc::infer::SubregionOrigin;
use rustc::infer::error_reporting::nice_region_error::NiceRegionError;
-use rustc::infer::region_constraints::{GenericKind, VarOrigins};
+use rustc::infer::region_constraints::{GenericKind, VarInfos};
use rustc::mir::{ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureRegionRequirements,
Local, Location, Mir};
use rustc::traits::ObligationCause;
/// of those will be constant regions representing the free
/// regions defined in `universal_regions`.
pub(crate) fn new(
- var_origins: VarOrigins,
+ var_infos: VarInfos,
universal_regions: UniversalRegions<'tcx>,
mir: &Mir<'tcx>,
) -> Self {
- let num_region_variables = var_origins.len();
+ let num_region_variables = var_infos.len();
let num_universal_regions = universal_regions.len();
let elements = &Rc::new(RegionValueElements::new(mir, num_universal_regions));
// Create a RegionDefinition for each inference variable.
- let definitions = var_origins
+ let definitions = var_infos
.into_iter()
- .map(|origin| RegionDefinition::new(origin))
+ .map(|info| RegionDefinition::new(info.origin))
.collect();
let mut result = Self {