-use crate::infer::type_variable::TypeVariableMap;
-use crate::ty::{self, Ty, TyCtxt};
+use crate::ty::{self, Ty, TyCtxt, TyVid, RegionVid};
use crate::ty::fold::{TypeFoldable, TypeFolder};
use super::InferCtxt;
use super::RegionVariableOrigin;
+use std::ops::Range;
+
impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
/// This rather funky routine is used while processing expected
/// types. What happens here is that we want to propagate a
/// regions in question are not particularly important. We will
/// use the expected types to guide coercions, but we will still
/// type-check the resulting types from those coercions against
- /// the actual types (`?T`, `Option<?T`) -- and remember that
+ /// the actual types (`?T`, `Option<?T>`) -- and remember that
/// after the snapshot is popped, the variable `?T` is no longer
/// unified.
- pub fn fudge_regions_if_ok<T, E, F>(&self,
- origin: &RegionVariableOrigin,
- f: F) -> Result<T, E> where
+ pub fn fudge_regions_if_ok<T, E, F>(
+ &self,
+ origin: &RegionVariableOrigin,
+ f: F,
+ ) -> Result<T, E> where
F: FnOnce() -> Result<T, E>,
T: TypeFoldable<'tcx>,
{
pub struct RegionFudger<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
- type_variables: &'a TypeVariableMap,
- region_vars: &'a Vec<ty::RegionVid>,
+ type_variables: &'a Range<TyVid>,
+ region_vars: &'a Range<RegionVid>,
origin: &'a RegionVariableOrigin,
}
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
match ty.sty {
ty::Infer(ty::InferTy::TyVar(vid)) => {
- match self.type_variables.get(&vid) {
- None => {
- // This variable was created before the
- // "fudging". Since we refresh all type
- // variables to their binding anyhow, we know
- // that it is unbound, so we can just return
- // it.
- debug_assert!(self.infcx.type_variables.borrow_mut()
- .probe(vid)
- .is_unknown());
- ty
- }
-
- Some(&origin) => {
- // This variable was created during the
- // fudging. Recreate it with a fresh variable
- // here.
- self.infcx.next_ty_var(origin)
- }
+ if self.type_variables.contains(&vid) {
+ // This variable was created during the fudging.
+ // Recreate it with a fresh variable here.
+ let origin = self.infcx.type_variables.borrow().var_origin(vid).clone();
+ self.infcx.next_ty_var(origin)
+ } else {
+ // This variable was created before the
+ // "fudging". Since we refresh all type
+ // variables to their binding anyhow, we know
+ // that it is unbound, so we can just return
+ // it.
+ debug_assert!(self.infcx.type_variables.borrow_mut()
+ .probe(vid)
+ .is_unknown());
+ ty
}
}
_ => ty.super_fold_with(self),
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
match *r {
- ty::ReVar(v) if self.region_vars.contains(&v) => {
+ ty::ReVar(vid) if self.region_vars.contains(&vid) => {
self.infcx.next_region_var(self.origin.clone())
}
- _ => {
- r
- }
+ _ => r,
}
}
}
use syntax::symbol::InternedString;
use syntax_pos::Span;
-use crate::ty::{self, Ty};
+use crate::ty::{self, Ty, TyVid};
use std::cmp;
use std::marker::PhantomData;
+use std::ops::Range;
use std::u32;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::snapshot_vec as sv;
use rustc_data_structures::unify as ut;
+use ut::UnifyKey;
pub struct TypeVariableTable<'tcx> {
values: sv::SnapshotVec<Delegate>,
/// Returns a map from the type variables created during the
/// snapshot to the origin of the type variable.
- pub fn vars_since_snapshot(&mut self, s: &Snapshot<'tcx>) -> TypeVariableMap {
- self.values.values_since_snapshot(&s.snapshot).map(|idx| {
- let origin = self.values.get(idx).origin.clone();
- (ty::TyVid { index: idx as u32 }, origin)
- }).collect()
+ pub fn vars_since_snapshot(&mut self, s: &Snapshot<'tcx>) -> Range<TyVid> {
+ let range = self.values.values_since_snapshot(&s.snapshot);
+ TyVid::from_index(range.start as u32)..TyVid::from_index(range.end as u32)
}
/// Finds the set of type variables that existed *before* `s`