Extract more ty
and infer
dependencies from the unification engine
so that it is closer to standalone.
This commit is contained in:
parent
c581840dcc
commit
a6d9930525
5 changed files with 66 additions and 63 deletions
|
@ -436,8 +436,17 @@ pub fn expected_found<'tcx, C, T>(this: &C,
|
|||
a: T,
|
||||
b: T)
|
||||
-> ty::expected_found<T>
|
||||
where C: Combine<'tcx> {
|
||||
if this.a_is_expected() {
|
||||
where C: Combine<'tcx>
|
||||
{
|
||||
expected_found_bool(this.a_is_expected(), a, b)
|
||||
}
|
||||
|
||||
fn expected_found_bool<T>(a_is_expected: bool,
|
||||
a: T,
|
||||
b: T)
|
||||
-> ty::expected_found<T>
|
||||
{
|
||||
if a_is_expected {
|
||||
ty::expected_found {expected: a, found: b}
|
||||
} else {
|
||||
ty::expected_found {expected: b, found: a}
|
||||
|
@ -469,7 +478,8 @@ pub fn super_tys<'tcx, C>(this: &C,
|
|||
(&ty::ty_infer(IntVar(a_id)), &ty::ty_infer(IntVar(b_id))) => {
|
||||
try!(this.infcx().int_unification_table
|
||||
.borrow_mut()
|
||||
.unify_var_var(this.a_is_expected(), a_id, b_id));
|
||||
.unify_var_var(a_id, b_id)
|
||||
.map_err(|e| int_unification_error(this.a_is_expected(), e)));
|
||||
Ok(a)
|
||||
}
|
||||
(&ty::ty_infer(IntVar(v_id)), &ty::ty_int(v)) => {
|
||||
|
@ -489,7 +499,8 @@ pub fn super_tys<'tcx, C>(this: &C,
|
|||
(&ty::ty_infer(FloatVar(a_id)), &ty::ty_infer(FloatVar(b_id))) => {
|
||||
try!(this.infcx().float_unification_table
|
||||
.borrow_mut()
|
||||
.unify_var_var(this.a_is_expected(), a_id, b_id));
|
||||
.unify_var_var(a_id, b_id)
|
||||
.map_err(|e| float_unification_error(this.a_is_expected(), e)));
|
||||
Ok(a)
|
||||
}
|
||||
(&ty::ty_infer(FloatVar(v_id)), &ty::ty_float(v)) => {
|
||||
|
@ -617,9 +628,11 @@ pub fn super_tys<'tcx, C>(this: &C,
|
|||
-> CombineResult<'tcx, Ty<'tcx>>
|
||||
where C: Combine<'tcx>
|
||||
{
|
||||
try!(this.infcx().int_unification_table
|
||||
.borrow_mut()
|
||||
.unify_var_value(vid_is_expected, vid, val));
|
||||
try!(this.infcx()
|
||||
.int_unification_table
|
||||
.borrow_mut()
|
||||
.unify_var_value(vid, val)
|
||||
.map_err(|e| int_unification_error(vid_is_expected, e)));
|
||||
match val {
|
||||
IntType(v) => Ok(ty::mk_mach_int(this.tcx(), v)),
|
||||
UintType(v) => Ok(ty::mk_mach_uint(this.tcx(), v)),
|
||||
|
@ -635,7 +648,8 @@ pub fn super_tys<'tcx, C>(this: &C,
|
|||
{
|
||||
try!(this.infcx().float_unification_table
|
||||
.borrow_mut()
|
||||
.unify_var_value(vid_is_expected, vid, val));
|
||||
.unify_var_value(vid, val)
|
||||
.map_err(|e| float_unification_error(vid_is_expected, e)));
|
||||
Ok(ty::mk_mach_float(this.tcx(), val))
|
||||
}
|
||||
}
|
||||
|
@ -863,3 +877,17 @@ impl<'tcx, T:Clone + PartialEq> CombineResultCompare<'tcx, T> for CombineResult<
|
|||
}
|
||||
}
|
||||
|
||||
fn int_unification_error<'tcx>(a_is_expected: bool, v: (ty::IntVarValue, ty::IntVarValue))
|
||||
-> ty::type_err<'tcx>
|
||||
{
|
||||
let (a, b) = v;
|
||||
ty::terr_int_mismatch(expected_found_bool(a_is_expected, a, b))
|
||||
}
|
||||
|
||||
fn float_unification_error<'tcx>(a_is_expected: bool,
|
||||
v: (ast::FloatTy, ast::FloatTy))
|
||||
-> ty::type_err<'tcx>
|
||||
{
|
||||
let (a, b) = v;
|
||||
ty::terr_float_mismatch(expected_found_bool(a_is_expected, a, b))
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ use middle::ty_fold::TypeFolder;
|
|||
use std::collections::hash_map::{self, Entry};
|
||||
|
||||
use super::InferCtxt;
|
||||
use super::unify::ToType;
|
||||
|
||||
pub struct TypeFreshener<'a, 'tcx:'a> {
|
||||
infcx: &'a InferCtxt<'a, 'tcx>,
|
||||
|
@ -115,14 +116,18 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
|
|||
|
||||
ty::ty_infer(ty::IntVar(v)) => {
|
||||
self.freshen(
|
||||
self.infcx.int_unification_table.borrow_mut().probe(tcx, v),
|
||||
self.infcx.int_unification_table.borrow_mut()
|
||||
.probe(v)
|
||||
.map(|v| v.to_type(tcx)),
|
||||
ty::IntVar(v),
|
||||
ty::FreshIntTy)
|
||||
}
|
||||
|
||||
ty::ty_infer(ty::FloatVar(v)) => {
|
||||
self.freshen(
|
||||
self.infcx.float_unification_table.borrow_mut().probe(tcx, v),
|
||||
self.infcx.float_unification_table.borrow_mut()
|
||||
.probe(v)
|
||||
.map(|v| v.to_type(tcx)),
|
||||
ty::FloatVar(v),
|
||||
ty::FreshIntTy)
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ use self::region_inference::{RegionVarBindings, RegionSnapshot};
|
|||
use self::equate::Equate;
|
||||
use self::sub::Sub;
|
||||
use self::lub::Lub;
|
||||
use self::unify::UnificationTable;
|
||||
use self::unify::{ToType, UnificationTable};
|
||||
use self::error_reporting::ErrorReporting;
|
||||
|
||||
pub mod bivariate;
|
||||
|
@ -885,14 +885,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
ty::ty_infer(ty::IntVar(v)) => {
|
||||
self.int_unification_table
|
||||
.borrow_mut()
|
||||
.probe(self.tcx, v)
|
||||
.probe(v)
|
||||
.map(|v| v.to_type(self.tcx))
|
||||
.unwrap_or(typ)
|
||||
}
|
||||
|
||||
ty::ty_infer(ty::FloatVar(v)) => {
|
||||
self.float_unification_table
|
||||
.borrow_mut()
|
||||
.probe(self.tcx, v)
|
||||
.probe(v)
|
||||
.map(|v| v.to_type(self.tcx))
|
||||
.unwrap_or(typ)
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ use std::marker;
|
|||
|
||||
use middle::ty::{expected_found, IntVarValue};
|
||||
use middle::ty::{self, Ty};
|
||||
use middle::infer::{UnitResult};
|
||||
use std::fmt::Debug;
|
||||
use std::marker::PhantomData;
|
||||
use syntax::ast;
|
||||
|
@ -224,36 +223,15 @@ impl<K:UnifyKey> sv::SnapshotVecDelegate for Delegate<K> {
|
|||
// floats---anything that doesn't have a subtyping relationship we
|
||||
// need to worry about.
|
||||
|
||||
/// Indicates a type that does not have any kind of subtyping
|
||||
/// relationship.
|
||||
pub trait SimplyUnifiable<'tcx> : Clone + PartialEq + Debug {
|
||||
fn to_type(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx>;
|
||||
fn to_type_err(expected_found<Self>) -> ty::type_err<'tcx>;
|
||||
}
|
||||
|
||||
pub fn err<'tcx, V:SimplyUnifiable<'tcx>>(a_is_expected: bool,
|
||||
a_t: V,
|
||||
b_t: V)
|
||||
-> UnitResult<'tcx> {
|
||||
if a_is_expected {
|
||||
Err(SimplyUnifiable::to_type_err(
|
||||
ty::expected_found {expected: a_t, found: b_t}))
|
||||
} else {
|
||||
Err(SimplyUnifiable::to_type_err(
|
||||
ty::expected_found {expected: b_t, found: a_t}))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx,K,V> UnificationTable<K>
|
||||
where K : UnifyKey<Value=Option<V>>,
|
||||
V : SimplyUnifiable<'tcx>,
|
||||
Option<V> : UnifyValue,
|
||||
where K: UnifyKey<Value=Option<V>>,
|
||||
V: Clone+PartialEq,
|
||||
Option<V>: UnifyValue,
|
||||
{
|
||||
pub fn unify_var_var(&mut self,
|
||||
a_is_expected: bool,
|
||||
a_id: K,
|
||||
b_id: K)
|
||||
-> UnitResult<'tcx>
|
||||
-> Result<(),(V,V)>
|
||||
{
|
||||
let node_a = self.get(a_id);
|
||||
let node_b = self.get(b_id);
|
||||
|
@ -268,13 +246,13 @@ impl<'tcx,K,V> UnificationTable<K>
|
|||
None
|
||||
}
|
||||
(&Some(ref v), &None) | (&None, &Some(ref v)) => {
|
||||
Some((*v).clone())
|
||||
Some(v.clone())
|
||||
}
|
||||
(&Some(ref v1), &Some(ref v2)) => {
|
||||
if *v1 != *v2 {
|
||||
return err(a_is_expected, (*v1).clone(), (*v2).clone())
|
||||
return Err((v1.clone(), v2.clone()));
|
||||
}
|
||||
Some((*v1).clone())
|
||||
Some(v1.clone())
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -285,10 +263,9 @@ impl<'tcx,K,V> UnificationTable<K>
|
|||
/// Sets the value of the key `a_id` to `b`. Because simple keys do not have any subtyping
|
||||
/// relationships, if `a_id` already has a value, it must be the same as `b`.
|
||||
pub fn unify_var_value(&mut self,
|
||||
a_is_expected: bool,
|
||||
a_id: K,
|
||||
b: V)
|
||||
-> UnitResult<'tcx>
|
||||
-> Result<(),(V,V)>
|
||||
{
|
||||
let node_a = self.get(a_id);
|
||||
let a_id = node_a.key.clone();
|
||||
|
@ -303,7 +280,7 @@ impl<'tcx,K,V> UnificationTable<K>
|
|||
if *a_t == b {
|
||||
Ok(())
|
||||
} else {
|
||||
err(a_is_expected, (*a_t).clone(), b)
|
||||
Err((a_t.clone(), b))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -313,12 +290,8 @@ impl<'tcx,K,V> UnificationTable<K>
|
|||
self.get(id).value.is_some()
|
||||
}
|
||||
|
||||
pub fn probe(&mut self, tcx: &ty::ctxt<'tcx>, a_id: K) -> Option<Ty<'tcx>> {
|
||||
let node_a = self.get(a_id);
|
||||
match node_a.value {
|
||||
None => None,
|
||||
Some(ref a_t) => Some(a_t.to_type(tcx))
|
||||
}
|
||||
pub fn probe(&mut self, a_id: K) -> Option<V> {
|
||||
self.get(a_id).value.clone()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -326,6 +299,10 @@ impl<'tcx,K,V> UnificationTable<K>
|
|||
|
||||
// Integral type keys
|
||||
|
||||
pub trait ToType<'tcx> {
|
||||
fn to_type(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx>;
|
||||
}
|
||||
|
||||
impl UnifyKey for ty::IntVid {
|
||||
type Value = Option<IntVarValue>;
|
||||
fn index(&self) -> u32 { self.index }
|
||||
|
@ -333,17 +310,13 @@ impl UnifyKey for ty::IntVid {
|
|||
fn tag(_: Option<ty::IntVid>) -> &'static str { "IntVid" }
|
||||
}
|
||||
|
||||
impl<'tcx> SimplyUnifiable<'tcx> for IntVarValue {
|
||||
impl<'tcx> ToType<'tcx> for IntVarValue {
|
||||
fn to_type(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx> {
|
||||
match *self {
|
||||
ty::IntType(i) => ty::mk_mach_int(tcx, i),
|
||||
ty::UintType(i) => ty::mk_mach_uint(tcx, i),
|
||||
}
|
||||
}
|
||||
|
||||
fn to_type_err(err: expected_found<IntVarValue>) -> ty::type_err<'tcx> {
|
||||
return ty::terr_int_mismatch(err);
|
||||
}
|
||||
}
|
||||
|
||||
impl UnifyValue for Option<IntVarValue> { }
|
||||
|
@ -360,12 +333,8 @@ impl UnifyKey for ty::FloatVid {
|
|||
impl UnifyValue for Option<ast::FloatTy> {
|
||||
}
|
||||
|
||||
impl<'tcx> SimplyUnifiable<'tcx> for ast::FloatTy {
|
||||
impl<'tcx> ToType<'tcx> for ast::FloatTy {
|
||||
fn to_type(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx> {
|
||||
ty::mk_mach_float(tcx, *self)
|
||||
}
|
||||
|
||||
fn to_type_err(err: expected_found<ast::FloatTy>) -> ty::type_err<'tcx> {
|
||||
ty::terr_float_mismatch(err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,9 +62,8 @@
|
|||
|
||||
use check::{autoderef, FnCtxt, NoPreference, PreferMutLvalue, UnresolvedTypeAction};
|
||||
|
||||
use middle::infer::{self, CombineResult, Coercion, TypeTrace};
|
||||
use middle::infer::{self, CombineResult, Coercion};
|
||||
use middle::infer::combine::Combine;
|
||||
use middle::infer::sub::Sub;
|
||||
use middle::subst;
|
||||
use middle::ty::{AutoPtr, AutoDerefRef, AdjustDerefRef, AutoUnsize, AutoUnsafe};
|
||||
use middle::ty::{self, mt, Ty};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue