Skip to content

Commit c13f008

Browse files
committed
---
yaml --- r: 2655 b: refs/heads/master c: bc87ecf h: refs/heads/master i: 2653: 4c33d8a 2651: 6b501d7 2647: 6bda5e6 2639: 40c60a2 2623: 766a3c9 v: v3
1 parent eb93b04 commit c13f008

File tree

3 files changed

+107
-45
lines changed

3 files changed

+107
-45
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 6b95584df5c878f716743eb9c60ad5df77af8b18
2+
refs/heads/master: bc87ecf11086704744f554a6d4b1ba323a89a7a0

trunk/src/comp/middle/ty.rs

Lines changed: 105 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import std::int;
12
import std::str;
23
import std::uint;
34
import std::vec;
@@ -1878,18 +1879,48 @@ mod unify {
18781879
ures_err(type_err, t, t);
18791880
}
18801881

1882+
tag set_result {
1883+
usr_ok(vec[t]);
1884+
usr_err(type_err, t, t);
1885+
}
1886+
18811887
type bindings[T] = rec(ufind::ufind sets,
18821888
hashmap[T,uint] ids,
1883-
mutable vec[mutable vec[t]] types);
1889+
mutable vec[mutable option::t[t]] types);
18841890

18851891
fn mk_bindings[T](map::hashfn[T] hasher, map::eqfn[T] eqer)
18861892
-> @bindings[T] {
1887-
let vec[mutable vec[t]] types = [mutable];
1893+
let vec[mutable option::t[t]] types = [mutable];
18881894
ret @rec(sets=ufind::make(),
18891895
ids=map::mk_hashmap[T,uint](hasher, eqer),
18901896
mutable types=types);
18911897
}
18921898

1899+
fn record_binding[T](&@ctxt cx, &@bindings[T] bindings, &T key, t typ)
1900+
-> result {
1901+
auto n = get_or_create_set[T](bindings, key);
1902+
1903+
auto result_type = typ;
1904+
if (n < vec::len[option::t[t]](bindings.types)) {
1905+
alt (bindings.types.(n)) {
1906+
case (some[t](?old_type)) {
1907+
alt (unify_step(cx, old_type, typ)) {
1908+
case (ures_ok(?unified_type)) {
1909+
result_type = unified_type;
1910+
}
1911+
case (?res) { ret res; }
1912+
}
1913+
}
1914+
case (none[t]) { /* fall through */ }
1915+
}
1916+
}
1917+
1918+
vec::grow_set[option::t[t]](bindings.types, n, none[t],
1919+
some[t](result_type));
1920+
1921+
ret ures_ok(typ);
1922+
}
1923+
18931924
type ctxt = rec(@bindings[int] bindings,
18941925
unify_handler handler,
18951926
ty_ctxt tcx);
@@ -2091,12 +2122,12 @@ mod unify {
20912122
ret ures_ok(t);
20922123
}
20932124

