rustc: Split out type variable fixups from unification
This commit is contained in:
parent
96516e9ca2
commit
13d9f6a264
2 changed files with 40 additions and 37 deletions
|
|
@ -1869,14 +1869,14 @@ mod unify {
|
|||
hashmap[int,uint] var_ids,
|
||||
mutable vec[mutable vec[t]] types);
|
||||
|
||||
fn mk_var_bindings() -> var_bindings {
|
||||
fn mk_var_bindings() -> @var_bindings {
|
||||
let vec[mutable vec[t]] types = [mutable];
|
||||
ret rec(sets=ufind::make(),
|
||||
var_ids=common::new_int_hash[uint](),
|
||||
mutable types=types);
|
||||
ret @rec(sets=ufind::make(),
|
||||
var_ids=common::new_int_hash[uint](),
|
||||
mutable types=types);
|
||||
}
|
||||
|
||||
type ctxt = rec(var_bindings var_bindings,
|
||||
type ctxt = rec(@var_bindings var_bindings,
|
||||
unify_handler handler,
|
||||
ty_ctxt tcx);
|
||||
|
||||
|
|
@ -2519,17 +2519,19 @@ mod unify {
|
|||
}
|
||||
|
||||
// Performs type binding substitution.
|
||||
fn substitute(&@ctxt cx, &vec[t] set_types, &t typ) -> t {
|
||||
if (!type_contains_vars(cx.tcx, typ)) {
|
||||
fn substitute(&ty_ctxt tcx, &@var_bindings var_bindings,
|
||||
&vec[t] set_types, &t typ) -> t {
|
||||
if (!type_contains_vars(tcx, typ)) {
|
||||
ret typ;
|
||||
}
|
||||
|
||||
fn substituter(@ctxt cx, vec[t] types, t typ) -> t {
|
||||
alt (struct(cx.tcx, typ)) {
|
||||
fn substituter(ty_ctxt tcx, @var_bindings var_bindings, vec[t] types,
|
||||
t typ) -> t {
|
||||
alt (struct(tcx, typ)) {
|
||||
case (ty_var(?id)) {
|
||||
alt (cx.var_bindings.var_ids.find(id)) {
|
||||
alt (var_bindings.var_ids.find(id)) {
|
||||
case (some[uint](?n)) {
|
||||
auto root = ufind::find(cx.var_bindings.sets, n);
|
||||
auto root = ufind::find(var_bindings.sets, n);
|
||||
ret types.(root);
|
||||
}
|
||||
case (none[uint]) { ret typ; }
|
||||
|
|
@ -2539,24 +2541,24 @@ mod unify {
|
|||
}
|
||||
}
|
||||
|
||||
auto f = bind substituter(cx, set_types, _);
|
||||
ret fold_ty(cx.tcx, f, typ);
|
||||
auto f = bind substituter(tcx, var_bindings, set_types, _);
|
||||
ret fold_ty(tcx, f, typ);
|
||||
}
|
||||
|
||||
fn unify_sets(&@ctxt cx) -> vec[t] {
|
||||
fn unify_sets(&@var_bindings var_bindings) -> vec[t] {
|
||||
let vec[t] throwaway = [];
|
||||
let vec[mutable vec[t]] set_types = [mutable throwaway];
|
||||
vec::pop[vec[t]](set_types); // FIXME: botch
|
||||
|
||||
for (ufind::node node in cx.var_bindings.sets.nodes) {
|
||||
for (ufind::node node in var_bindings.sets.nodes) {
|
||||
let vec[t] v = [];
|
||||
set_types += [mutable v];
|
||||
}
|
||||
|
||||
auto i = 0u;
|
||||
while (i < vec::len[vec[t]](set_types)) {
|
||||
auto root = ufind::find(cx.var_bindings.sets, i);
|
||||
set_types.(root) += cx.var_bindings.types.(i);
|
||||
auto root = ufind::find(var_bindings.sets, i);
|
||||
set_types.(root) += var_bindings.types.(i);
|
||||
i += 1u;
|
||||
}
|
||||
|
||||
|
|
@ -2576,27 +2578,15 @@ mod unify {
|
|||
fn unify(&t expected,
|
||||
&t actual,
|
||||
&unify_handler handler,
|
||||
&@var_bindings var_bindings,
|
||||
&ty_ctxt tcx) -> result {
|
||||
auto cx = @rec(var_bindings=mk_var_bindings(),
|
||||
handler=handler,
|
||||
tcx=tcx);
|
||||
auto cx = @rec(var_bindings=var_bindings, handler=handler, tcx=tcx);
|
||||
ret unify_step(cx, expected, actual);
|
||||
}
|
||||
|
||||
auto ures = unify_step(cx, expected, actual);
|
||||
alt (ures) {
|
||||
case (ures_ok(?typ)) {
|
||||
// Fast path: if there are no local variables, don't perform
|
||||
// substitutions.
|
||||
if (vec::len(cx.var_bindings.sets.nodes) == 0u) {
|
||||
ret ures_ok(typ);
|
||||
}
|
||||
|
||||
auto set_types = unify_sets(cx);
|
||||
auto t2 = substitute(cx, set_types, typ);
|
||||
ret ures_ok(t2);
|
||||
}
|
||||
case (_) { ret ures; }
|
||||
}
|
||||
fail; // not reached
|
||||
fn fixup(&ty_ctxt tcx, &@var_bindings var_bindings, t typ) -> t {
|
||||
auto set_types = unify_sets(var_bindings);
|
||||
ret substitute(tcx, var_bindings, set_types, typ);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -934,8 +934,21 @@ mod unify {
|
|||
|
||||
|
||||
auto handler = unify_handler(fcx, param_substs);
|
||||
|
||||
auto var_bindings = ty::unify::mk_var_bindings();
|
||||
auto result = ty::unify::unify(expected, actual, handler,
|
||||
fcx.ccx.tcx);
|
||||
var_bindings, fcx.ccx.tcx);
|
||||
|
||||
alt (result) {
|
||||
case (ures_ok(?rty)) {
|
||||
if (ty::type_contains_vars(fcx.ccx.tcx, rty)) {
|
||||
result = ures_ok(ty::unify::fixup(fcx.ccx.tcx,
|
||||
var_bindings, rty));
|
||||
}
|
||||
}
|
||||
case (_) { /* nothing */ }
|
||||
}
|
||||
|
||||
fcx.ccx.unify_cache.insert(cache_key, result);
|
||||
ret result;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue