Skip to content

Commit c43b72c

Browse files
committed
Refactor to make inference code around unification more readable
1 parent 2b28115 commit c43b72c

File tree

9 files changed

+335
-283
lines changed

9 files changed

+335
-283
lines changed

src/librustc/middle/ty.rs

Lines changed: 39 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export ProvidedMethodSource;
5555
export ProvidedMethodInfo;
5656
export ProvidedMethodsMap;
5757
export InstantiatedTraitRef;
58-
export TyVid, IntVid, FloatVid, FnVid, RegionVid, Vid;
58+
export TyVid, IntVid, FloatVid, RegionVid, Vid;
5959
export br_hashmap;
6060
export is_instantiable;
6161
export node_id_to_type;
@@ -215,7 +215,7 @@ export ty_sort_str;
215215
export normalize_ty;
216216
export to_str;
217217
export bound_const;
218-
export terr_no_integral_type, terr_no_floating_point_type;
218+
export terr_int_mismatch, terr_float_mismatch, terr_sigil_mismatch;
219219
export terr_ty_param_size, terr_self_substs;
220220
export terr_in_field, terr_record_fields, terr_vstores_differ, terr_arg_count;
221221
export terr_sorts, terr_vec, terr_str, terr_record_size, terr_tuple_size;
@@ -241,6 +241,7 @@ export AutoRef;
241241
export AutoRefKind, AutoPtr, AutoBorrowVec, AutoBorrowVecRef, AutoBorrowFn;
242242
export iter_bound_traits_and_supertraits;
243243
export count_traits_and_supertraits;
244+
export IntVarValue, IntType, UintType;
244245

245246
// Data types
246247

@@ -703,6 +704,12 @@ enum sty {
703704
ty_unboxed_vec(mt),
704705
}
705706

707+
#[deriving_eq]
708+
enum IntVarValue {
709+
IntType(ast::int_ty),
710+
UintType(ast::uint_ty),
711+
}
712+
706713
enum terr_vstore_kind {
707714
terr_vec, terr_str, terr_fn, terr_trait
708715
}
@@ -740,8 +747,8 @@ enum type_err {
740747
terr_sorts(expected_found<t>),
741748
terr_self_substs,
742749
terr_integer_as_char,
743-
terr_no_integral_type,
744-
terr_no_floating_point_type,
750+
terr_int_mismatch(expected_found<IntVarValue>),
751+
terr_float_mismatch(expected_found<ast::float_ty>)
745752
}
746753

747754
enum param_bound {
@@ -752,10 +759,16 @@ enum param_bound {
752759
bound_trait(t),
753760
}
754761

762+
#[deriving_eq]
755763
enum TyVid = uint;
764+
765+
#[deriving_eq]
756766
enum IntVid = uint;
767+
768+
#[deriving_eq]
757769
enum FloatVid = uint;
758-
enum FnVid = uint;
770+
771+
#[deriving_eq]
759772
#[auto_encode]
760773
#[auto_decode]
761774
enum RegionVid = uint;
@@ -851,14 +864,6 @@ impl FloatVid: ToStr {
851864
pure fn to_str() -> ~str { fmt!("<VF%u>", self.to_uint()) }
852865
}
853866

854-
impl FnVid: Vid {
855-
pure fn to_uint() -> uint { *self }
856-
}
857-
858-
impl FnVid: ToStr {
859-
pure fn to_str() -> ~str { fmt!("<F%u>", self.to_uint()) }
860-
}
861-
862867
impl RegionVid: Vid {
863868
pure fn to_uint() -> uint { *self }
864869
}
@@ -884,33 +889,36 @@ impl InferTy: ToStr {
884889
}
885890
}
886891

887-
impl RegionVid : to_bytes::IterBytes {
888-
pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
889-
(**self).iter_bytes(lsb0, f)
892+
impl IntVarValue : ToStr {
893+
pure fn to_str() -> ~str {
894+
match self {
895+
IntType(ref v) => v.to_str(),
896+
UintType(ref v) => v.to_str(),
897+
}
890898
}
891899
}
892900

893901
impl TyVid : to_bytes::IterBytes {
894902
pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
895-
(**self).iter_bytes(lsb0, f)
903+
self.to_uint().iter_bytes(lsb0, f)
896904
}
897905
}
898906

899907
impl IntVid : to_bytes::IterBytes {
900908
pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
901-
(**self).iter_bytes(lsb0, f)
909+
self.to_uint().iter_bytes(lsb0, f)
902910
}
903911
}
904912

