Skip to content

Commit a6d9930

Browse files
committed
Extract more ty and infer dependencies from the unification engine
so that it is closer to standalone.
1 parent c581840 commit a6d9930

File tree

5 files changed

+66
-63
lines changed

5 files changed

+66
-63
lines changed

src/librustc/middle/infer/combine.rs

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -436,8 +436,17 @@ pub fn expected_found<'tcx, C, T>(this: &C,
436436
a: T,
437437
b: T)
438438
-> ty::expected_found<T>
439-
where C: Combine<'tcx> {
440-
if this.a_is_expected() {
439+
where C: Combine<'tcx>
440+
{
441+
expected_found_bool(this.a_is_expected(), a, b)
442+
}
443+
444+
fn expected_found_bool<T>(a_is_expected: bool,
445+
a: T,
446+
b: T)
447+
-> ty::expected_found<T>
448+
{
449+
if a_is_expected {
441450
ty::expected_found {expected: a, found: b}
442451
} else {
443452
ty::expected_found {expected: b, found: a}
@@ -469,7 +478,8 @@ pub fn super_tys<'tcx, C>(this: &C,
469478
(&ty::ty_infer(IntVar(a_id)), &ty::ty_infer(IntVar(b_id))) => {
470479
try!(this.infcx().int_unification_table
471480
.borrow_mut()
472-
.unify_var_var(this.a_is_expected(), a_id, b_id));
481+
.unify_var_var(a_id, b_id)
482+
.map_err(|e| int_unification_error(this.a_is_expected(), e)));
473483
Ok(a)
474484
}
475485
(&ty::ty_infer(IntVar(v_id)), &ty::ty_int(v)) => {
@@ -489,7 +499,8 @@ pub fn super_tys<'tcx, C>(this: &C,
489499
(&ty::ty_infer(FloatVar(a_id)), &ty::ty_infer(FloatVar(b_id))) => {
490500
try!(this.infcx().float_unification_table
491501
.borrow_mut()
492-
.unify_var_var(this.a_is_expected(), a_id, b_id));
502+
.unify_var_var(a_id, b_id)
503+
.map_err(|e| float_unification_error(this.a_is_expected(), e)));
493504
Ok(a)
494505
}
495506
(&ty::ty_infer(FloatVar(v_id)), &ty::ty_float(v)) => {
@@ -617,9 +628,11 @@ pub fn super_tys<'tcx, C>(this: &C,
617628
-> CombineResult<'tcx, Ty<'tcx>>
618629
where C: Combine<'tcx>
619630
{
620-
try!(this.infcx().int_unification_table
621-
.borrow_mut()
622-
.unify_var_value(vid_is_expected, vid, val));
631+
try!(this.infcx()
632+
.int_unification_table
633+
.borrow_mut()
634+
.unify_var_value(vid, val)
635+
.map_err(|e| int_unification_error(vid_is_expected, e)));
623636
match val {
624637
IntType(v) => Ok(ty::mk_mach_int(this.tcx(), v)),
625638
UintType(v) => Ok(ty::mk_mach_uint(this.tcx(), v)),
@@ -635,7 +648,8 @@ pub fn super_tys<'tcx, C>(this: &C,
635648
{
636649
try!(this.infcx().float_unification_table
637650
.borrow_mut()
638-
.unify_var_value(vid_is_expected, vid, val));
651+
.unify_var_value(vid, val)
652+
.map_err(|e| float_unification_error(vid_is_expected, e)));
639653
Ok(ty::mk_mach_float(this.tcx(), val))
640654
}
641655
}
@@ -863,3 +877,17 @@ impl<'tcx, T:Clone + PartialEq> CombineResultCompare<'tcx, T> for CombineResult<
863877
}
864878
}
865879

880+
fn int_unification_error<'tcx>(a_is_expected: bool, v: (ty::IntVarValue, ty::IntVarValue))
881+
-> ty::type_err<'tcx>
882+
{
883+
let (a, b) = v;
884+
ty::terr_int_mismatch(expected_found_bool(a_is_expected, a, b))
885+
}
886+
887+
fn float_unification_error<'tcx>(a_is_expected: bool,
888+
v: (ast::FloatTy, ast::FloatTy))
889+
-> ty::type_err<'tcx>
890+
{
891+
let (a, b) = v;
892+
ty::terr_float_mismatch(expected_found_bool(a_is_expected, a, b))
893+
}

src/librustc/middle/infer/freshen.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ use middle::ty_fold::TypeFolder;
3737
use std::collections::hash_map::{self, Entry};
3838

