aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPatrick Walton <[email protected]>2011-04-21 12:10:53 -0700
committerPatrick Walton <[email protected]>2011-04-21 12:10:53 -0700
commitef0fcdd6300e9b5d78d7b86a1bdc2e849f68f935 (patch)
tree59e1d5dd503beac5ecd7e97b8f2cad5a783900b3 /src
parentrustc: Move ty.unify to a separate namespace (diff)
downloadrust-ef0fcdd6300e9b5d78d7b86a1bdc2e849f68f935.tar.xz
rust-ef0fcdd6300e9b5d78d7b86a1bdc2e849f68f935.zip
rustc: Create a unification context
Diffstat (limited to 'src')
-rw-r--r--src/comp/middle/ty.rs174
1 files changed, 75 insertions, 99 deletions
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index eed07098..0140e5e8 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -1552,9 +1552,10 @@ mod Unify {
ures_err(type_err, @ty.t, @ty.t);
}
- type var_bindings = rec(UFind.ufind sets,
- hashmap[int,uint] var_ids,
- mutable vec[mutable vec[@t]] types);
+ type ctxt = rec(UFind.ufind sets,
+ hashmap[int,uint] var_ids,
+ mutable vec[mutable vec[@t]] types,
+ unify_handler handler);
// Wraps the given type in an appropriate cname.
//
@@ -1592,10 +1593,9 @@ mod Unify {
fn_common_res_ok(vec[arg], @t);
}
- fn unify_fn_common(&var_bindings bindings,
+ fn unify_fn_common(@ctxt cx,
@ty.t expected,
@ty.t actual,
- &unify_handler handler,
vec[arg] expected_inputs, @t expected_output,
vec[arg] actual_inputs, @t actual_output)
-> fn_common_res {
@@ -1622,15 +1622,11 @@ mod Unify {
result_mode = ast.val;
}
- auto result = unify_step(bindings,
- actual_input.ty,
- expected_input.ty,
- handler);
+ auto result = unify_step(cx, actual_input.ty, expected_input.ty);
alt (result) {
case (ures_ok(?rty)) {
- result_ins += vec(rec(mode=result_mode,
- ty=rty));
+ result_ins += vec(rec(mode=result_mode, ty=rty));
}
case (_) {
@@ -1642,10 +1638,7 @@ mod Unify {
}
// Check the output.
- auto result = unify_step(bindings,
- expected_output,
- actual_output,
- handler);
+ auto result = unify_step(cx, expected_output, actual_output);
alt (result) {
case (ures_ok(?rty)) {
ret fn_common_res_ok(result_ins, rty);
@@ -1657,12 +1650,11 @@ mod Unify {
}
}
- fn unify_fn(&var_bindings bindings,
+ fn unify_fn(@ctxt cx,
ast.proto e_proto,
ast.proto a_proto,
@ty.t expected,
@ty.t actual,
- &unify_handler handler,
vec[arg] expected_inputs, @t expected_output,
vec[arg] actual_inputs, @t actual_output)
-> result {
@@ -1670,8 +1662,8 @@ mod Unify {
if (e_proto != a_proto) {
ret ures_err(terr_mismatch, expected, actual);
}
- auto t = unify_fn_common(bindings, expected, actual,
- handler, expected_inputs, expected_output,
+ auto t = unify_fn_common(cx, expected, actual,
+ expected_inputs, expected_output,
actual_inputs, actual_output);
alt (t) {
case (fn_common_res_err(?r)) {
@@ -1684,12 +1676,11 @@ mod Unify {
}
}
- fn unify_native_fn(&var_bindings bindings,
+ fn unify_native_fn(@ctxt cx,
ast.native_abi e_abi,
ast.native_abi a_abi,
@ty.t expected,
@ty.t actual,
- &unify_handler handler,
vec[arg] expected_inputs, @t expected_output,
vec[arg] actual_inputs, @t actual_output)
-> result {
@@ -1697,8 +1688,8 @@ mod Unify {
ret ures_err(terr_mismatch, expected, actual);
}
- auto t = unify_fn_common(bindings, expected, actual,
- handler, expected_inputs, expected_output,
+ auto t = unify_fn_common(cx, expected, actual,
+ expected_inputs, expected_output,
actual_inputs, actual_output);
alt (t) {
case (fn_common_res_err(?r)) {
@@ -1711,10 +1702,9 @@ mod Unify {
}
}
- fn unify_obj(&var_bindings bindings,
+ fn unify_obj(@ctxt cx,
@ty.t expected,
@ty.t actual,
- &unify_handler handler,
vec[method] expected_meths,
vec[method] actual_meths) -> result {
let vec[method] result_meths = vec();
@@ -1733,9 +1723,9 @@ mod Unify {
ret ures_err(terr_obj_meths(e_meth.ident, a_meth.ident),
expected, actual);
}
- auto r = unify_fn(bindings,
+ auto r = unify_fn(cx,
e_meth.proto, a_meth.proto,
- expected, actual, handler,
+ expected, actual,
e_meth.inputs, e_meth.output,
a_meth.inputs, a_meth.output);
alt (r) {
@@ -1758,20 +1748,19 @@ mod Unify {
ret ures_ok(t);
}
- fn get_or_create_set(&var_bindings bindings, int id) -> uint {
+ fn get_or_create_set(@ctxt cx, int id) -> uint {
auto set_num;
- alt (bindings.var_ids.find(id)) {
+ alt (cx.var_ids.find(id)) {
case (none[uint]) {
- set_num = UFind.make_set(bindings.sets);
- bindings.var_ids.insert(id, set_num);
+ set_num = UFind.make_set(cx.sets);
+ cx.var_ids.insert(id, set_num);
}
case (some[uint](?n)) { set_num = n; }
}
ret set_num;
}
- fn unify_step(&var_bindings bindings, @ty.t expected, @ty.t actual,
- &unify_handler handler) -> result {
+ fn unify_step(@ctxt cx, @ty.t expected, @ty.t actual) -> result {
// TODO: rewrite this using tuple pattern matching when available, to
// avoid all this rightward drift and spikiness.
@@ -1782,22 +1771,21 @@ mod Unify {
// If the RHS is a variable type, then just do the appropriate
// binding.
case (ty.ty_var(?actual_id)) {
- auto actual_n = get_or_create_set(bindings, actual_id);
+ auto actual_n = get_or_create_set(cx, actual_id);
alt (expected.struct) {
case (ty.ty_var(?expected_id)) {
- auto expected_n = get_or_create_set(bindings,
- expected_id);
- UFind.union(bindings.sets, expected_n, actual_n);
+ auto expected_n = get_or_create_set(cx, expected_id);
+ UFind.union(cx.sets, expected_n, actual_n);
}
case (_) {
// Just bind the type variable to the expected type.
- auto vlen = _vec.len[mutable vec[@t]](bindings.types);
+ auto vlen = _vec.len[mutable vec[@t]](cx.types);
if (actual_n < vlen) {
- bindings.types.(actual_n) += vec(expected);
+ cx.types.(actual_n) += vec(expected);
} else {
check (actual_n == vlen);
- bindings.types += vec(mutable vec(expected));
+ cx.types += vec(mutable vec(expected));
}
}
}
@@ -1805,13 +1793,10 @@ mod Unify {
}
case (ty.ty_local(?actual_id)) {
auto result_ty;
- alt (handler.resolve_local(actual_id)) {
+ alt (cx.handler.resolve_local(actual_id)) {
case (none[@ty.t]) { result_ty = expected; }
case (some[@ty.t](?actual_ty)) {
- auto result = unify_step(bindings,
- expected,
- actual_ty,
- handler);
+ auto result = unify_step(cx, expected, actual_ty);
alt (result) {
case (ures_ok(?rty)) { result_ty = rty; }
case (_) { ret result; }
@@ -1819,7 +1804,7 @@ mod Unify {
}
}
- handler.record_local(actual_id, result_ty);
+ cx.handler.record_local(actual_id, result_ty);
ret ures_ok(result_ty);
}
case (ty.ty_bound_param(?actual_id)) {
@@ -1830,7 +1815,7 @@ mod Unify {
}
case (_) {
- ret handler.record_param(actual_id, expected);
+ ret cx.handler.record_param(actual_id, expected);
}
}
}
@@ -1867,10 +1852,9 @@ mod Unify {
auto expected_tp = expected_tps.(i);
auto actual_tp = actual_tps.(i);
- auto result = unify_step(bindings,
+ auto result = unify_step(cx,
expected_tp,
- actual_tp,
- handler);
+ actual_tp);
alt (result) {
case (ures_ok(?rty)) {
@@ -1904,10 +1888,9 @@ mod Unify {
case (some[ast.mutability](?m)) { mut = m; }
}
- auto result = unify_step(bindings,
+ auto result = unify_step(cx,
expected_mt.ty,
- actual_mt.ty,
- handler);
+ actual_mt.ty);
alt (result) {
case (ures_ok(?result_sub)) {
auto mt = rec(ty=result_sub, mut=mut);
@@ -1937,10 +1920,9 @@ mod Unify {
case (some[ast.mutability](?m)) { mut = m; }
}
- auto result = unify_step(bindings,
+ auto result = unify_step(cx,
expected_mt.ty,
- actual_mt.ty,
- handler);
+ actual_mt.ty);
alt (result) {
case (ures_ok(?result_sub)) {
auto mt = rec(ty=result_sub, mut=mut);
@@ -1961,10 +1943,9 @@ mod Unify {
case (ty.ty_port(?expected_sub)) {
alt (actual.struct) {
case (ty.ty_port(?actual_sub)) {
- auto result = unify_step(bindings,
+ auto result = unify_step(cx,
expected_sub,
- actual_sub,
- handler);
+ actual_sub);
alt (result) {
case (ures_ok(?result_sub)) {
ret ures_ok(mk_port(result_sub));
@@ -1984,10 +1965,9 @@ mod Unify {
case (ty.ty_chan(?expected_sub)) {
alt (actual.struct) {
case (ty.ty_chan(?actual_sub)) {
- auto result = unify_step(bindings,
+ auto result = unify_step(cx,
expected_sub,
- actual_sub,
- handler);
+ actual_sub);
alt (result) {
case (ures_ok(?result_sub)) {
ret ures_ok(mk_chan(result_sub));
@@ -2033,10 +2013,9 @@ mod Unify {
case (some[ast.mutability](?m)) { mut = m; }
}
- auto result = unify_step(bindings,
+ auto result = unify_step(cx,
expected_elem.ty,
- actual_elem.ty,
- handler);
+ actual_elem.ty);
alt (result) {
case (ures_ok(?rty)) {
auto mt = rec(ty=rty, mut=mut);
@@ -2096,10 +2075,9 @@ mod Unify {
ret ures_err(err, expected, actual);
}
- auto result = unify_step(bindings,
+ auto result = unify_step(cx,
expected_field.mt.ty,
- actual_field.mt.ty,
- handler);
+ actual_field.mt.ty);
alt (result) {
case (ures_ok(?rty)) {
auto mt = rec(ty=rty, mut=mut);
@@ -2127,8 +2105,8 @@ mod Unify {
case (ty.ty_fn(?ep, ?expected_inputs, ?expected_output)) {
alt (actual.struct) {
case (ty.ty_fn(?ap, ?actual_inputs, ?actual_output)) {
- ret unify_fn(bindings, ep, ap,
- expected, actual, handler,
+ ret unify_fn(cx, ep, ap,
+ expected, actual,
expected_inputs, expected_output,
actual_inputs, actual_output);
}
@@ -2144,8 +2122,8 @@ mod Unify {
alt (actual.struct) {
case (ty.ty_native_fn(?a_abi, ?actual_inputs,
?actual_output)) {
- ret unify_native_fn(bindings, e_abi, a_abi,
- expected, actual, handler,
+ ret unify_native_fn(cx, e_abi, a_abi,
+ expected, actual,
expected_inputs, expected_output,
actual_inputs, actual_output);
}
@@ -2158,7 +2136,7 @@ mod Unify {
case (ty.ty_obj(?expected_meths)) {
alt (actual.struct) {
case (ty.ty_obj(?actual_meths)) {
- ret unify_obj(bindings, expected, actual, handler,
+ ret unify_obj(cx, expected, actual,
expected_meths, actual_meths);
}
case (_) {
@@ -2169,26 +2147,23 @@ mod Unify {
case (ty.ty_var(?expected_id)) {
// Add a binding.
- auto expected_n = get_or_create_set(bindings, expected_id);
- auto vlen = _vec.len[mutable vec[@t]](bindings.types);
+ auto expected_n = get_or_create_set(cx, expected_id);
+ auto vlen = _vec.len[mutable vec[@t]](cx.types);
if (expected_n < vlen) {
- bindings.types.(expected_n) += vec(actual);
+ cx.types.(expected_n) += vec(actual);
} else {
check (expected_n == vlen);
- bindings.types += vec(mutable vec(actual));
+ cx.types += vec(mutable vec(actual));
}
ret ures_ok(expected);
}
case (ty.ty_local(?expected_id)) {
auto result_ty;
- alt (handler.resolve_local(expected_id)) {
+ alt (cx.handler.resolve_local(expected_id)) {
case (none[@ty.t]) { result_ty = actual; }
case (some[@ty.t](?expected_ty)) {
- auto result = unify_step(bindings,
- expected_ty,
- actual,
- handler);
+ auto result = unify_step(cx, expected_ty, actual);
alt (result) {
case (ures_ok(?rty)) { result_ty = rty; }
case (_) { ret result; }
@@ -2196,12 +2171,12 @@ mod Unify {
}
}
- handler.record_local(expected_id, result_ty);
+ cx.handler.record_local(expected_id, result_ty);
ret ures_ok(result_ty);
}
case (ty.ty_bound_param(?expected_id)) {
- ret handler.record_param(expected_id, actual);
+ ret cx.handler.record_param(expected_id, actual);
}
}
@@ -2210,13 +2185,13 @@ mod Unify {
}
// Performs type binding substitution.
- fn substitute(var_bindings bindings, vec[@t] set_types, @t typ) -> @t {
- fn substituter(var_bindings bindings, vec[@t] types, @t typ) -> @t {
+ fn substitute(@ctxt cx, vec[@t] set_types, @t typ) -> @t {
+ fn substituter(@ctxt cx, vec[@t] types, @t typ) -> @t {
alt (typ.struct) {
case (ty_var(?id)) {
- alt (bindings.var_ids.find(id)) {
+ alt (cx.var_ids.find(id)) {
case (some[uint](?n)) {
- auto root = UFind.find(bindings.sets, n);
+ auto root = UFind.find(cx.sets, n);
ret types.(root);
}
case (none[uint]) { ret typ; }
@@ -2226,24 +2201,24 @@ mod Unify {
}
}
- auto f = bind substituter(bindings, set_types, _);
+ auto f = bind substituter(cx, set_types, _);
ret fold_ty(f, typ);
}
- fn unify_sets(&var_bindings bindings) -> vec[@t] {
+ fn unify_sets(@ctxt cx) -> vec[@t] {
let vec[@t] throwaway = vec();
let vec[mutable vec[@t]] set_types = vec(mutable throwaway);
_vec.pop[mutable vec[@t]](set_types); // FIXME: botch
- for (UFind.node node in bindings.sets.nodes) {
+ for (UFind.node node in cx.sets.nodes) {
let vec[@t] v = vec();
set_types += vec(mutable v);
}
auto i = 0u;
while (i < _vec.len[mutable vec[@t]](set_types)) {
- auto root = UFind.find(bindings.sets, i);
- set_types.(root) += bindings.types.(i);
+ auto root = UFind.find(cx.sets, i);
+ set_types.(root) += cx.types.(i);
i += 1u;
}
@@ -2266,15 +2241,16 @@ mod Unify {
let vec[mutable vec[@t]] types = vec(mutable throwaway);
_vec.pop[mutable vec[@t]](types); // FIXME: botch
- auto bindings = rec(sets=UFind.make(),
- var_ids=common.new_int_hash[uint](),
- mutable types=types);
+ auto cx = @rec(sets=UFind.make(),
+ var_ids=common.new_int_hash[uint](),
+ mutable types=types,
+ handler=handler);
- auto ures = unify_step(bindings, expected, actual, handler);
+ auto ures = unify_step(cx, expected, actual);
alt (ures) {
case (ures_ok(?t)) {
- auto set_types = unify_sets(bindings);
- auto t2 = substitute(bindings, set_types, t);
+ auto set_types = unify_sets(cx);
+ auto t2 = substitute(cx, set_types, t);
ret ures_ok(t2);
}
case (_) { ret ures; }