diff options
| author | Graydon Hoare <[email protected]> | 2011-02-07 14:11:43 -0800 |
|---|---|---|
| committer | Graydon Hoare <[email protected]> | 2011-02-07 14:11:43 -0800 |
| commit | d7f118135b8a3eee7c8788052542e6e1c205a3d9 (patch) | |
| tree | 89e0f6a5e43d270fa91b6e4cf88933ff725de3c6 /src | |
| parent | Add native modules to resolve. With this hello world gets to typecheck. (diff) | |
| download | rust-d7f118135b8a3eee7c8788052542e6e1c205a3d9.tar.xz 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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp/middle/ty.rs | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 2f14aae6..92fa1399 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 { |