3939
use super::InferCtxt;
40+
use super::unify::ToType;
4041

4142
pub struct TypeFreshener<'a, 'tcx:'a> {
4243
infcx: &'a InferCtxt<'a, 'tcx>,
@@ -115,14 +116,18 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
115116

116117
ty::ty_infer(ty::IntVar(v)) => {
117118
self.freshen(
118-
self.infcx.int_unification_table.borrow_mut().probe(tcx, v),
119+
self.infcx.int_unification_table.borrow_mut()
120+
.probe(v)
121+
.map(|v| v.to_type(tcx)),
119122
ty::IntVar(v),
120123
ty::FreshIntTy)
121124
}
122125

123126
ty::ty_infer(ty::FloatVar(v)) => {
124127
self.freshen(
125-
self.infcx.float_unification_table.borrow_mut().probe(tcx, v),
128+
self.infcx.float_unification_table.borrow_mut()
129+
.probe(v)
130+
.map(|v| v.to_type(tcx)),
126131
ty::FloatVar(v),
127132
ty::FreshIntTy)
128133
}

src/librustc/middle/infer/mod.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ use self::region_inference::{RegionVarBindings, RegionSnapshot};
4343
use self::equate::Equate;
4444
use self::sub::Sub;
4545
use self::lub::Lub;
46-
use self::unify::UnificationTable;
46+
use self::unify::{ToType, UnificationTable};
4747
use self::error_reporting::ErrorReporting;
4848

4949
pub mod bivariate;
@@ -885,14 +885,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
885885
ty::ty_infer(ty::IntVar(v)) => {
886886
self.int_unification_table
887887
.borrow_mut()
888-
.probe(self.tcx, v)
888+
.probe(v)
889+
.map(|v| v.to_type(self.tcx))
889890
.unwrap_or(typ)
890891
}
891892

892893
ty::ty_infer(ty::FloatVar(v)) => {
893894
self.float_unification_table
894895
.borrow_mut()
895-
.probe(self.tcx, v)
896+
.probe(v)
897+
.map(|v| v.to_type(self.tcx))
896898
.unwrap_or(typ)
897899
}
898900

src/librustc/middle/infer/unify.rs

Lines changed: 17 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use std::marker;
1414

1515
use middle::ty::{expected_found, IntVarValue};
1616
use middle::ty::{self, Ty};
17-
use middle::infer::{UnitResult};
1817
use std::fmt::Debug;
1918
use std::marker::PhantomData;
2019
use syntax::ast;
@@ -224,36 +223,15 @@ impl<K:UnifyKey> sv::SnapshotVecDelegate for Delegate<K> {
224223
// floats---anything that doesn't have a subtyping relationship we
225224
// need to worry about.
226225

227-
/// Indicates a type that does not have any kind of subtyping
228-
/// relationship.
229-
pub trait SimplyUnifiable<'tcx> : Clone + PartialEq + Debug {
230-
fn to_type(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx>;
231-
fn to_type_err(expected_found<Self>) -> ty::type_err<'tcx>;
232-
}
233-
234-
pub fn err<'tcx, V:SimplyUnifiable<'tcx>>(a_is_expected: bool,
235-
a_t: V,
236-
b_t: V)
237-
-> UnitResult<'tcx> {
238-
if a_is_expected {
239-
Err(SimplyUnifiable::to_type_err(
240-
ty::expected_found {expected: a_t, found: b_t}))
241-
} else {
242-
Err(SimplyUnifiable::to_type_err(
243-
ty::expected_found {expected: b_t, found: a_t}))
244-
}
245-
}
246-
247226
impl<'tcx,K,V> UnificationTable<K>
248-
where K : UnifyKey<Value=Option<V>>,
249-
V : SimplyUnifiable<'tcx>,
250-
Option<V> : UnifyValue,
227+
where K: UnifyKey<Value=Option<V>>,
228+
V: Clone+PartialEq,
229+
Option<V>: UnifyValue,
251230
{
252231
pub fn unify_var_var(&mut self,
253-
a_is_expected: bool,
254232
a_id: K,
255233
b_id: K)
256-
-> UnitResult<'tcx>
234+
-> Result<(),(V,V)>
257235
{
258236
let node_a = self.get(a_id);
259237
let node_b = self.get(b_id);
@@ -268,13 +246,13 @@ impl<'tcx,K,V> UnificationTable<K>
268246
None
269247
}
270248
(&Some(ref v), &None) | (&None, &Some(ref v)) => {
271-
Some((*v).clone())
249+
Some(v.clone())
272250
}
273251
(&Some(ref v1), &Some(ref v2)) => {
274252
if *v1 != *v2 {
275-
return err(a_is_expected, (*v1).clone(), (*v2).clone())
253+
return Err((v1.clone(), v2.clone()));
276254
}
277-
Some((*v1).clone())
255+
Some(v1.clone())
278256
}
279257
}
280258
};
@@ -285,10 +263,9 @@ impl<'tcx,K,V> UnificationTable<K>
285263
/// Sets the value of the key `a_id` to `b`. Because simple keys do not have any subtyping
286264
/// relationships, if `a_id` already has a value, it must be the same as `b`.
287265
pub fn unify_var_value(&mut self,
288-
a_is_expected: bool,
289266
a_id: K,
290267
b: V)
291-
-> UnitResult<'tcx>
268+
-> Result<(),(V,V)>
292269
{
293270
let node_a = self.get(a_id);
294271
let a_id = node_a.key.clone();
@@ -303,7 +280,7 @@ impl<'tcx,K,V> UnificationTable<K>
303280
if *a_t == b {
304281
Ok(())
305282
} else {
306-
err(a_is_expected, (*a_t).clone(), b)
283+
Err((a_t.clone(), b))
307284
}
308285
}
309286
}
@@ -313,37 +290,33 @@ impl<'tcx,K,V> UnificationTable<K>
313290
self.get(id).value.is_some()
314291
}
315292

