about summary refs log tree commit diff
path: root/src/rustc
diff options
context:
space:
mode:
authorLindsey Kuper <lindsey@rockstargirl.org>2012-06-01 14:56:33 -0700
committerLindsey Kuper <lindsey@rockstargirl.org>2012-06-02 11:19:27 -0700
commit7d0755529e729e2e85c30ad45131cd15eea5f04f (patch)
tree1d4dfc0f1cbc7c5c0820a69962c065251ccb18a8 /src/rustc
parent77c470d183472b357737b6d3e6c7cafc26174c91 (diff)
downloadrust-7d0755529e729e2e85c30ad45131cd15eea5f04f.tar.gz
rust-7d0755529e729e2e85c30ad45131cd15eea5f04f.zip
Add ty_var_integral (WIP on issue #1425).
Diffstat (limited to 'src/rustc')
-rw-r--r--src/rustc/metadata/tyencode.rs6
-rw-r--r--src/rustc/middle/trans/shape.rs2
-rw-r--r--src/rustc/middle/trans/type_of.rs3
-rw-r--r--src/rustc/middle/ty.rs59
-rw-r--r--src/rustc/middle/typeck/infer.rs44
-rw-r--r--src/rustc/util/ppaux.rs1
6 files changed, 81 insertions, 34 deletions
diff --git a/src/rustc/metadata/tyencode.rs b/src/rustc/metadata/tyencode.rs
index eb6631c7a50..4893275f953 100644
--- a/src/rustc/metadata/tyencode.rs
+++ b/src/rustc/metadata/tyencode.rs
@@ -276,6 +276,12 @@ fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
         w.write_char('X');
         w.write_uint(id.to_uint());
       }
+      ty::ty_var_integral(id) {
+        // TODO: should we have a different character for these? (Issue #1425)
+        w.write_char('X');
+        w.write_uint(id.to_uint());
+        w.write_str("(integral)");
+      }
       ty::ty_param(id, did) {
         w.write_char('p');
         w.write_str(cx.ds(did));
diff --git a/src/rustc/middle/trans/shape.rs b/src/rustc/middle/trans/shape.rs
index 707c8d0608e..303b8995244 100644
--- a/src/rustc/middle/trans/shape.rs
+++ b/src/rustc/middle/trans/shape.rs
@@ -395,7 +395,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> [u8] {
       ty::ty_fn({proto: ast::proto_bare, _}) { [shape_bare_fn] }
       ty::ty_opaque_closure_ptr(_) { [shape_opaque_closure_ptr] }
       ty::ty_constr(inner_t, _) { shape_of(ccx, inner_t) }
-      ty::ty_var(_) | ty::ty_self {
+      ty::ty_var(_) | ty::ty_var_integral(_) | ty::ty_self {
         ccx.sess.bug("shape_of: unexpected type struct found");
       }
     }
diff --git a/src/rustc/middle/trans/type_of.rs b/src/rustc/middle/trans/type_of.rs
index fedd7c713cf..7ce9b5885b4 100644
--- a/src/rustc/middle/trans/type_of.rs
+++ b/src/rustc/middle/trans/type_of.rs
@@ -161,6 +161,9 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
           }
           ty::ty_self { cx.tcx.sess.unimpl("type_of: ty_self"); }
           ty::ty_var(_) { cx.tcx.sess.bug("type_of shouldn't see a ty_var"); }
+          ty::ty_var_integral(_) {
+            cx.tcx.sess.bug("type_of shouldn't see a ty_var_integral");
+          }
         }
     };
     cx.lltypes.insert(t, llty);
diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs
index fd6b797d559..c608a83319c 100644
--- a/src/rustc/middle/ty.rs
+++ b/src/rustc/middle/ty.rs
@@ -102,6 +102,7 @@ export ty_type, mk_type;
 export ty_uint, mk_uint, mk_mach_uint;
 export ty_uniq, mk_uniq, mk_imm_uniq, type_is_unique_box;
 export ty_var, mk_var, type_is_var;
