ref: 80c98275269f28f88827ce8d493bb5db47db9757
parent: 6a2702fa848c89bf3d9d6cb366f0c838ea8fcd50
author: Ori Bernstein <[email protected]>
date: Mon Sep 23 20:08:03 EDT 2013
Make delayed types unify as well.
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -558,6 +558,29 @@
return t->type == Tyname && t->narg > 0;
}
+static void membunify(Inferstate *st, Node *ctx, Type *u, Type *v) {
+ size_t i;
+
+ if (hthas(st->delayed, u))
+ u = htget(st->delayed, u);
+ u = tybase(u);
+ if (hthas(st->delayed, v))
+ v = htget(st->delayed, v);
+ v = tybase(v);
+ if (u->type == Tyunion && v->type == Tyunion && u != v) {
+ assert(u->nmemb = v->nmemb);
+ for (i = 0; i < v->nmemb; i++) {
+ if (u->udecls[i]->etype)
+ unify(st, ctx, u->udecls[i]->etype, v->udecls[i]->etype);
+ }
+ } else if (u->type == Tystruct && v->type == Tystruct && u != v) {
+ assert(u->nmemb = v->nmemb);
+ for (i = 0; i < v->nmemb; i++) {
+ unify(st, ctx, type(st, u->sdecls[i]), type(st, v->sdecls[i]));
+ }
+ }
+}
+
/* Unifies two types, or errors if the types are not unifiable. */
static Type *unify(Inferstate *st, Node *ctx, Type *u, Type *v)
{
@@ -593,6 +616,14 @@
r = b;
}
+ /* if we have delayed types for a tyvar, transfer it over. */
+ if (a->type == Tyvar && b->type == Tyvar) {
+ if (hthas(st->delayed, a) && !hthas(st->delayed, b))
+ htput(st->delayed, b, htget(st->delayed, a));
+ else if (hthas(st->delayed, b) && !hthas(st->delayed, a))
+ htput(st->delayed, a, htget(st->delayed, b));
+ }
+
/* Disallow recursive types */
if (a->type == Tyvar && b->type != Tyvar)
if (occurs(a, b))
@@ -624,25 +655,7 @@
tystr(a), tystr(b), ctxstr(st, ctx));
}
mergecstrs(st, ctx, a, b);
-
- if (hthas(st->delayed, u))
- u = htget(st->delayed, u);
- u = tybase(u);
- if (hthas(st->delayed, v))
- v = htget(st->delayed, v);
- v = tybase(v);
- if (u->type == Tyunion && v->type == Tyunion && u != v) {
- assert(u->nmemb = v->nmemb);
- for (i = 0; i < v->nmemb; i++) {
- if (u->udecls[i]->etype)
- unify(st, NULL, u->udecls[i]->etype, v->udecls[i]->etype);
- }
- } else if (u->type == Tystruct && v->type == Tystruct && u != v) {
- assert(u->nmemb = v->nmemb);
- for (i = 0; i < v->nmemb; i++) {
- unify(st, NULL, type(st, u->sdecls[i]), type(st, v->sdecls[i]));
- }
- }
+ membunify(st, ctx, a, b);
return r;
}
--- a/test/stdopt-mk.myr
+++ b/test/stdopt-mk.myr
@@ -1,15 +1,20 @@
use std
-const main = {args : byte[:][:]
- match getoption(123)
- `std.Some val: std.put("Got a value: %i\n", val);;
- `std.None: std.put("No value returned\n");;
+const f = {x
+ if x == 123
+ -> `std.Some 42
+ else
+ -> `std.None
;;
}
-const getoption = {val
- match val
- 0: -> `std.None;;
- _: -> `std.Some val;;
+const main = {
+ var v
+
+ v = f(123)
+ match v
+ `std.Some x: -> x;;
+ `std.None: -> 123;;
;;
}
+