316-
pub fn probe(&mut self, tcx: &ty::ctxt<'tcx>, a_id: K) -> Option<Ty<'tcx>> {
317-
let node_a = self.get(a_id);
318-
match node_a.value {
319-
None => None,
320-
Some(ref a_t) => Some(a_t.to_type(tcx))
321-
}
293+
pub fn probe(&mut self, a_id: K) -> Option<V> {
294+
self.get(a_id).value.clone()
322295
}
323296
}
324297

325298
///////////////////////////////////////////////////////////////////////////
326299

327300
// Integral type keys
328301

302+
pub trait ToType<'tcx> {
303+
fn to_type(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx>;
304+
}
305+
329306
impl UnifyKey for ty::IntVid {
330307
type Value = Option<IntVarValue>;
331308
fn index(&self) -> u32 { self.index }
332309
fn from_index(i: u32) -> ty::IntVid { ty::IntVid { index: i } }
333310
fn tag(_: Option<ty::IntVid>) -> &'static str { "IntVid" }
334311
}
335312

336-
impl<'tcx> SimplyUnifiable<'tcx> for IntVarValue {
313+
impl<'tcx> ToType<'tcx> for IntVarValue {
337314
fn to_type(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx> {
338315
match *self {
339316
ty::IntType(i) => ty::mk_mach_int(tcx, i),
340317
ty::UintType(i) => ty::mk_mach_uint(tcx, i),
341318
}
342319
}
343-
344-
fn to_type_err(err: expected_found<IntVarValue>) -> ty::type_err<'tcx> {
345-
return ty::terr_int_mismatch(err);
346-
}
347320
}
348321

349322
impl UnifyValue for Option<IntVarValue> { }
@@ -360,12 +333,8 @@ impl UnifyKey for ty::FloatVid {
360333
impl UnifyValue for Option<ast::FloatTy> {
361334
}
362335

363-
impl<'tcx> SimplyUnifiable<'tcx> for ast::FloatTy {
336+
impl<'tcx> ToType<'tcx> for ast::FloatTy {
364337
fn to_type(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx> {
365338
ty::mk_mach_float(tcx, *self)
366339
}
367-
368-
fn to_type_err(err: expected_found<ast::FloatTy>) -> ty::type_err<'tcx> {
369-
ty::terr_float_mismatch(err)
370-
}
371340
}

src/librustc_typeck/check/coercion.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,8 @@
6262
6363
use check::{autoderef, FnCtxt, NoPreference, PreferMutLvalue, UnresolvedTypeAction};
6464

65-
use middle::infer::{self, CombineResult, Coercion, TypeTrace};
65+
use middle::infer::{self, CombineResult, Coercion};
6666
use middle::infer::combine::Combine;
67-
use middle::infer::sub::Sub;
6867
use middle::subst;
6968
use middle::ty::{AutoPtr, AutoDerefRef, AdjustDerefRef, AutoUnsize, AutoUnsafe};
7069
use middle::ty::{self, mt, Ty};

0 commit comments

Comments
 (0)