ref: 767e744e5841c7bfe108b0787d96e109c897aff2
parent: b6872f8fa14d01499db9bdfcfbf2cfa48266bd28
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Jun 24 10:11:14 EDT 2017
Start marking sources of type errors.
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -23,6 +23,8 @@
int innamed;
int indentdepth;
Type *ret;
+ Srcloc *usrc;
+ size_t nusrc;
/* post-inference checking/unification */
Htab *delayed;
@@ -116,6 +118,36 @@
return strdup("unknown");
}
+static void marksrc(Inferstate *st, Type *t, Srcloc l)
+{
+ size_t sz;
+
+ sz = max(t->tid + 1, st->nusrc);
+ if (sz > st->nusrc) {
+ st->usrc = zrealloc(st->usrc, st->nusrc*sizeof(Srcloc), sz*sizeof(Srcloc));
+ st->nusrc = sz;
+ }
+ t = tf(st, t);
+ if (st->usrc[t->tid].line <= 0)
+ st->usrc[t->tid] = l;
+}
+
+static char *srcstr(Inferstate *st, Type *ty)
+{
+ char src[128];
+ Srcloc l;
+ char *s;
+
+ src[0] = 0;
+ if (st->nusrc > ty->tid && st->usrc[ty->tid].line > 0) {
+ l = st->usrc[ty->tid];
+ s = tystr(ty);
+ snprintf(src, sizeof src, "\n\t%s from %s:%d", s, fname(l), lnum(l));
+ free(s);
+ }
+ return strdup(src);
+}
+
/* Tries to give a good string describing the context
* for the sake of error messages. */
static char *ctxstr(Inferstate *st, Node *n)
@@ -237,17 +269,21 @@
static void typeerror(Inferstate *st, Type *a, Type *b, Node *ctx, char *msg)
{
- char *t1, *t2, *c;
+ char *t1, *t2, *s1, *s2, *c;
t1 = tystr(tyfix(st, NULL, a, 1));
t2 = tystr(tyfix(st, NULL, b, 1));
+ s1 = srcstr(st, a);
+ s2 = srcstr(st, b);
c = ctxstr(st, ctx);
if (msg)
- fatal(ctx, "type \"%s\" incompatible with \"%s\" near %s: %s", t1, t2, c, msg);
+ fatal(ctx, "type \"%s\" incompatible with \"%s\" near %s: %s%s%s", t1, t2, c, msg, s1, s2);
else
- fatal(ctx, "type \"%s\" incompatible with \"%s\" near %s", t1, t2, c);
+ fatal(ctx, "type \"%s\" incompatible with \"%s\" near %s%s%s", t1, t2, c, s1, s2);
free(t1);
free(t2);
+ free(s1);
+ free(s2);
free(c);
}
@@ -571,6 +607,8 @@
case Nfunc: n->func.type = t; break;
default: die("untypable node %s", nodestr[n->type]); break;
}
+ if (t->type != Tyvar)
+ marksrc(st, t, n->loc);
}
/* Gets the type of a literal value */
@@ -795,8 +833,10 @@
static void verifytraits(Inferstate *st, Node *ctx, Type *a, Type *b)
{
size_t i, n;
+ Srcloc l;
char *sep;
- char traitbuf[1024], abuf[1024], bbuf[1024];
+ char traitbuf[64], abuf[64], bbuf[64];
+ char asrc[64], bsrc[64];
if (!checktraits(a, b)) {
sep = "";
@@ -809,8 +849,14 @@
}
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));
+ bsrc[0] = 0;
+ if (st->nusrc > b->tid && st->usrc[b->tid].line > 0) {
+ l = st->usrc[b->tid];
+ snprintf(bsrc, sizeof asrc, "\n\t%s from %s:%d", bbuf, fname(l), lnum(l));
+ }
+ fatal(ctx, "%s missing traits %s for %s near %s%s%s",
+ bbuf, traitbuf, abuf, ctxstr(st, ctx),
+ srcstr(st, a), srcstr(st, b));
}
}
@@ -853,7 +899,9 @@
int found;
if (u->nmemb != v->nmemb)
- fatal(ctx, "can't unify %s and %s near %s\n", tystr(u), tystr(v), ctxstr(st, ctx));
+ fatal(ctx, "can't unify %s and %s near %s%s%s\n",
+ tystr(u), tystr(v), ctxstr(st, ctx),
+ srcstr(st, u), srcstr(st, v));
for (i = 0; i < u->nmemb; i++) {
found = 0;
@@ -866,12 +914,14 @@
else if (u->udecls[i]->etype && v->udecls[j]->etype)
unify(st, ctx, u->udecls[i]->etype, v->udecls[j]->etype);
else
- fatal(ctx, "can't unify %s and %s near %s\n", tystr(u), tystr(v),
- ctxstr(st, ctx));
+ fatal(ctx, "can't unify %s and %s near %s%s%s",
+ tystr(u), tystr(v), ctxstr(st, ctx),
+ srcstr(st, u), srcstr(st, v));
}
if (!found)
- fatal(ctx, "can't unify %s and %s near %s\n", tystr(u), tystr(v),
- ctxstr(st, ctx));
+ fatal(ctx, "can't unify %s and %s near %s%s%s",
+ tystr(u), tystr(v), ctxstr(st, ctx),
+ srcstr(st, u), srcstr(st, v));
}
}
@@ -882,7 +932,9 @@
char *ud, *vd;
if (u->nmemb != v->nmemb)
- fatal(ctx, "can't unify %s and %s near %s\n", tystr(u), tystr(v), ctxstr(st, ctx));
+ fatal(ctx, "can't unify %s and %s near %s%s%s",
+ tystr(u), tystr(v), ctxstr(st, ctx),
+ srcstr(st, u), srcstr(st, v));
for (i = 0; i < u->nmemb; i++) {
found = 0;
@@ -896,8 +948,9 @@
}
/* we had at least one missing member */
if (!found)
- fatal(ctx, "can't unify %s and %s near %s\n", tystr(u), tystr(v),
- ctxstr(st, ctx));
+ fatal(ctx, "can't unify %s and %s near %s%s%s",
+ tystr(u), tystr(v), ctxstr(st, ctx),
+ srcstr(st, u), srcstr(st, v));
}
}
@@ -998,8 +1051,13 @@
}
r = NULL;
- if (a->type == Tyvar || tyeq(a, b))
+ if (a->type == Tyvar || tyeq(a, b)) {
tytab[a->tid] = b;
+ if (ctx) {
+ marksrc(st, a, ctx->loc);
+ marksrc(st, b, ctx->loc);
+ }
+ }
if (a->type == Tyvar) {
ea = basetype(st, a);
eb = basetype(st, b);