905913
impl FloatVid : to_bytes::IterBytes {
906914
pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
907-
(**self).iter_bytes(lsb0, f)
915+
self.to_uint().iter_bytes(lsb0, f)
908916
}
909917
}
910918

911-
impl FnVid : to_bytes::IterBytes {
919+
impl RegionVid : to_bytes::IterBytes {
912920
pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
913-
(**self).iter_bytes(lsb0, f)
921+
self.to_uint().iter_bytes(lsb0, f)
914922
}
915923
}
916924

@@ -3575,17 +3583,18 @@ fn type_err_to_str(cx: ctxt, err: &type_err) -> ~str {
35753583
terr_self_substs => {
35763584
~"inconsistent self substitution" // XXX this is more of a bug
35773585
}
3578-
terr_no_integral_type => {
3579-
~"couldn't determine an appropriate integral type for integer \
3580-
literal"
3581-
}
35823586
terr_integer_as_char => {
3583-
~"integer literals can't be inferred to char type \
3584-
(try an explicit cast)"
3587+
fmt!("expected an integral type but found char")
35853588
}
3586-
terr_no_floating_point_type => {
3587-
~"couldn't determine an appropriate floating point type for \
3588-
floating point literal"
3589+
terr_int_mismatch(ref values) => {
3590+
fmt!("expected %s but found %s",
3591+
values.expected.to_str(),
3592+
values.found.to_str())
3593+
}
3594+
terr_float_mismatch(ref values) => {
3595+
fmt!("expected %s but found %s",
3596+
values.expected.to_str(),
3597+
values.found.to_str())
35893598
}
35903599
}
35913600
}
@@ -4451,31 +4460,6 @@ impl vstore : cmp::Eq {
44514460
pure fn ne(&self, other: &vstore) -> bool { !(*self).eq(other) }
44524461
}
44534462

