shithub: mc

Download patch

ref: ff0dabb5294b6fab33fc8cd68b2fcc37a00c28c0
parent: eff57189af8d9eb2d05005f65d3598b28379b199
author: Ori Bernstein <[email protected]>
date: Mon Oct 21 19:52:30 EDT 2013

Improve errors even more.

    Fix cases where we allow unions that are incompatible
    passing through to the backend.

--- a/parse/infer.c
+++ b/parse/infer.c
@@ -357,10 +357,12 @@
     return NULL;
 }
 
-static Type *delayed(Inferstate *st, Type *fallback)
+static Type *delayeducon(Inferstate *st, Type *fallback)
 {
     Type *t;
 
+    if (fallback->type != Tyunion)
+        return fallback;
     t = mktylike(fallback->line, fallback->type);
     htput(st->delayed, t, fallback);
     return t;
@@ -627,18 +629,6 @@
         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));
-    } else if (hthas(st->delayed, a)) {
-        t = htget(st->delayed, a);
-        if (tybase(t)->type != tybase(b)->type)
-            typeerror(st, t, b, ctx, NULL);
-    }
-
     /* Disallow recursive types */
    if (a->type == Tyvar && b->type != Tyvar)  {
         if (occurs(a, b))
@@ -670,6 +660,16 @@
     mergecstrs(st, ctx, a, b);
     membunify(st, ctx, a, 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));
+    } else if (hthas(st->delayed, a)) {
+        unify(st, ctx, htget(st->delayed, a), tybase(b));
+    }
+
     return r;
 }
 
@@ -918,7 +918,7 @@
     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));
+    settype(st, n, delayeducon(st, t));
 }
 
 static void inferpat(Inferstate *st, Node *n, Node *val, Node ***bind, size_t *nbind)