+export ty_var_integral, mk_var_integral, type_is_var_integral;
 export ty_self, mk_self, type_has_self;
 export region, bound_region, encl_region;
 export get, type_has_params, type_needs_infer, type_has_regions;
@@ -299,6 +300,11 @@ enum closure_kind {
     ck_uniq,
 }
 
+enum ty_var_kind {
+    tvk_regular,
+    tvk_integral,
+}
+
 type fn_ty = {purity: ast::purity,
               proto: ast::proto,
               inputs: [arg],
@@ -365,6 +371,8 @@ enum sty {
     ty_tup([t]),
 
     ty_var(ty_vid), // type variable during typechecking
+    ty_var_integral(ty_vid), // type variable during typechecking, for
+                             // integral types only
     ty_param(uint, def_id), // type parameter
     ty_self, // special, implicit `self` type parameter
 
@@ -555,7 +563,7 @@ fn mk_t_with_id(cx: ctxt, st: sty, o_def_id: option<ast::def_id>) -> t {
       ty_str | ty_estr(_) | ty_type | ty_opaque_closure_ptr(_) |
       ty_opaque_box {}
       ty_param(_, _) { flags |= has_params as uint; }
-      ty_var(_) { flags |= needs_infer as uint; }
+      ty_var(_) | ty_var_integral(_) { flags |= needs_infer as uint; }
       ty_self { flags |= has_self as uint; }
       ty_enum(_, substs) | ty_class(_, substs) | ty_iface(_, substs) {
         flags |= sflags(substs);
@@ -680,6 +688,8 @@ fn mk_res(cx: ctxt, did: ast::def_id,
 
 fn mk_var(cx: ctxt, v: ty_vid) -> t { mk_t(cx, ty_var(v)) }
 
+fn mk_var_integral(cx: ctxt, v: ty_vid) -> t { mk_t(cx, ty_var_integral(v)) }
+
 fn mk_self(cx: ctxt) -> t { mk_t(cx, ty_self) }
 
 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) {
     alt get(ty).struct {
       ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
       ty_str | ty_estr(_) | ty_type | ty_opaque_box | ty_self |
-      ty_opaque_closure_ptr(_) | ty_var(_) | ty_param(_, _) {
+      ty_opaque_closure_ptr(_) | ty_var(_) | ty_var_integral(_) |
+      ty_param(_, _) {
       }
       ty_box(tm) | ty_vec(tm) | ty_evec(tm, _) |
       ty_ptr(tm) | ty_rptr(_, tm) {
@@ -824,7 +835,7 @@ fn fold_sty(sty: sty, fldop: fn(t) -> t) -> sty {
       }
       ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
       ty_str | ty_estr(_) | ty_type | ty_opaque_closure_ptr(_) |
-      ty_opaque_box | ty_var(_) | ty_param(*) | ty_self {
+      ty_opaque_box | ty_var(_) | ty_var_integral(_) | ty_param(*) | ty_self {
         sty
       }
     }
@@ -1038,6 +1049,13 @@ fn type_is_var(ty: t) -> bool {
     }
 }
 
+fn type_is_var_integral(ty: t) -> bool {
+    alt get(ty).struct {
+      ty_var_integral(_) { true }
+      _ { false }
+    }
+}
+
 fn type_is_bool(ty: t) -> bool { get(ty).struct == ty_bool }
 
 fn type_is_structural(ty: t) -> bool {
@@ -1553,8 +1571,9 @@ fn type_kind(cx: ctxt, ty: t) -> kind {
       ty_constr(t, _) { type_kind(cx, t) }
       // FIXME: is self ever const?
       ty_self { kind_noncopyable() }
-
-      ty_var(_) { cx.sess.bug("Asked to compute kind of a type variable"); }
+      ty_var(_) | ty_var_integral(_) {
+        cx.sess.bug("Asked to compute kind of a type variable");
+      }
       ty_type | ty_opaque_closure_ptr(_) | ty_opaque_box {
         cx.sess.bug("Asked to compute kind of fictitious type");
       }
@@ -1602,6 +1621,7 @@ fn is_instantiable(cx: ctxt, r_ty: t) -> bool {
           ty_estr(_) |
           ty_fn(_) |
           ty_var(_) |
+          ty_var_integral(_) |
           ty_param(_, _) |
           ty_self |
           ty_type |
@@ -1878,12 +1898,25 @@ fn type_param(ty: t) -> option<uint> {
     ret none;
 }
 
-// Returns a vec of all the type variables
-// occurring in t. It may contain duplicates.
-fn vars_in_type(ty: t) -> [ty_vid] {
+// Returns a vec of all the type variables of kind `tvk` occurring in `ty`. It
+// may contain duplicates.
+fn vars_in_type(ty: t, tvk: ty_var_kind) -> [ty_vid] {
     let mut rslt = [];
     walk_ty(ty) {|ty|
-        alt get(ty).struct { ty_var(v) { rslt += [v]; } _ { } }
+        alt get(ty).struct {
+          ty_var(v) {
+            alt tvk {
+              tvk_regular { rslt += [v]; }
+              _ { }
+            }
+          }
+          ty_var_integral(v) {
+            alt tvk {
+              tvk_integral { rslt += [v]; }
+              _ { }
+            }
+          }
+          _ { } }
     }
     rslt
 }
@@ -2037,7 +2070,8 @@ fn hash_type_structure(st: sty) -> uint {
         for f.inputs.each {|a| h = hash_subty(h, a.ty); }
         hash_subty(h, f.output)
       }
-      ty_var(v) { hash_uint(30u, v.to_uint()) }
+      ty_var(v) { hash_uint(29u, v.to_uint()) }
+      ty_var_integral(v) { hash_uint(30u, v.to_uint()) }
       ty_param(pid, did) { hash_def(hash_uint(31u, pid), did) }
       ty_self { 28u }
       ty_type { 32u }
@@ -2184,7 +2218,7 @@ fn is_pred_ty(fty: t) -> bool {
 
 fn ty_var_id(typ: t) -> ty_vid {
     alt get(typ).struct {
-      ty_var(vid) { ret vid; }
+      ty_var(vid) | ty_var_integral(vid) { ret vid; }
       _ { #error("ty_var_id called on non-var ty"); fail; }
     }
 }
@@ -2276,7 +2310,7 @@ fn occurs_check(tcx: ctxt, sp: span, vid: ty_vid, rt: t) {
     if !type_needs_infer(rt) { ret; }
 
     // Occurs check!
-    if vec::contains(vars_in_type(rt), vid) {
+    if vec::contains(vars_in_type(rt, tvk_regular), vid) {
             // Maybe this should be span_err -- however, there's an
             // assertion later on that the type doesn't contain
             // 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 {
       ty_res(id, _, _) { #fmt["resource %s", item_path_str(cx, id)] }
       ty_tup(_) { "tuple" }
       ty_var(_) { "variable" }
+      ty_var_integral(_) { "integral variable" }
       ty_param(_, _) { "type parameter" }
       ty_self { "self" }
       ty_constr(t, _) { ty_sort_str(cx, t) }
diff --git a/src/rustc/middle/typeck/infer.rs b/src/rustc/middle/typeck/infer.rs
index 2896e8875da..45726bff966 100644
--- a/src/rustc/middle/typeck/infer.rs
+++ b/src/rustc/middle/typeck/infer.rs
@@ -198,8 +198,9 @@ type vals_and_bindings<V:copy, T:copy> = {
 
 enum infer_ctxt = @{
     tcx: ty::ctxt,
-    vb: vals_and_bindings<ty::ty_vid, ty::t>,
-    rb: vals_and_bindings<ty::region_vid, ty::region>,
+    tvb: vals_and_bindings<ty::ty_vid, ty::t>, // for type variables
+    tvib: vals_and_bindings<ty::ty_vid, ty::t>, // for integral type variables
+    rb: vals_and_bindings<ty::region_vid, ty::region>, // for region variables
 
     // For keeping track of existing type/region variables.
     ty_var_counter: @mut uint,
@@ -227,7 +228,8 @@ type fres<T> = result::result<T, fixup_err>;
 
 fn new_infer_ctxt(tcx: ty::ctxt) -> infer_ctxt {
     infer_ctxt(@{tcx: tcx,
-                 vb: {vals: smallintmap::mk(), mut bindings: []},
+                 tvb: {vals: smallintmap::mk(), mut bindings: []},
+                 tvib: {vals: smallintmap::mk(), mut bindings: []},
                  rb: {vals: smallintmap::mk(), mut bindings: []},
                  ty_var_counter: @mut 0u,
                  region_var_counter: @mut 0u})}
@@ -423,14 +425,14 @@ impl transaction_methods for infer_ctxt {
     #[doc = "Execute `f` and commit the bindings if successful"]
     fn commit<T,E>(f: fn() -> result<T,E>) -> result<T,E> {
 
-        assert self.vb.bindings.len() == 0u;
+        assert self.tvb.bindings.len() == 0u;
         assert self.rb.bindings.len() == 0u;
 
         let r <- self.try(f);
 
         // TODO---could use a vec::clear() that ran destructors but kept
         // the vec at its currently allocated length
-        self.vb.bindings = [];
+        self.tvb.bindings = [];
         self.rb.bindings = [];
 
         ret r;
@@ -439,15 +441,15 @@ impl transaction_methods for infer_ctxt {
     #[doc = "Execute `f`, unroll bindings on failure"]
     fn try<T,E>(f: fn() -> result<T,E>) -> result<T,E> {
 
-        let vbl = self.vb.bindings.len();
+        let tvbl = self.tvb.bindings.len();
         let rbl = self.rb.bindings.len();
-        #debug["try(vbl=%u, rbl=%u)", vbl, rbl];
+        #debug["try(tvbl=%u, rbl=%u)", tvbl, rbl];
         let r <- f();
         alt r {
           result::ok(_) { #debug["try--ok"]; }
           result::err(_) {
             #debug["try--rollback"];
-            rollback_to(self.vb, vbl);
+            rollback_to(self.tvb, tvbl);
             rollback_to(self.rb, rbl);
           }
         }
@@ -456,10 +458,10 @@ impl transaction_methods for infer_ctxt {
 
     #[doc = "Execute `f` then unroll any bindings it creates"]
     fn probe<T,E>(f: fn() -> result<T,E>) -> result<T,E> {
-        assert self.vb.bindings.len() == 0u;
+        assert self.tvb.bindings.len() == 0u;
         assert self.rb.bindings.len() == 0u;
         let r <- f();
-        rollback_to(self.vb, 0u);
+        rollback_to(self.tvb, 0u);
         rollback_to(self.rb, 0u);
         ret r;
     }
@@ -932,7 +934,7 @@ impl methods for resolve_state {
             // tend to carry more restrictions or higher
             // perf. penalties, so it pays to know more.
 
-            let {root:_, bounds} = self.infcx.get(self.infcx.vb, vid);
+            let {root:_, bounds} = self.infcx.get(self.infcx.tvb, vid);
             let t1 = alt bounds {
               { ub:_, lb:some(t) } if !type_is_bot(t) { self.resolve1(t) }
               { ub:some(t), lb:_ } { self.resolve1(t) }
@@ -1025,21 +1027,21 @@ impl assignment for infer_ctxt {
           }
 
           (ty::ty_var(a_id), ty::ty_var(b_id)) {
-            let {root:_, bounds: a_bounds} = self.get(self.vb, a_id);
-            let {root:_, bounds: b_bounds} = self.get(self.vb, b_id);
+            let {root:_, bounds: a_bounds} = self.get(self.tvb, a_id);
+            let {root:_, bounds: b_bounds} = self.get(self.tvb, b_id);
             let a_bnd = select(a_bounds.ub, a_bounds.lb);
             let b_bnd = select(b_bounds.lb, b_bounds.ub);
             self.assign_tys_or_sub(anmnt, a, b, a_bnd, b_bnd)
           }
 
           (ty::ty_var(a_id), _) {
-            let {root:_, bounds:a_bounds} = self.get(self.vb, a_id);
+            let {root:_, bounds:a_bounds} = self.get(self.tvb, a_id);
             let a_bnd = select(a_bounds.ub, a_bounds.lb);
             self.assign_tys_or_sub(anmnt, a, b, a_bnd, some(b))
           }
 
           (_, ty::ty_var(b_id)) {
-            let {root:_, bounds: b_bounds} = self.get(self.vb, b_id);
+            let {root:_, bounds: b_bounds} = self.get(self.tvb, b_id);
             let b_bnd = select(b_bounds.lb, b_bounds.ub);
             self.assign_tys_or_sub(anmnt, a, b, some(a), b_bnd)
           }
@@ -1632,13 +1634,13 @@ impl of combine for sub {
                 ok(a)
               }
               (ty::ty_var(a_id), ty::ty_var(b_id)) {
-                self.infcx().vars(self.vb, a_id, b_id).then {|| ok(a) }
+                self.infcx().vars(self.tvb, a_id, b_id).then {|| ok(a) }
               }
               (ty::ty_var(a_id), _) {
-                self.infcx().vart(self.vb, a_id, b).then {|| ok(a) }
+                self.infcx().vart(self.tvb, a_id, b).then {|| ok(a) }
               }
               (_, ty::ty_var(b_id)) {
-                self.infcx().tvar(self.vb, a, b_id).then {|| ok(a) }
+                self.infcx().tvar(self.tvb, a, b_id).then {|| ok(a) }
               }
               (_, ty::ty_bot) {
                 err(ty::terr_sorts(b, a))
@@ -2148,18 +2150,18 @@ fn lattice_tys<L:lattice_ops combine>(
           (_, ty::ty_bot) { self.ty_bot(a) }
 
           (ty::ty_var(a_id), ty::ty_var(b_id)) {
-            lattice_vars(self, self.infcx().vb,
+            lattice_vars(self, self.infcx().tvb,
                          a, a_id, b_id,
                          {|x, y| self.tys(x, y) })
           }
 
           (ty::ty_var(a_id), _) {
-            lattice_var_t(self, self.infcx().vb, a_id, b,
+            lattice_var_t(self, self.infcx().tvb, a_id, b,
                           {|x, y| self.tys(x, y) })
           }
 
           (_, ty::ty_var(b_id)) {
-            lattice_var_t(self, self.infcx().vb, b_id, a,
+            lattice_var_t(self, self.infcx().tvb, b_id, a,
                           {|x, y| self.tys(x, y) })
           }
 
diff --git a/src/rustc/util/ppaux.rs b/src/rustc/util/ppaux.rs
index 664bd268039..60f4ea8dabf 100644
--- a/src/rustc/util/ppaux.rs
+++ b/src/rustc/util/ppaux.rs
@@ -194,6 +194,7 @@ fn ty_to_str(cx: ctxt, typ: t) -> str {
                   f.output, f.ret_style, f.constraints)
       }
       ty_var(v) { v.to_str() }
+      ty_var_integral(v) { v.to_str() }
       ty_param(id, _) {
         "'" + str::from_bytes([('a' as u8) + (id as u8)])
       }