diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs index 959fefbe6b6e..44a848d3cc6e 100644 --- a/src/librustc/infer/combine.rs +++ b/src/librustc/infer/combine.rs @@ -34,10 +34,10 @@ use super::equate::Equate; use super::glb::Glb; +use super::{InferCtxt, MiscVariable, TypeTrace}; use super::lub::Lub; use super::sub::Sub; -use super::InferCtxt; -use super::{MiscVariable, TypeTrace}; +use super::type_variable::TypeVariableValue; use hir::def_id::DefId; use ty::{IntType, UintType}; @@ -194,7 +194,7 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> { use self::RelationDir::*; // Get the actual variable that b_vid has been inferred to - debug_assert!(self.infcx.type_variables.borrow_mut().probe(b_vid).is_none()); + debug_assert!(self.infcx.type_variables.borrow_mut().probe(b_vid).is_unknown()); debug!("instantiate(a_ty={:?} dir={:?} b_vid={:?})", a_ty, dir, b_vid); @@ -403,11 +403,11 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, ' return Err(TypeError::CyclicTy(self.root_ty)); } else { match variables.probe(vid) { - Some(u) => { + TypeVariableValue::Known { value: u } => { drop(variables); self.relate(&u, &u) } - None => { + TypeVariableValue::Unknown { .. } => { match self.ambient_variance { // Invariant: no need to make a fresh type variable. ty::Invariant => return Ok(t), diff --git a/src/librustc/infer/freshen.rs b/src/librustc/infer/freshen.rs index 25300eed548b..ee0921f4b07a 100644 --- a/src/librustc/infer/freshen.rs +++ b/src/librustc/infer/freshen.rs @@ -133,7 +133,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> { match t.sty { ty::TyInfer(ty::TyVar(v)) => { - let opt_ty = self.infcx.type_variables.borrow_mut().probe(v); + let opt_ty = self.infcx.type_variables.borrow_mut().probe(v).known(); self.freshen( opt_ty, ty::TyVar(v), diff --git a/src/librustc/infer/fudge.rs b/src/librustc/infer/fudge.rs index 756a6947ee3f..961dd70a4685 100644 --- a/src/librustc/infer/fudge.rs +++ b/src/librustc/infer/fudge.rs @@ -131,7 +131,9 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionFudger<'a, 'gcx, 'tcx> { // 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_none()); + debug_assert!(self.infcx.type_variables.borrow_mut() + .probe(vid) + .is_unknown()); ty } diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index fa224b575a31..9b856f94c561 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -1259,9 +1259,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // so this recursion should always be of very limited // depth. self.type_variables.borrow_mut() - .probe(v) - .map(|t| self.shallow_resolve(t)) - .unwrap_or(typ) + .probe(v) + .known() + .map(|t| self.shallow_resolve(t)) + .unwrap_or(typ) } ty::TyInfer(ty::IntVar(v)) => { diff --git a/src/librustc/infer/type_variable.rs b/src/librustc/infer/type_variable.rs index 9e98c16c819b..9b9e9fa0015f 100644 --- a/src/librustc/infer/type_variable.rs +++ b/src/librustc/infer/type_variable.rs @@ -78,12 +78,28 @@ struct TypeVariableData { diverging: bool } -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -enum TypeVariableValue<'tcx> { +#[derive(Copy, Clone, Debug)] +pub enum TypeVariableValue<'tcx> { Known { value: Ty<'tcx> }, Unknown, } +impl<'tcx> TypeVariableValue<'tcx> { + pub fn known(&self) -> Option> { + match *self { + TypeVariableValue::Unknown { .. } => None, + TypeVariableValue::Known { value } => Some(value), + } + } + + pub fn is_unknown(&self) -> bool { + match *self { + TypeVariableValue::Unknown { .. } => true, + TypeVariableValue::Known { .. } => false, + } + } +} + pub struct Snapshot<'tcx> { /// number of variables at the time of the snapshot num_vars: usize, @@ -124,8 +140,8 @@ impl<'tcx> TypeVariableTable<'tcx> { /// /// Precondition: neither `a` nor `b` are known. pub fn equate(&mut self, a: ty::TyVid, b: ty::TyVid) { - debug_assert!(self.probe(a).is_none()); - debug_assert!(self.probe(b).is_none()); + debug_assert!(self.probe(a).is_unknown()); + debug_assert!(self.probe(b).is_unknown()); self.eq_relations.union(a, b); self.sub_relations.union(a, b); } @@ -134,8 +150,8 @@ impl<'tcx> TypeVariableTable<'tcx> { /// /// Precondition: neither `a` nor `b` are known. pub fn sub(&mut self, a: ty::TyVid, b: ty::TyVid) { - debug_assert!(self.probe(a).is_none()); - debug_assert!(self.probe(b).is_none()); + debug_assert!(self.probe(a).is_unknown()); + debug_assert!(self.probe(b).is_unknown()); self.sub_relations.union(a, b); } @@ -144,8 +160,8 @@ impl<'tcx> TypeVariableTable<'tcx> { /// Precondition: `vid` must not have been previously instantiated. pub fn instantiate(&mut self, vid: ty::TyVid, ty: Ty<'tcx>) { let vid = self.root_var(vid); - debug_assert!(self.probe(vid).is_none()); - debug_assert!(self.eq_relations.probe_value(vid) == TypeVariableValue::Unknown, + debug_assert!(self.probe(vid).is_unknown()); + debug_assert!(self.eq_relations.probe_value(vid).is_unknown(), "instantiating type variable `{:?}` twice: new-value = {:?}, old-value={:?}", vid, ty, self.eq_relations.probe_value(vid)); self.eq_relations.union_value(vid, TypeVariableValue::Known { value: ty }); @@ -211,12 +227,8 @@ impl<'tcx> TypeVariableTable<'tcx> { /// Retrieves the type to which `vid` has been instantiated, if /// any. - pub fn probe(&mut self, vid: ty::TyVid) -> Option> { - let vid = self.root_var(vid); - match self.eq_relations.probe_value(vid) { - TypeVariableValue::Unknown => None, - TypeVariableValue::Known { value } => Some(value) - } + pub fn probe(&mut self, vid: ty::TyVid) -> TypeVariableValue<'tcx> { + self.eq_relations.probe_value(vid) } /// If `t` is a type-inference variable, and it has been @@ -226,8 +238,8 @@ impl<'tcx> TypeVariableTable<'tcx> { match t.sty { ty::TyInfer(ty::TyVar(v)) => { match self.probe(v) { - None => t, - Some(u) => u + TypeVariableValue::Unknown { .. } => t, + TypeVariableValue::Known { value } => value, } } _ => t, @@ -313,12 +325,9 @@ impl<'tcx> TypeVariableTable<'tcx> { // use the less efficient algorithm for now. let mut escaping_types = Vec::with_capacity(snapshot.num_vars); escaping_types.extend( - (0..snapshot.num_vars) // for all variables that pre-exist the snapshot... + (0..snapshot.num_vars) // for all variables that pre-exist the snapshot, collect.. .map(|i| ty::TyVid { index: i as u32 }) - .filter_map(|vid| match self.eq_relations.probe_value(vid) { - TypeVariableValue::Unknown => None, - TypeVariableValue::Known { value } => Some(value), - })); // ...collect what types they've been instantiated with. + .filter_map(|vid| self.probe(vid).known())); // ..types they are instantiated with. debug!("types_escaping_snapshot = {:?}", escaping_types); escaping_types } @@ -329,10 +338,9 @@ impl<'tcx> TypeVariableTable<'tcx> { (0..self.var_data.len()) .filter_map(|i| { let vid = ty::TyVid { index: i as u32 }; - if self.probe(vid).is_some() { - None - } else { - Some(vid) + match self.probe(vid) { + TypeVariableValue::Unknown { .. } => Some(vid), + TypeVariableValue::Known { .. } => None, } }) .collect()