2094-
fn get_or_create_set(&@ctxt cx, int id) -> uint {
2125+
fn get_or_create_set[T](&@bindings[T] bindings, &T key) -> uint {
20952126
auto set_num;
2096-
alt (cx.bindings.ids.find(id)) {
2127+
alt (bindings.ids.find(key)) {
20972128
case (none[uint]) {
2098-
set_num = ufind::make_set(cx.bindings.sets);
2099-
cx.bindings.ids.insert(id, set_num);
2129+
set_num = ufind::make_set(bindings.sets);
2130+
bindings.ids.insert(key, set_num);
21002131
}
21012132
case (some[uint](?n)) { set_num = n; }
21022133
}
@@ -2117,21 +2148,21 @@ mod unify {
21172148
// If the RHS is a variable type, then just do the appropriate
21182149
// binding.
21192150
case (ty::ty_var(?actual_id)) {
2120-
auto actual_n = get_or_create_set(cx, actual_id);
2151+
auto actual_n = get_or_create_set[int](cx.bindings,
2152+
actual_id);
21212153
alt (struct(cx.tcx, expected)) {
21222154
case (ty::ty_var(?expected_id)) {
2123-
auto expected_n = get_or_create_set(cx, expected_id);
2155+
auto expected_n = get_or_create_set[int](cx.bindings,
2156+
expected_id);
21242157
ufind::union(cx.bindings.sets, expected_n, actual_n);
21252158
}
21262159

21272160
case (_) {
21282161
// Just bind the type variable to the expected type.
2129-
auto vlen = vec::len[vec[t]](cx.bindings.types);
2130-
if (actual_n < vlen) {
2131-
cx.bindings.types.(actual_n) += [expected];
2132-
} else {
2133-
assert (actual_n == vlen);
2134-
cx.bindings.types += [mutable [expected]];
2162+
alt (record_binding[int](cx, cx.bindings, actual_id,
2163+
expected)) {
2164+
case (ures_ok(_)) { /* fall through */ }
2165+
case (?res) { ret res; }
21352166
}
21362167
}
21372168
}
@@ -2493,14 +2524,11 @@ mod unify {
24932524
}
24942525

24952526
case (ty::ty_var(?expected_id)) {
2496-
// Add a binding.
2497-
auto expected_n = get_or_create_set(cx, expected_id);
2498-
auto vlen = vec::len[vec[t]](cx.bindings.types);
2499-
if (expected_n < vlen) {
2500-
cx.bindings.types.(expected_n) += [actual];
2501-
} else {
2502-
assert (expected_n == vlen);
2503-
cx.bindings.types += [mutable [actual]];
2527+
// Add a binding. (`actual` can't actually be a var here.)
2528+
alt (record_binding[int](cx, cx.bindings, expected_id,
2529+
actual)) {
2530+
case (ures_ok(_)) { /* fall through */ }
2531+
case (?res) { ret res; }
25042532
}
25052533
ret ures_ok(expected);
25062534
}
@@ -2562,32 +2590,63 @@ mod unify {
25622590
ret fold_ty(tcx, f, typ);
25632591
}
25642592

2565-
fn unify_sets[T](&@bindings[T] bindings) -> vec[t] {
2566-
let vec[mutable vec[t]] set_types = [mutable];
2567-
2568-
for (ufind::node node in bindings.sets.nodes) {
2569-
let vec[t] v = [];
2570-
set_types += [mutable v];
2593+
fn unify_sets[T](&ty_ctxt tcx, &@bindings[T] bindings) -> set_result {
2594+
obj handler() {
2595+
fn resolve_local(ast::def_id id) -> option::t[t] {
2596+
log_err "resolve_local in unify_sets";
2597+
fail;
2598+
}
2599+
fn record_local(ast::def_id id, t ty) {
2600+
log_err "record_local in unify_sets";
2601+
fail;
2602+
}
2603+
fn record_param(uint index, t binding) -> unify::result {
2604+
log_err "record_param in unify_sets";
2605+
fail;
2606+
}
25712607
}
25722608

2609+
auto node_count = vec::len[option::t[t]](bindings.types);
2610+
2611+
let vec[option::t[t]] results =
2612+
vec::init_elt[option::t[t]](none[t], node_count);
2613+
25732614
auto i = 0u;
2574-
while (i < vec::len[vec[t]](set_types)) {
2615+
while (i < node_count) {
25752616
auto root = ufind::find(bindings.sets, i);
2576-
set_types.(root) += bindings.types.(i);
2617+
alt (bindings.types.(i)) {
2618+
case (none[t]) { /* nothing to do */ }
2619+
case (some[t](?actual)) {
2620+
alt (results.(root)) {
2621+
case (none[t]) { results.(root) = some[t](actual); }
2622+
case (some[t](?expected)) {
2623+
// FIXME: Is this right?
2624+
auto bindings = mk_bindings[int](int::hash,
2625+
int::eq_alias);
2626+
alt (unify(expected, actual, handler(), bindings,
2627+
tcx)) {
2628+
case (ures_ok(?result_ty)) {
2629+
results.(i) = some[t](result_ty);
2630+
}
2631+
case (ures_err(?e, ?t_a, ?t_b)) {
2632+
ret usr_err(e, t_a, t_b);
2633+
}
2634+
}
2635+
}
2636+
}
2637+
}
2638+
}
25772639
i += 1u;
25782640
}
25792641

2580-
let vec[t] result = [];
2581-
for (vec[t] types in set_types) {
2582-
if (vec::len[t](types) > 1u) {
2583-
log_err "unification of > 1 types in a type set is " +
2584-
"unimplemented";
2585-
fail;
2586-
}
2587-
result += [types.(0)];
2642+
// FIXME: This is equivalent to map(option::get, results) but it
2643+
// causes an assertion in typeck at the moment.
2644+
let vec[t] real_results = [];
2645+
for (option::t[t] typ in results) {
2646+
real_results += [option::get[t](typ)];
25882647
}
25892648

2590-
ret result;
2649+
ret usr_ok(real_results);
25912650
}
25922651

25932652
fn unify(&t expected,
@@ -2599,9 +2658,13 @@ mod unify {
25992658
ret unify_step(cx, expected, actual);
26002659
}
26012660

2602-
fn fixup(&ty_ctxt tcx, &@bindings[int] bindings, t typ) -> t {
2603-
auto set_types = unify_sets[int](bindings);
2604-
ret substitute(tcx, bindings, set_types, typ);
2661+
fn fixup(&ty_ctxt tcx, &@bindings[int] bindings, t typ) -> result {
2662+
alt (unify_sets[int](tcx, bindings)) {
2663+
case (usr_ok(?set_types)) {
2664+
ret ures_ok(substitute(tcx, bindings, set_types, typ));
2665+
}
2666+
case (usr_err(?terr, ?t0, ?t1)) { ret ures_err(terr, t0, t1); }
2667+
}
26052668
}
26062669
}
26072670

trunk/src/comp/middle/typeck.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -953,8 +953,7 @@ mod unify {
953953
alt (result) {
954954
case (ures_ok(?rty)) {
955955
if (ty::type_contains_vars(scx.fcx.ccx.tcx, rty)) {
956-
result = ures_ok(ty::unify::fixup(scx.fcx.ccx.tcx,
957-
bindings, rty));
956+
result = ty::unify::fixup(scx.fcx.ccx.tcx, bindings, rty);
958957
}
959958
}
960959
case (_) { /* nothing */ }

0 commit comments

Comments
 (0)