aboutsummaryrefslogtreecommitdiff
path: root/src/comp
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2010-12-31 09:48:54 -0800
committerGraydon Hoare <[email protected]>2010-12-31 09:48:54 -0800
commitaa1d8d07687ef686c214044d11780a13b4b958e2 (patch)
tree2b8b72afc917f229c6eff8d8c164a14da03dcfac /src/comp
parentTeach typeck.ast_ty_to_ty about ty_obj. (diff)
downloadrust-aa1d8d07687ef686c214044d11780a13b4b958e2.tar.xz
rust-aa1d8d07687ef686c214044d11780a13b4b958e2.zip
Move unify_fn logic out-of-line.
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/middle/ty.rs131
1 files changed, 72 insertions, 59 deletions
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index 4dbd236f..b7ddfe14 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -655,6 +655,75 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
ret ures_err(terr_mismatch, expected, actual);
}
+ fn unify_fn(&hashmap[int,@ty.t] bindings,
+ @ty.t expected,
+ @ty.t actual,
+ &unify_handler handler,
+ vec[arg] expected_inputs, @t expected_output,
+ vec[arg] actual_inputs, @t actual_output)
+ -> unify_result {
+ auto expected_len = _vec.len[arg](expected_inputs);
+ auto actual_len = _vec.len[arg](actual_inputs);
+ if (expected_len != actual_len) {
+ ret ures_err(terr_arg_count, expected, actual);
+ }
+
+ // TODO: as above, we should have an iter2 iterator.
+ let vec[arg] result_ins = vec();
+ auto i = 0u;
+ while (i < expected_len) {
+ auto expected_input = expected_inputs.(i);
+ auto actual_input = actual_inputs.(i);
+
+ // This should be safe, I think?
+ auto result_mode;
+ if (mode_is_alias(expected_input.mode) ||
+ mode_is_alias(actual_input.mode)) {
+ result_mode = ast.alias;
+ } else {
+ result_mode = ast.val;
+ }
+
+ auto result = unify_step(bindings,
+ actual_input.ty,
+ expected_input.ty,
+ handler);
+
+ alt (result) {
+ case (ures_ok(?rty)) {
+ result_ins += vec(rec(mode=result_mode,
+ ty=rty));
+ }
+
+ case (_) {
+ ret result;
+ }
+ }
+
+ i += 1u;
+ }
+
+ // Check the output.
+ auto result_out;
+ auto result = unify_step(bindings,
+ expected_output,
+ actual_output,
+ handler);
+ alt (result) {
+ case (ures_ok(?rty)) {
+ result_out = rty;
+ }
+
+ case (_) {
+ ret result;
+ }
+ }
+
+ auto t = plain_ty(ty.ty_fn(result_ins, result_out));
+ ret ures_ok(t);
+
+ }
+
fn unify_step(&hashmap[int,@ty.t] bindings, @ty.t expected, @ty.t actual,
&unify_handler handler) -> unify_result {
// TODO: rewrite this using tuple pattern matching when available, to
@@ -881,65 +950,9 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
case (ty.ty_fn(?expected_inputs, ?expected_output)) {
alt (actual.struct) {
case (ty.ty_fn(?actual_inputs, ?actual_output)) {
- auto expected_len = _vec.len[arg](expected_inputs);
- auto actual_len = _vec.len[arg](actual_inputs);
- if (expected_len != actual_len) {
- ret ures_err(terr_arg_count, expected, actual);
- }
-
- // TODO: as above, we should have an iter2 iterator.
- let vec[arg] result_ins = vec();
- auto i = 0u;
- while (i < expected_len) {
- auto expected_input = expected_inputs.(i);
- auto actual_input = actual_inputs.(i);
-
- // This should be safe, I think?
- auto result_mode;
- if (mode_is_alias(expected_input.mode) ||
- mode_is_alias(actual_input.mode)) {
- result_mode = ast.alias;
- } else {
- result_mode = ast.val;
- }
-
- auto result = unify_step(bindings,
- actual_input.ty,
- expected_input.ty,
- handler);
-
- alt (result) {
- case (ures_ok(?rty)) {
- result_ins += vec(rec(mode=result_mode,
- ty=rty));
- }
-
- case (_) {
- ret result;
- }
- }
-
- i += 1u;
- }
-
- // Check the output.
- auto result_out;
- auto result = unify_step(bindings,
- expected_output,
- actual_output,
- handler);
- alt (result) {
- case (ures_ok(?rty)) {
- result_out = rty;
- }
-
- case (_) {
- ret result;
- }
- }
-
- auto t = plain_ty(ty.ty_fn(result_ins, result_out));
- ret ures_ok(t);
+ ret unify_fn(bindings, expected, actual, handler,
+ expected_inputs, expected_output,
+ actual_inputs, actual_output);
}
case (_) {