shithub: mc

Download patch

ref: fd91c0a3fc7e496e8d55e91ebe0e44b61bca8ce1
parent: 527bad788adf057d71faa98ed6e09952395abe50
author: Ori Bernstein <[email protected]>
date: Sun Jun 14 15:57:18 EDT 2015

Fix some type error messages.

    We would give a confusing error if we were tryig to unify an
    indexable type variable with a non-indexable type.

    This gives a much better error.

--- a/parse/infer.c
+++ b/parse/infer.c
@@ -705,13 +705,29 @@
     return bsissubset(a->traits, b->traits);
 }
 
-/* Merges the constraints on types */
-static void mergetraits(Inferstate *st, Node *ctx, Type *a, Type *b)
+static void verifytraits(Inferstate *st, Node *ctx, Type *a, Type *b)
 {
     size_t i, n;
     char *sep;
     char traitbuf[1024], abuf[1024], bbuf[1024];
 
+    if (!checktraits(a, b)) {
+        sep = "";
+        n = 0;
+        for (i = 0; bsiter(a->traits, &i); i++) {
+            if (!b->traits || !bshas(b->traits, i))
+                n += snprintf(traitbuf + n, sizeof(traitbuf) - n, "%s%s", sep, namestr(traittab[i]->name));
+            sep = ",";
+        }
+        tyfmt(abuf, sizeof abuf, a);
+        tyfmt(bbuf, sizeof bbuf, b);
+        fatal(ctx, "%s missing traits %s for %s near %s", bbuf, traitbuf, abuf, ctxstr(st, ctx));
+    }
+}
+
+/* Merges the constraints on types */
+static void mergetraits(Inferstate *st, Node *ctx, Type *a, Type *b)
+{
     if (b->type == Tyvar) {
         /* make sure that if a = b, both have same traits */
         if (a->traits && b->traits)
@@ -721,18 +737,7 @@
         else if (b->traits)
             a->traits = bsdup(b->traits);
     } else {
-        if (!checktraits(a, b)) {
-            sep = "";
-            n = 0;
-            for (i = 0; bsiter(a->traits, &i); i++) {
-                if (!b->traits || !bshas(b->traits, i))
-                    n += snprintf(traitbuf + n, sizeof(traitbuf) - n, "%s%s", sep, namestr(traittab[i]->name));
-                sep = ",";
-            }
-            tyfmt(abuf, sizeof abuf, a);
-            tyfmt(bbuf, sizeof bbuf, b);
-            fatal(ctx, "%s missing traits %s for %s near %s", bbuf, traitbuf, abuf, ctxstr(st, ctx));
-        }
+        verifytraits(st, ctx, a, b);
     }
 }
 
@@ -888,6 +893,7 @@
         if (a->type == Tyname && !nameeq(a->name, b->name))
             typeerror(st, a, b, ctx, NULL);
         if (a->nsub != b->nsub) {
+            verifytraits(st, ctx, a, b);
             if (tybase(a)->type == Tyfunc)
                 typeerror(st, a, b, ctx, "function arity mismatch");
             else
@@ -1525,7 +1531,7 @@
         /* infer and unify types */
         if (n->impl.type->type == Tygeneric || n->impl.type->type == Typaram)
             fatal(n, "trait specialization requires concrete type, got %s", tystr(n->impl.type));
-        checktraits(t->param, n->impl.type);
+        verifytraits(st, n, t->param, n->impl.type);
         ht = mkht(tyhash, tyeq);
         htput(ht, t->param, n->impl.type);
         ty = tyspecialize(type(st, proto), ht, st->delayed);