]> git.lizzy.rs Git - rust.git/commitdiff
rustc: Generalize variable bindings so that we can use it for locals too
authorPatrick Walton <pcwalton@mimiga.net>
Thu, 19 May 2011 18:14:04 +0000 (11:14 -0700)
committerPatrick Walton <pcwalton@mimiga.net>
Thu, 19 May 2011 18:14:44 +0000 (11:14 -0700)
src/comp/middle/ty.rs
src/comp/middle/typeck.rs
src/lib/int.rs

index 6b2ee1441bbabc9de515e82dfbeec193a942a3ec..65d603895a3fd22435823a84302467175997ff73 100644 (file)
@@ -1865,18 +1865,19 @@ mod unify {
         ures_err(type_err, t, t);
     }
 
-    type var_bindings = rec(ufind::ufind sets,
-                            hashmap[int,uint] var_ids,
-                            mutable vec[mutable vec[t]] types);
+    type bindings[T] = rec(ufind::ufind sets,
+                           hashmap[T,uint] ids,
+                           mutable vec[mutable vec[t]] types);
 
-    fn mk_var_bindings() -> @var_bindings {
+    fn mk_bindings[T](map::hashfn[T] hasher, map::eqfn[T] eqer)
+            -> @bindings[T] {
         let vec[mutable vec[t]] types = [mutable];
         ret @rec(sets=ufind::make(),
-                 var_ids=common::new_int_hash[uint](),
+                 ids=map::mk_hashmap[T,uint](hasher, eqer),
                  mutable types=types);
     }
 
-    type ctxt = rec(@var_bindings var_bindings,
+    type ctxt = rec(@bindings[int] bindings,
                     unify_handler handler,
                     ty_ctxt tcx);
 
@@ -2079,10 +2080,10 @@ fn unify_obj(&@ctxt cx,
 
     fn get_or_create_set(&@ctxt cx, int id) -> uint {
         auto set_num;
-        alt (cx.var_bindings.var_ids.find(id)) {
+        alt (cx.bindings.ids.find(id)) {
             case (none[uint]) {
-                set_num = ufind::make_set(cx.var_bindings.sets);
-                cx.var_bindings.var_ids.insert(id, set_num);
+                set_num = ufind::make_set(cx.bindings.sets);
+                cx.bindings.ids.insert(id, set_num);
             }
             case (some[uint](?n)) { set_num = n; }
         }
@@ -2107,18 +2108,17 @@ fn unify_step(&@ctxt cx, &t expected, &t actual) -> result {
                 alt (struct(cx.tcx, expected)) {
                     case (ty::ty_var(?expected_id)) {
                         auto expected_n = get_or_create_set(cx, expected_id);
-                        ufind::union(cx.var_bindings.sets, expected_n,
-                                     actual_n);
+                        ufind::union(cx.bindings.sets, expected_n, actual_n);
                     }
 
                     case (_) {
                         // Just bind the type variable to the expected type.
-                        auto vlen = vec::len[vec[t]](cx.var_bindings.types);
+                        auto vlen = vec::len[vec[t]](cx.bindings.types);
                         if (actual_n < vlen) {
-                            cx.var_bindings.types.(actual_n) += [expected];
+                            cx.bindings.types.(actual_n) += [expected];
                         } else {
                             assert (actual_n == vlen);
-                            cx.var_bindings.types += [mutable [expected]];
+                            cx.bindings.types += [mutable [expected]];
                         }
                     }
                 }
@@ -2482,12 +2482,12 @@ fn unify_step(&@ctxt cx, &t expected, &t actual) -> result {
             case (ty::ty_var(?expected_id)) {
                 // Add a binding.
                 auto expected_n = get_or_create_set(cx, expected_id);
-                auto vlen = vec::len[vec[t]](cx.var_bindings.types);
+                auto vlen = vec::len[vec[t]](cx.bindings.types);
                 if (expected_n < vlen) {
-                    cx.var_bindings.types.(expected_n) += [actual];
+                    cx.bindings.types.(expected_n) += [actual];
                 } else {
                     assert (expected_n == vlen);
-                    cx.var_bindings.types += [mutable [actual]];
+                    cx.bindings.types += [mutable [actual]];
                 }
                 ret ures_ok(expected);
             }
@@ -2519,19 +2519,23 @@ fn unify_step(&@ctxt cx, &t expected, &t actual) -> result {
     }
 
     // Performs type binding substitution.
-    fn substitute(&ty_ctxt tcx, &@var_bindings var_bindings,
-                  &vec[t] set_types, &t typ) -> t {
+    fn substitute(&ty_ctxt tcx,
+                  &@bindings[int] bindings,
+                  &vec[t] set_types,
+                  &t typ) -> t {
         if (!type_contains_vars(tcx, typ)) {
             ret typ;
         }
 
-        fn substituter(ty_ctxt tcx, @var_bindings var_bindings, vec[t] types,
+        fn substituter(ty_ctxt tcx,
+                       @bindings[int] bindings,
+                       vec[t] types,
                        t typ) -> t {
             alt (struct(tcx, typ)) {
                 case (ty_var(?id)) {
-                    alt (var_bindings.var_ids.find(id)) {
+                    alt (bindings.ids.find(id)) {
                         case (some[uint](?n)) {
-                            auto root = ufind::find(var_bindings.sets, n);
+                            auto root = ufind::find(bindings.sets, n);
                             ret types.(root);
                         }
                         case (none[uint]) { ret typ; }
@@ -2541,24 +2545,22 @@ fn substituter(ty_ctxt tcx, @var_bindings var_bindings, vec[t] types,
             }
         }
 
-        auto f = bind substituter(tcx, var_bindings, set_types, _);
+        auto f = bind substituter(tcx, bindings, set_types, _);
         ret fold_ty(tcx, f, typ);
     }
 
-    fn unify_sets(&@var_bindings var_bindings) -> vec[t] {
-        let vec[t] throwaway = [];
-        let vec[mutable vec[t]] set_types = [mutable throwaway];
-        vec::pop[vec[t]](set_types);   // FIXME: botch
+    fn unify_sets[T](&@bindings[T] bindings) -> vec[t] {
+        let vec[mutable vec[t]] set_types = [mutable];
 
-        for (ufind::node node in var_bindings.sets.nodes) {
+        for (ufind::node node in bindings.sets.nodes) {
             let vec[t] v = [];
             set_types += [mutable v];
         }
 
         auto i = 0u;
         while (i < vec::len[vec[t]](set_types)) {
-            auto root = ufind::find(var_bindings.sets, i);
-            set_types.(root) += var_bindings.types.(i);
+            auto root = ufind::find(bindings.sets, i);
+            set_types.(root) += bindings.types.(i);
             i += 1u;
         }
 
@@ -2578,15 +2580,15 @@ fn unify_sets(&@var_bindings var_bindings) -> vec[t] {
     fn unify(&t expected,
              &t actual,
              &unify_handler handler,
-             &@var_bindings var_bindings,
+             &@bindings[int] bindings,
              &ty_ctxt tcx) -> result {
-        auto cx = @rec(var_bindings=var_bindings, handler=handler, tcx=tcx);
+        auto cx = @rec(bindings=bindings, handler=handler, tcx=tcx);
         ret unify_step(cx, expected, actual);
     }
 
-    fn fixup(&ty_ctxt tcx, &@var_bindings var_bindings, t typ) -> t {
-        auto set_types = unify_sets(var_bindings);
-        ret substitute(tcx, var_bindings, set_types, typ);
+    fn fixup(&ty_ctxt tcx, &@bindings[int] bindings, t typ) -> t {
+        auto set_types = unify_sets[int](bindings);
+        ret substitute(tcx, bindings, set_types, typ);
     }
 }
 
index dbad2715776e634cafd2f77054bd12e2133537e5..72c22ab691c4ecd648fafbe22de03bd1fa28503f 100644 (file)
@@ -37,6 +37,7 @@
 import middle::ty::unify::ures_ok;
 import middle::ty::unify::ures_err;
 
+import std::int;
 import std::str;
 import std::uint;
 import std::vec;
@@ -969,15 +970,15 @@ fn record_param(uint index, ty::t binding) -> ty::unify::result {
 
         auto handler = unify_handler(scx, param_substs);
 
-        auto var_bindings = ty::unify::mk_var_bindings();
-        auto result = ty::unify::unify(expected, actual, handler,
-                                       var_bindings, scx.fcx.ccx.tcx);
+        auto bindings = ty::unify::mk_bindings[int](int::hash, int::eq_alias);
+        auto result = ty::unify::unify(expected, actual, handler, bindings,
+                                       scx.fcx.ccx.tcx);
 
         alt (result) {
             case (ures_ok(?rty)) {
                 if (ty::type_contains_vars(scx.fcx.ccx.tcx, rty)) {
                     result = ures_ok(ty::unify::fixup(scx.fcx.ccx.tcx,
-                                                      var_bindings, rty));
+                                                      bindings, rty));
                 }
             }
             case (_) { /* nothing */ }
index 1e253b3857cbe6cfcfdd1dc567f81fe7c05cb952..23aabbc6cd9812bb5173b2900c318f4530ef5552 100644 (file)
 fn nonpositive(int x) -> bool { ret x <= 0; }
 fn nonnegative(int x) -> bool { ret x >= 0; }
 
+// FIXME: Make sure this works with negative integers.
+fn hash(&int x) -> uint { ret x as uint; }
+fn eq_alias(&int x, &int y) -> bool { ret x == y; }
+
 iter range(int lo, int hi) -> int {
     let int lo_ = lo;
     while (lo_ < hi) {