shithub: mc

Download patch

ref: 9783cadd19045e7d3f5b5eaaad8feb5ebeacb042
parent: dfa5608bf26c5c5ad6ffea8c18392479ae353ded
author: Ori Bernstein <[email protected]>
date: Fri Sep 13 09:06:24 EDT 2013

Fix generic union constructor inference in pattern matching.

--- a/parse/infer.c
+++ b/parse/infer.c
@@ -844,13 +844,27 @@
         n->expr.isconst = n->expr.isconst && n->expr.args[i]->expr.isconst;
         types[i] = type(st, n->expr.args[i]);
     }
+    *isconst = n->expr.isconst;
     settype(st, n, mktytuple(n->line, types, n->expr.nargs));
 }
 
+static void inferucon(Inferstate *st, Node *n, int *isconst)
+{
+    Ucon *uc;
+    Type *t;
+
+    uc = uconresolve(st, n);
+    t = tyfreshen(st, tf(st, uc->utype));
+    uc = tybase(t)->udecls[uc->id];
+    if (uc->etype)
+        unify(st, n, uc->etype, type(st, n->expr.args[1]));
+    *isconst = n->expr.args[0]->expr.isconst;
+    settype(st, n, delayed(st, t));
+}
+
 static void inferpat(Inferstate *st, Node *n, Node *val, Node ***bind, size_t *nbind)
 {
     size_t i;
-    Ucon *uc;
     Node **args;
     Node *s;
     Type *t;
@@ -861,10 +875,7 @@
             inferpat(st, args[i], val, bind, nbind);
     switch (exprop(n)) {
         case Oucon:
-            uc = uconresolve(st, n);
-            if (uc->etype)
-                unify(st, n, uc->etype, type(st, args[1]));
-            settype(st, n, delayed(st, uc->utype));
+            inferucon(st, n, &n->expr.isconst);
             break;
         case Ovar:
             s = getdcl(curstab(), args[0]);
@@ -913,7 +924,6 @@
 {
     Node **args;
     size_t i, nargs;
-    Ucon *uc;
     Node *s;
     Type *t;
 
@@ -1055,12 +1065,7 @@
             }
             break;
         case Oucon:
-            uc = uconresolve(st, n);
-            t = tyfreshen(st, tf(st, uc->utype));
-            uc = tybase(t)->udecls[uc->id];
-            if (uc->etype)
-                unify(st, n, uc->etype, type(st, args[1]));
-            settype(st, n, delayed(st, t));
+            inferucon(st, n, &n->expr.isconst);
             break;
         case Otup:
             infertuple(st, n, &n->expr.isconst);