4454-
impl TyVid : cmp::Eq {
4455-
pure fn eq(&self, other: &TyVid) -> bool { *(*self) == *(*other) }
4456-
pure fn ne(&self, other: &TyVid) -> bool { *(*self) != *(*other) }
4457-
}
4458-
4459-
impl IntVid : cmp::Eq {
4460-
pure fn eq(&self, other: &IntVid) -> bool { *(*self) == *(*other) }
4461-
pure fn ne(&self, other: &IntVid) -> bool { *(*self) != *(*other) }
4462-
}
4463-
4464-
impl FloatVid : cmp::Eq {
4465-
pure fn eq(&self, other: &FloatVid) -> bool { *(*self) == *(*other) }
4466-
pure fn ne(&self, other: &FloatVid) -> bool { *(*self) != *(*other) }
4467-
}
4468-
4469-
impl FnVid : cmp::Eq {
4470-
pure fn eq(&self, other: &FnVid) -> bool { *(*self) == *(*other) }
4471-
pure fn ne(&self, other: &FnVid) -> bool { *(*self) != *(*other) }
4472-
}
4473-
4474-
impl RegionVid : cmp::Eq {
4475-
pure fn eq(&self, other: &RegionVid) -> bool { *(*self) == *(*other) }
4476-
pure fn ne(&self, other: &RegionVid) -> bool { *(*self) != *(*other) }
4477-
}
4478-
44794463
impl Region : cmp::Eq {
44804464
pure fn eq(&self, other: &Region) -> bool {
44814465
match (*self) {

src/librustc/middle/typeck/infer/assignment.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ impl Assign {
103103
}
104104

105105
(ty::ty_infer(TyVar(a_id)), ty::ty_infer(TyVar(b_id))) => {
106-
let nde_a = self.infcx.get(&self.infcx.ty_var_bindings, a_id);
107-
let nde_b = self.infcx.get(&self.infcx.ty_var_bindings, b_id);
106+
let nde_a = self.infcx.get(a_id);
107+
let nde_b = self.infcx.get(b_id);
108108
let a_bounds = nde_a.possible_types;
109109
let b_bounds = nde_b.possible_types;
110110

@@ -114,15 +114,15 @@ impl Assign {
114114
}
115115

116116
(ty::ty_infer(TyVar(a_id)), _) => {
117-
let nde_a = self.infcx.get(&self.infcx.ty_var_bindings, a_id);
117+
let nde_a = self.infcx.get(a_id);
118118
let a_bounds = nde_a.possible_types;
119119

120120
let a_bnd = option::or(a_bounds.ub, a_bounds.lb);
121121
self.assign_tys_or_sub(a, b, a_bnd, Some(b))
122122
}
123123

124124
(_, ty::ty_infer(TyVar(b_id))) => {
125-
let nde_b = self.infcx.get(&self.infcx.ty_var_bindings, b_id);
125+
let nde_b = self.infcx.get(b_id);
126126
let b_bounds = nde_b.possible_types;
127127

128128
let b_bnd = option::or(b_bounds.lb, b_bounds.ub);

src/librustc/middle/typeck/infer/combine.rs

Lines changed: 71 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
use core::prelude::*;
5858

5959
use middle::ty::{FloatVar, FnTyBase, FnMeta, FnSig, IntVar, TyVar};
60+
use middle::ty::{IntType, UintType};
6061
use middle::ty;
6162
use middle::typeck::infer::glb::Glb;
6263
use middle::typeck::infer::lub::Lub;
@@ -112,8 +113,8 @@ pub struct CombineFields {
112113
}
113114

114115
fn expected_found<C:Combine,T>(
115-
self: &C, +a: T, +b: T) -> ty::expected_found<T> {
116-
116+
self: &C, +a: T, +b: T) -> ty::expected_found<T>
117+
{
117118
if self.a_is_expected() {
118119
ty::expected_found {expected: move a, found: move b}
119120
} else {
@@ -392,7 +393,7 @@ fn super_tys<C:Combine>(
392393
self: &C, a: ty::t, b: ty::t) -> cres<ty::t>
393394
{
394395
let tcx = self.infcx().tcx;
395-
match (/*bad*/copy ty::get(a).sty, /*bad*/copy ty::get(b).sty) {
396+
return match (/*bad*/copy ty::get(a).sty, /*bad*/copy ty::get(b).sty) {
396397
// The "subtype" ought to be handling cases involving bot or var:
397398
(ty::ty_bot, _) |
398399
(_, ty::ty_bot) |
@@ -405,53 +406,46 @@ fn super_tys<C:Combine>(
405406
b.inf_str(self.infcx())));
406407
}
407408

408-
// Relate integral variables to other types
409-
(ty::ty_infer(IntVar(a_id)), ty::ty_infer(IntVar(b_id))) => {
410-
if_ok!(self.infcx().simple_vars(&self.infcx().int_var_bindings,
411-
ty::terr_no_integral_type,
412-
a_id, b_id));
413-
Ok(a)
414-
}
415-
(ty::ty_infer(IntVar(v_id)), ty::ty_int(v)) |
416-
(ty::ty_int(v), ty::ty_infer(IntVar(v_id))) => {
417-
if v == ast::ty_char {
418-
Err(ty::terr_integer_as_char)
419-
} else {
420-
if_ok!(self.infcx().simple_var_t(&self.infcx().int_var_bindings,
421-
ty::terr_no_integral_type,
422-
v_id, IntType(v)));
423-
Ok(ty::mk_mach_int(tcx, v))
409+
// Relate integral variables to other types
410+
(ty::ty_infer(IntVar(a_id)), ty::ty_infer(IntVar(b_id))) => {
411+
if_ok!(self.infcx().simple_vars(self.a_is_expected(),
412+
a_id, b_id));
413+
Ok(a)
414+
}
415+
(ty::ty_infer(IntVar(v_id)), ty::ty_int(v)) => {
416+
unify_integral_variable(self, self.a_is_expected(),
417+
v_id, IntType(v))
418+
}
419+
(ty::ty_int(v), ty::ty_infer(IntVar(v_id))) => {
420+
unify_integral_variable(self, !self.a_is_expected(),
421+
v_id, IntType(v))
422+
}
423+
(ty::ty_infer(IntVar(v_id)), ty::ty_uint(v)) => {
424+
unify_integral_variable(self, self.a_is_expected(),
425+
v_id, UintType(v))
426+
}
427+
(ty::ty_uint(v), ty::ty_infer(IntVar(v_id))) => {
428+
unify_integral_variable(self, !self.a_is_expected(),
429+
v_id, UintType(v))
424430
}
425-
}
426-
(ty::ty_infer(IntVar(v_id)), ty::ty_uint(v)) |
427-
(ty::ty_uint(v), ty::ty_infer(IntVar(v_id))) => {
428-
if_ok!(self.infcx().simple_var_t(&self.infcx().int_var_bindings,
429-
ty::terr_no_integral_type,
430-
v_id, UintType(v)));
431-
Ok(ty::mk_mach_uint(tcx, v))
432-
}
433431

434-
// Relate floating-point variables to other types
435-
(ty::ty_infer(FloatVar(a_id)), ty::ty_infer(FloatVar(b_id))) => {
436-
if_ok!(self.infcx().simple_vars(&self.infcx().float_var_bindings,
437-
ty::terr_no_floating_point_type,
438-
a_id, b_id));
439-
Ok(a)
440-
}
441-
(ty::ty_infer(FloatVar(v_id)), ty::ty_float(v)) |
442-
(ty::ty_float(v), ty::ty_infer(FloatVar(v_id))) => {
443-
if_ok!(self.infcx().simple_var_t(&self.infcx().float_var_bindings,
444-
ty::terr_no_floating_point_type,
445-
v_id, v));
446-
Ok(ty::mk_mach_float(tcx, v))
447-
}
432+
// Relate floating-point variables to other types
433+
(ty::ty_infer(FloatVar(a_id)), ty::ty_infer(FloatVar(b_id))) => {
434+
if_ok!(self.infcx().simple_vars(self.a_is_expected(),
435+
a_id, b_id));
436+
Ok(a)
437+
}
438+
(ty::ty_infer(FloatVar(v_id)), ty::ty_float(v)) => {
439+
unify_float_variable(self, self.a_is_expected(), v_id, v)
440+
}
441+
(ty::ty_float(v), ty::ty_infer(FloatVar(v_id))) => {
442+
unify_float_variable(self, !self.a_is_expected(), v_id, v)
443+
}
448444

449445
(ty::ty_int(_), _) |
450446
(ty::ty_uint(_), _) |
451447
(ty::ty_float(_), _) => {
452-
let as_ = /*bad*/copy ty::get(a).sty;
453-
let bs = /*bad*/copy ty::get(b).sty;
454-
if as_ == bs {
448+
if ty::get(a).sty == ty::get(b).sty {
455449
Ok(a)
456450
} else {
457451
Err(ty::terr_sorts(expected_found(self, a, b)))
@@ -516,11 +510,9 @@ fn super_tys<C:Combine>(
516510
}
517511

518512
(ty::ty_rptr(a_r, a_mt), ty::ty_rptr(b_r, b_mt)) => {
519-
do self.contraregions(a_r, b_r).chain |r| {
520-
do self.mts(a_mt, b_mt).chain |mt| {
521-
Ok(ty::mk_rptr(tcx, r, mt))
522-
}
523-
}
513+
let r = if_ok!(self.contraregions(a_r, b_r));
514+
let mt = if_ok!(self.mts(a_mt, b_mt));
515+
Ok(ty::mk_rptr(tcx, r, mt))
524516
}
525517

526518
(ty::ty_evec(a_mt, vs_a), ty::ty_evec(b_mt, vs_b)) => {
@@ -565,5 +557,34 @@ fn super_tys<C:Combine>(
565557
}
566558

567559
_ => Err(ty::terr_sorts(expected_found(self, a, b)))
560+
};
561+
562+
fn unify_integral_variable<C:Combine>(
563+
self: &C,
564+
vid_is_expected: bool,
565+
vid: ty::IntVid,
566+
val: ty::IntVarValue) -> cres<ty::t>
567+
{
568+
let tcx = self.infcx().tcx;
569+
if val == IntType(ast::ty_char) {
570+
Err(ty::terr_integer_as_char)
571+
} else {
572+
if_ok!(self.infcx().simple_var_t(vid_is_expected, vid, val));
573+
match val {
574+
IntType(v) => Ok(ty::mk_mach_int(tcx, v)),
575+
UintType(v) => Ok(ty::mk_mach_uint(tcx, v))
576+
}
577+
}
568578
}
569-
}
579+
580+
fn unify_float_variable<C:Combine>(
581+
self: &C,
582+
vid_is_expected: bool,
583+
vid: ty::FloatVid,
584+
val: ast::float_ty) -> cres<ty::t>
585+
{
586+
let tcx = self.infcx().tcx;
587+
if_ok!(self.infcx().simple_var_t(vid_is_expected, vid, val));
588+
Ok(ty::mk_mach_float(tcx, val))
589+
}
590+
}

0 commit comments

Comments
 (0)