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);