have probe()
return TypeVariableValue
This commit is contained in:
parent
ccd92c2a4e
commit
69fe43c97e
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)) => {
|
||||
|
@ -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 @@ 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<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 @@ 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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user