Skip to content

Commit 7d07555

Browse files
committed
Add ty_var_integral (WIP on issue #1425).
1 parent 77c470d commit 7d07555

File tree

6 files changed

+81
-34
lines changed

6 files changed

+81
-34
lines changed

src/rustc/metadata/tyencode.rs

+6
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,12 @@ fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
276276
w.write_char('X');
277277
w.write_uint(id.to_uint());
278278
}
279+
ty::ty_var_integral(id) {
280+
// TODO: should we have a different character for these? (Issue #1425)
281+
w.write_char('X');
282+
w.write_uint(id.to_uint());
283+
w.write_str("(integral)");
284+
}
279285
ty::ty_param(id, did) {
280286
w.write_char('p');
281287
w.write_str(cx.ds(did));

src/rustc/middle/trans/shape.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> [u8] {
395395
ty::ty_fn({proto: ast::proto_bare, _}) { [shape_bare_fn] }
396396
ty::ty_opaque_closure_ptr(_) { [shape_opaque_closure_ptr] }
397397
ty::ty_constr(inner_t, _) { shape_of(ccx, inner_t) }
398-
ty::ty_var(_) | ty::ty_self {
398+
ty::ty_var(_) | ty::ty_var_integral(_) | ty::ty_self {
399399
ccx.sess.bug("shape_of: unexpected type struct found");
400400
}
401401
}

src/rustc/middle/trans/type_of.rs

+3
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,9 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
161161
}
162162
ty::ty_self { cx.tcx.sess.unimpl("type_of: ty_self"); }
163163
ty::ty_var(_) { cx.tcx.sess.bug("type_of shouldn't see a ty_var"); }
164+
ty::ty_var_integral(_) {
165+
cx.tcx.sess.bug("type_of shouldn't see a ty_var_integral");
166+
}
164167
}
165168
};
166169
cx.lltypes.insert(t, llty);

src/rustc/middle/ty.rs

+47-12
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ export ty_type, mk_type;
102102
export ty_uint, mk_uint, mk_mach_uint;
103103
export ty_uniq, mk_uniq, mk_imm_uniq, type_is_unique_box;
104104
export ty_var, mk_var, type_is_var;
105+
export ty_var_integral, mk_var_integral, type_is_var_integral;
105106
export ty_self, mk_self, type_has_self;
106107
export region, bound_region, encl_region;
107108
export get, type_has_params, type_needs_infer, type_has_regions;
@@ -299,6 +300,11 @@ enum closure_kind {
299300
ck_uniq,
300301
}
301302

