about summary refs log tree commit diff
path: root/src/comp/middle
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2011-06-22 20:39:14 -0700
committerBrian Anderson <banderson@mozilla.com>2011-06-22 20:43:50 -0700
commitd2b7ea877c6290094a977d17ddb2ae9853de507b (patch)
treec52ed66aceba0ed7cdb85dc90f23417dd5fc6337 /src/comp/middle
parentd9b56ec2eab88de55748d6b46ce8cf22d29dd9a5 (diff)
downloadrust-d2b7ea877c6290094a977d17ddb2ae9853de507b.tar.gz
rust-d2b7ea877c6290094a977d17ddb2ae9853de507b.zip
rustc: Don't commit unification changes until unify succeeds
This is so that subsequent reports about type mismatches get the types
correct.

Issue #516
Diffstat (limited to 'src/comp/middle')
-rw-r--r--src/comp/middle/ty.rs24
1 files changed, 16 insertions, 8 deletions
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index a9f23887075..9a6fd4bbd92 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -1878,14 +1878,21 @@ mod unify {
         ufind::grow(cx.vb.sets, uint::max(set_a, set_b) + 1u);
         auto root_a = ufind::find(cx.vb.sets, set_a);
         auto root_b = ufind::find(cx.vb.sets, set_b);
-        ufind::union(cx.vb.sets, set_a, set_b);
-        auto root_c = ufind::find(cx.vb.sets, set_a);
+
+        auto replace_type = bind fn (&@ctxt cx, t t, uint set_a, uint set_b) {
+            ufind::union(cx.vb.sets, set_a, set_b);
+            let uint root_c = ufind::find(cx.vb.sets, set_a);
+            smallintmap::insert[t](cx.vb.types, root_c, t);
+        } (_, _, set_a, set_b);
+
         alt (smallintmap::find[t](cx.vb.types, root_a)) {
             case (none[t]) {
                 alt (smallintmap::find[t](cx.vb.types, root_b)) {
-                    case (none[t]) { ret unres_ok; }
+                    case (none[t]) {
+                        ufind::union(cx.vb.sets, set_a, set_b);
+                        ret unres_ok; }
                     case (some[t](?t_b)) {
-                        smallintmap::insert[t](cx.vb.types, root_c, t_b);
+                        replace_type(cx, t_b);
                         ret unres_ok;
                     }
                 }
@@ -1893,17 +1900,18 @@ mod unify {
             case (some[t](?t_a)) {
                 alt (smallintmap::find[t](cx.vb.types, root_b)) {
                     case (none[t]) {
-                        smallintmap::insert[t](cx.vb.types, root_c, t_a);
+                        replace_type(cx, t_a);
                         ret unres_ok;
                     }
                     case (some[t](?t_b)) {
                         alt (unify_step(cx, t_a, t_b)) {
                             case (ures_ok(?t_c)) {
-                                smallintmap::insert[t](cx.vb.types, root_c,
-                                                       t_c);
+                                replace_type(cx, t_c);
                                 ret unres_ok;
                             }
-                            case (ures_err(?terr)) { ret unres_err(terr); }
+                            case (ures_err(?terr)) {
+                                ret unres_err(terr);
+                            }
                         }
                     }
                 }