diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2011-05-18 13:08:02 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2011-05-18 13:08:54 -0700 |
| commit | 13d9f6a2640815aa1fa2a299e0ab364cd292cbfa (patch) | |
| tree | 56d2387bcfa2c8597215c0a29c468c3423ac76a7 | |
| parent | 96516e9ca263574fa58c2f0a48348fa0d876be10 (diff) | |
| download | rust-13d9f6a2640815aa1fa2a299e0ab364cd292cbfa.tar.gz rust-13d9f6a2640815aa1fa2a299e0ab364cd292cbfa.zip | |
rustc: Split out type variable fixups from unification
| -rw-r--r-- | src/comp/middle/ty.rs | 62 | ||||
| -rw-r--r-- | src/comp/middle/typeck.rs | 15 |
2 files changed, 40 insertions, 37 deletions
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index b7ff61ffd2b..6b2ee1441bb 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -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 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 cx = @rec(var_bindings=var_bindings, handler=handler, tcx=tcx); + ret unify_step(cx, expected, actual); + } - 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); } } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 8dee831ffbd..3bc0364a684 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -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; } |
