have probe() return TypeVariableValue

This commit is contained in:
Niko Matsakis
2017-07-16 10:18:55 -04:00
committed by Sean Griffin
parent ccd92c2a4e
commit 69fe43c97e
5 changed files with 46 additions and 35 deletions
+5 -5
View File
@@ -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 @@ pub fn instantiate(&mut self,
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 @@ fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
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),
+1 -1
View File
@@ -133,7 +133,7 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'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),
+3 -1
View File
@@ -131,7 +131,9 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'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
}
+4 -3
View File
@@ -1259,9 +1259,10 @@ pub fn shallow_resolve(&self, typ: Ty<'tcx>) -> Ty<'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)) => {
+33 -25
View File
@@ -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<Ty<'tcx>> {
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 @@ pub fn var_origin(&self, vid: ty::TyVid) -> &TypeVariableOrigin {
///
/// 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 @@ pub fn equate(&mut self, a: ty::TyVid, b: ty::TyVid) {
///
/// 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 @@ pub fn sub(&mut self, a: ty::TyVid, b: ty::TyVid) {
/// 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 @@ pub fn sub_unified(&mut self, a: ty::TyVid, b: ty::TyVid) -> bool {
/// Retrieves the type to which `vid` has been instantiated, if
/// any.
pub fn probe(&mut self, vid: ty::TyVid) -> Option<Ty<'tcx>> {
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 @@ pub fn replace_if_possible(&mut self, t: Ty<'tcx>) -> Ty<'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 @@ pub fn types_escaping_snapshot(&mut self, snapshot: &Snapshot<'tcx>) -> Vec<Ty<'
// 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 @@ pub fn unsolved_variables(&mut self) -> Vec<ty::TyVid> {
(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()