about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2011-02-07 14:11:43 -0800
committerGraydon Hoare <graydon@mozilla.com>2011-02-07 14:11:43 -0800
commitd7f118135b8a3eee7c8788052542e6e1c205a3d9 (patch)
tree89e0f6a5e43d270fa91b6e4cf88933ff725de3c6
parent3e613c1648141ac757d1f0608ad845686ebbe97e (diff)
downloadrust-d7f118135b8a3eee7c8788052542e6e1c205a3d9.tar.gz
rust-d7f118135b8a3eee7c8788052542e6e1c205a3d9.zip
Iterate type unification to drive the types a bit further down into the leaves of results with residual vars. Cheap but kinda works.
-rw-r--r--src/comp/middle/ty.rs34
1 files changed, 33 insertions, 1 deletions
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index 2f14aae6259..92fa13997a3 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -551,6 +551,24 @@ fn count_ty_params(@t ty) -> uint {
     ret _vec.len[ast.def_id](*param_ids);
 }
 
+fn type_contains_ty_vars(@t ty) -> bool {
+    state obj checker(@mutable bool has_vars) {
+        fn fold_simple_ty(@t ty) -> @t {
+            alt (ty.struct) {
+                case (ty_var(_)) {
+                    *has_vars = true;
+                }
+                case (_) {}
+            }
+            ret ty;
+        }
+    }
+
+    let @mutable bool b = @mutable false;
+    fold_ty(checker(b), ty);
+    ret *b;
+}
+
 // Type accessors for substructures of types
 
 fn ty_fn_args(@t fty) -> vec[arg] {
@@ -1197,7 +1215,21 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
     auto eqer = eq_int;
     auto bindings = map.mk_hashmap[int,@ty.t](hasher, eqer);
 
-    ret unify_step(bindings, expected, actual, handler);
+    auto ures = unify_step(bindings, expected, actual, handler);
+    while (true) {
+        alt (ures) {
+            case (ures_ok(?t)) {
+                if (!type_contains_ty_vars(t)) {
+                    ret ures;
+                }
+                ures = unify_step(bindings, t, actual, handler);
+            }
+            case (_) {
+                ret ures;
+            }
+        }
+    }
+    fail;
 }
 
 fn type_err_to_str(&ty.type_err err) -> str {