303+
enum ty_var_kind {
304+
tvk_regular,
305+
tvk_integral,
306+
}
307+
302308
type fn_ty = {purity: ast::purity,
303309
proto: ast::proto,
304310
inputs: [arg],
@@ -365,6 +371,8 @@ enum sty {
365371
ty_tup([t]),
366372

367373
ty_var(ty_vid), // type variable during typechecking
374+
ty_var_integral(ty_vid), // type variable during typechecking, for
375+
// integral types only
368376
ty_param(uint, def_id), // type parameter
369377
ty_self, // special, implicit `self` type parameter
370378

@@ -555,7 +563,7 @@ fn mk_t_with_id(cx: ctxt, st: sty, o_def_id: option<ast::def_id>) -> t {
555563
ty_str | ty_estr(_) | ty_type | ty_opaque_closure_ptr(_) |
556564
ty_opaque_box {}
557565
ty_param(_, _) { flags |= has_params as uint; }
558-
ty_var(_) { flags |= needs_infer as uint; }
566+
ty_var(_) | ty_var_integral(_) { flags |= needs_infer as uint; }
559567
ty_self { flags |= has_self as uint; }
560568
ty_enum(_, substs) | ty_class(_, substs) | ty_iface(_, substs) {
561569
flags |= sflags(substs);
@@ -680,6 +688,8 @@ fn mk_res(cx: ctxt, did: ast::def_id,
680688

681689
fn mk_var(cx: ctxt, v: ty_vid) -> t { mk_t(cx, ty_var(v)) }
682690

691+
fn mk_var_integral(cx: ctxt, v: ty_vid) -> t { mk_t(cx, ty_var_integral(v)) }
692+
683693
fn mk_self(cx: ctxt) -> t { mk_t(cx, ty_self) }
684694

685695
fn mk_param(cx: ctxt, n: uint, k: def_id) -> t { mk_t(cx, ty_param(n, k)) }
@@ -729,7 +739,8 @@ fn maybe_walk_ty(ty: t, f: fn(t) -> bool) {
729739
alt get(ty).struct {
730740
ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
731741
ty_str | ty_estr(_) | ty_type | ty_opaque_box | ty_self |
732-
ty_opaque_closure_ptr(_) | ty_var(_) | ty_param(_, _) {
742+
ty_opaque_closure_ptr(_) | ty_var(_) | ty_var_integral(_) |
743+
ty_param(_, _) {
733744
}
734745
ty_box(tm) | ty_vec(tm) | ty_evec(tm, _) |
735746
ty_ptr(tm) | ty_rptr(_, tm) {
@@ -824,7 +835,7 @@ fn fold_sty(sty: sty, fldop: fn(t) -> t) -> sty {
824835
}
825836
ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
826837
ty_str | ty_estr(_) | ty_type | ty_opaque_closure_ptr(_) |
827-
ty_opaque_box | ty_var(_) | ty_param(*) | ty_self {
838+
ty_opaque_box | ty_var(_) | ty_var_integral(_) | ty_param(*) | ty_self {
828839
sty
829840
}
830841
}
@@ -1038,6 +1049,13 @@ fn type_is_var(ty: t) -> bool {
10381049
}
10391050
}
10401051

1052+
fn type_is_var_integral(ty: t) -> bool {
1053+
alt get(ty).struct {
1054+
ty_var_integral(_) { true }
1055+
_ { false }
1056+
}
1057+
}
1058+
10411059
fn type_is_bool(ty: t) -> bool { get(ty).struct == ty_bool }
10421060

10431061
fn type_is_structural(ty: t) -> bool {
@@ -1553,8 +1571,9 @@ fn type_kind(cx: ctxt, ty: t) -> kind {
15531571
ty_constr(t, _) { type_kind(cx, t) }
15541572
// FIXME: is self ever const?
15551573
ty_self { kind_noncopyable() }
1556-
1557-
ty_var(_) { cx.sess.bug("Asked to compute kind of a type variable"); }
1574+
ty_var(_) | ty_var_integral(_) {
1575+
cx.sess.bug("Asked to compute kind of a type variable");
1576+
}
15581577
ty_type | ty_opaque_closure_ptr(_) | ty_opaque_box {
15591578
cx.sess.bug("Asked to compute kind of fictitious type");
15601579
}
@@ -1602,6 +1621,7 @@ fn is_instantiable(cx: ctxt, r_ty: t) -> bool {
16021621
ty_estr(_) |
16031622
ty_fn(_) |
16041623
ty_var(_) |
1624+
ty_var_integral(_) |
16051625
ty_param(_, _) |
16061626
ty_self |
16071627
ty_type |
@@ -1878,12 +1898,25 @@ fn type_param(ty: t) -> option<uint> {
18781898
ret none;
18791899
}
18801900

1881-
// Returns a vec of all the type variables
1882-
// occurring in t. It may contain duplicates.
1883-
fn vars_in_type(ty: t) -> [ty_vid] {
1901+
// Returns a vec of all the type variables of kind `tvk` occurring in `ty`. It
1902+
// may contain duplicates.
1903+
fn vars_in_type(ty: t, tvk: ty_var_kind) -> [ty_vid] {
18841904
let mut rslt = [];
18851905
walk_ty(ty) {|ty|
1886-
alt get(ty).struct { ty_var(v) { rslt += [v]; } _ { } }
1906+
alt get(ty).struct {
1907+
ty_var(v) {
1908+
alt tvk {
1909+
tvk_regular { rslt += [v]; }
1910+
_ { }
1911+
}
1912+
}
1913+
ty_var_integral(v) {
1914+
alt tvk {
1915+
tvk_integral { rslt += [v]; }
1916+
_ { }
1917+
}
1918+
}
1919+
_ { } }
18871920
}
18881921
rslt
18891922
}
@@ -2037,7 +2070,8 @@ fn hash_type_structure(st: sty) -> uint {
20372070
for f.inputs.each {|a| h = hash_subty(h, a.ty); }
20382071
hash_subty(h, f.output)
20392072
}
2040-
ty_var(v) { hash_uint(30u, v.to_uint()) }
2073+
ty_var(v) { hash_uint(29u, v.to_uint()) }
2074+
ty_var_integral(v) { hash_uint(30u, v.to_uint()) }
20412075
ty_param(pid, did) { hash_def(hash_uint(31u, pid), did) }
20422076
ty_self { 28u }
20432077
ty_type { 32u }
@@ -2184,7 +2218,7 @@ fn is_pred_ty(fty: t) -> bool {
21842218

21852219
fn ty_var_id(typ: t) -> ty_vid {
21862220
alt get(typ).struct {
2187-
ty_var(vid) { ret vid; }
2221+
ty_var(vid) | ty_var_integral(vid) { ret vid; }
21882222
_ { #error("ty_var_id called on non-var ty"); fail; }
21892223
}
21902224
}
@@ -2276,7 +2310,7 @@ fn occurs_check(tcx: ctxt, sp: span, vid: ty_vid, rt: t) {
22762310
if !type_needs_infer(rt) { ret; }
22772311

22782312
// Occurs check!
2279-
if vec::contains(vars_in_type(rt), vid) {
2313+
if vec::contains(vars_in_type(rt, tvk_regular), vid) {
22802314
// Maybe this should be span_err -- however, there's an
22812315
// assertion later on that the type doesn't contain
22822316
// variables, so in this case we have to be sure to die.
@@ -2381,6 +2415,7 @@ fn ty_sort_str(cx: ctxt, t: t) -> str {
23812415
ty_res(id, _, _) { #fmt["resource %s", item_path_str(cx, id)] }
23822416
ty_tup(_) { "tuple" }
23832417
ty_var(_) { "variable" }
2418+
ty_var_integral(_) { "integral variable" }
23842419
ty_param(_, _) { "type parameter" }
23852420
ty_self { "self" }
23862421
ty_constr(t, _) { ty_sort_str(cx, t) }

src/rustc/middle/typeck/infer.rs

+23-21
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,9 @@ type vals_and_bindings<V:copy, T:copy> = {
198198

199199
enum infer_ctxt = @{
200200
tcx: ty::ctxt,
201-
vb: vals_and_bindings<ty::ty_vid, ty::t>,
202-
rb: vals_and_bindings<ty::region_vid, ty::region>,
201+
tvb: vals_and_bindings<ty::ty_vid, ty::t>, // for type variables
202+
tvib: vals_and_bindings<ty::ty_vid, ty::t>, // for integral type variables
203+
rb: vals_and_bindings<ty::region_vid, ty::region>, // for region variables
203204

204205
// For keeping track of existing type/region variables.
205206
ty_var_counter: @mut uint,
@@ -227,7 +228,8 @@ type fres<T> = result::result<T, fixup_err>;
227228

228229
fn new_infer_ctxt(tcx: ty::ctxt) -> infer_ctxt {
229230
infer_ctxt(@{tcx: tcx,
230-
vb: {vals: smallintmap::mk(), mut bindings: []},
231+
tvb: {vals: smallintmap::mk(), mut bindings: []},
232+
tvib: {vals: smallintmap::mk(), mut bindings: []},
231233
rb: {vals: smallintmap::mk(), mut bindings: []},
232234
ty_var_counter: @mut 0u,
233235
region_var_counter: @mut 0u})}
@@ -423,14 +425,14 @@ impl transaction_methods for infer_ctxt {
423425
#[doc = "Execute `f` and commit the bindings if successful"]
424426
fn commit<T,E>(f: fn() -> result<T,E>) -> result<T,E> {
425427

426-
assert self.vb.bindings.len() == 0u;
428+
assert self.tvb.bindings.len() == 0u;
427429
assert self.rb.bindings.len() == 0u;
428430

429431
let r <- self.try(f);
430432

431433
// TODO---could use a vec::clear() that ran destructors but kept
432434
// the vec at its currently allocated length
433-
self.vb.bindings = [];
435+
self.tvb.bindings = [];
434436
self.rb.bindings = [];
435437

436438
ret r;
@@ -439,15 +441,15 @@ impl transaction_methods for infer_ctxt {
439441
#[doc = "Execute `f`, unroll bindings on failure"]
440442
fn try<T,E>(f: fn() -> result<T,E>) -> result<T,E> {
441443

442-
let vbl = self.vb.bindings.len();
444+
let tvbl = self.tvb.bindings.len();
443445
let rbl = self.rb.bindings.len();
444-
#debug["try(vbl=%u, rbl=%u)", vbl, rbl];
446+
#debug["try(tvbl=%u, rbl=%u)", tvbl, rbl];
445447
let r <- f();
446448
alt r {
447449
result::ok(_) { #debug["try--ok"]; }
448450
result::err(_) {
449451
#debug["try--rollback"];
450-
rollback_to(self.vb, vbl);
452+
rollback_to(self.tvb, tvbl);
451453
rollback_to(self.rb, rbl);
452454
}
453455
}
@@ -456,10 +458,10 @@ impl transaction_methods for infer_ctxt {
456458

457459
#[doc = "Execute `f` then unroll any bindings it creates"]
458460
fn probe<T,E>(f: fn() -> result<T,E>) -> result<T,E> {
459-
assert self.vb.bindings.len() == 0u;
461+
assert self.tvb.bindings.len() == 0u;
460462
assert self.rb.bindings.len() == 0u;
461463
let r <- f();
462-
rollback_to(self.vb, 0u);
464+
rollback_to(self.tvb, 0u);
463465
rollback_to(self.rb, 0u);
464466
ret r;
465467
}
@@ -932,7 +934,7 @@ impl methods for resolve_state {
932934
// tend to carry more restrictions or higher
933935
// perf. penalties, so it pays to know more.
934936

935-
let {root:_, bounds} = self.infcx.get(self.infcx.vb, vid);
937+
let {root:_, bounds} = self.infcx.get(self.infcx.tvb, vid);
936938
let t1 = alt bounds {
937939
{ ub:_, lb:some(t) } if !type_is_bot(t) { self.resolve1(t) }
938940
{ ub:some(t), lb:_ } { self.resolve1(t) }
@@ -1025,21 +1027,21 @@ impl assignment for infer_ctxt {
10251027
}
10261028

10271029
(ty::ty_var(a_id), ty::ty_var(b_id)) {
1028-
let {root:_, bounds: a_bounds} = self.get(self.vb, a_id);
1029-
let {root:_, bounds: b_bounds} = self.get(self.vb, b_id);
1030+
let {root:_, bounds: a_bounds} = self.get(self.tvb, a_id);
1031+
let {root:_, bounds: b_bounds} = self.get(self.tvb, b_id);
10301032
let a_bnd = select(a_bounds.ub, a_bounds.lb);
10311033
let b_bnd = select(b_bounds.lb, b_bounds.ub);
10321034
self.assign_tys_or_sub(anmnt, a, b, a_bnd, b_bnd)
10331035
}
10341036

10351037
(ty::ty_var(a_id), _) {
1036-
let {root:_, bounds:a_bounds} = self.get(self.vb, a_id);
1038+
let {root:_, bounds:a_bounds} = self.get(self.tvb, a_id);
10371039
let a_bnd = select(a_bounds.ub, a_bounds.lb);
10381040
self.assign_tys_or_sub(anmnt, a, b, a_bnd, some(b))
10391041
}
10401042

10411043
(_, ty::ty_var(b_id)) {
1042-
let {root:_, bounds: b_bounds} = self.get(self.vb, b_id);
1044+
let {root:_, bounds: b_bounds} = self.get(self.tvb, b_id);
10431045
let b_bnd = select(b_bounds.lb, b_bounds.ub);
10441046
self.assign_tys_or_sub(anmnt, a, b, some(a), b_bnd)
10451047
}
@@ -1632,13 +1634,13 @@ impl of combine for sub {
16321634
ok(a)
16331635
}
16341636
(ty::ty_var(a_id), ty::ty_var(b_id)) {
1635-
self.infcx().vars(self.vb, a_id, b_id).then {|| ok(a) }
1637+
self.infcx().vars(self.tvb, a_id, b_id).then {|| ok(a) }
16361638
}
16371639
(ty::ty_var(a_id), _) {
1638-
self.infcx().vart(self.vb, a_id, b).then {|| ok(a) }
1640+
self.infcx().vart(self.tvb, a_id, b).then {|| ok(a) }
16391641
}
16401642
(_, ty::ty_var(b_id)) {
1641-
self.infcx().tvar(self.vb, a, b_id).then {|| ok(a) }
1643+
self.infcx().tvar(self.tvb, a, b_id).then {|| ok(a) }
16421644
}
16431645
(_, ty::ty_bot) {
16441646
err(ty::terr_sorts(b, a))
@@ -2148,18 +2150,18 @@ fn lattice_tys<L:lattice_ops combine>(
21482150
(_, ty::ty_bot) { self.ty_bot(a) }
21492151

21502152
(ty::ty_var(a_id), ty::ty_var(b_id)) {
2151-
lattice_vars(self, self.infcx().vb,
2153+
lattice_vars(self, self.infcx().tvb,
21522154
a, a_id, b_id,
21532155
{|x, y| self.tys(x, y) })
21542156
}
21552157

21562158
(ty::ty_var(a_id), _) {
2157-
lattice_var_t(self, self.infcx().vb, a_id, b,
2159+
lattice_var_t(self, self.infcx().tvb, a_id, b,
21582160
{|x, y| self.tys(x, y) })
21592161
}
21602162

21612163
(_, ty::ty_var(b_id)) {
2162-
lattice_var_t(self, self.infcx().vb, b_id, a,
2164+
lattice_var_t(self, self.infcx().tvb, b_id, a,
21632165
{|x, y| self.tys(x, y) })
21642166
}
21652167

src/rustc/util/ppaux.rs

+1
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ fn ty_to_str(cx: ctxt, typ: t) -> str {
194194
f.output, f.ret_style, f.constraints)
195195
}
196196
ty_var(v) { v.to_str() }
197+
ty_var_integral(v) { v.to_str() }
197198
ty_param(id, _) {
198199
"'" + str::from_bytes([('a' as u8) + (id as u8)])
199200
}

0 commit comments

Comments
 (0)