about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/middle/infer/combine.rs44
-rw-r--r--src/librustc/middle/infer/freshen.rs9
-rw-r--r--src/librustc/middle/infer/mod.rs8
-rw-r--r--src/librustc/middle/infer/unify.rs65
-rw-r--r--src/librustc_typeck/check/coercion.rs3
5 files changed, 66 insertions, 63 deletions
diff --git a/src/librustc/middle/infer/combine.rs b/src/librustc/middle/infer/combine.rs
index b3f4537f472..fdff750bf46 100644
--- a/src/librustc/middle/infer/combine.rs
+++ b/src/librustc/middle/infer/combine.rs
@@ -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))
+}
diff --git a/src/librustc/middle/infer/freshen.rs b/src/librustc/middle/infer/freshen.rs
index 39a0a276b28..29f74d12ea3 100644
--- a/src/librustc/middle/infer/freshen.rs
+++ b/src/librustc/middle/infer/freshen.rs
@@ -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)
             }
diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs
index 15c30847031..7e9c4d8e076 100644
--- a/src/librustc/middle/infer/mod.rs
+++ b/src/librustc/middle/infer/mod.rs
@@ -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)
             }
 
diff --git a/src/librustc/middle/infer/unify.rs b/src/librustc/middle/infer/unify.rs
index 5effaca32b1..a240917d6c1 100644
--- a/src/librustc/middle/infer/unify.rs
+++ b/src/librustc/middle/infer/unify.rs
@@ -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)
-    }
 }
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index 0765d7294ad..1ba0194f84e 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -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};