summaryrefslogtreecommitdiff
path: root/parse/infer.c
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2018-07-14 00:07:31 -0700
committerOri Bernstein <ori@eigenstate.org>2018-07-14 00:16:06 -0700
commite8121eb38f6c825fc4638d84521c51dc6cfe761b (patch)
treea2e37178de089f90db2c8115a41edcd299921433 /parse/infer.c
parent76ce9de16baeec77b86ece6825b90715b08545ba (diff)
downloadmc-e8121eb38f6c825fc4638d84521c51dc6cfe761b.tar.gz
Push down named unions types into union tags
Currently, union tags are given the type of their enclosing union, by default: type u = union `Foo ;; var x = `Foo will currently infer the variable 'x' as having type 'union `Foo ;;'. To make the type of 'x' infer as 'foo', the code needs to force 'x' to unify with something that is explicitly declared as a 'u'. This change makes it so that union tags declared in the manner above will default to type 'u', instead. This is a special case, but it makes the behavior less surprising.
Diffstat (limited to 'parse/infer.c')
-rw-r--r--parse/infer.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/parse/infer.c b/parse/infer.c
index c5cad2f..8da7e02 100644
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -514,7 +514,7 @@ tyresolve(Type *t)
case Tyunion:
inaggr++;
for (i = 0; i < t->nmemb; i++) {
- t->udecls[i]->utype = t;
+ assert(t->udecls[i]->utype);
t->udecls[i]->utype = tf(t->udecls[i]->utype);
if (t->udecls[i]->etype) {
tyresolve(t->udecls[i]->etype);
@@ -1498,7 +1498,11 @@ inferucon(Node *n, int *isconst)
*
* To make it compile, for now, we just bind the types in here.
*/
- t = tysubst(tf(uc->utype), uc->utype);
+ t = uc->utype;
+ if (t->type != Tyunion)
+ t = t->sub[0];
+ assert(t->type == Tyunion);
+ t = tysubst(tf(t), t);
uc = tybase(t)->udecls[uc->id];
if (uc->etype) {
inferexpr(&n->expr.args[1], NULL, NULL);