summaryrefslogtreecommitdiff
path: root/parse
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2015-04-19 21:08:57 -0700
committerOri Bernstein <ori@eigenstate.org>2015-04-19 21:08:57 -0700
commit3b6161698eb2533b1a4c6e97c589de2fbf862fa5 (patch)
treee205f61da0fd20f33f188cb1a71f9433bba074f4 /parse
parente3c224ae91768a0d339ebda1838f32c04edb6547 (diff)
downloadmc-3b6161698eb2533b1a4c6e97c589de2fbf862fa5.tar.gz
Fix tests in non-mbld world.
Diffstat (limited to 'parse')
-rw-r--r--parse/infer.c100
1 files changed, 54 insertions, 46 deletions
diff --git a/parse/infer.c b/parse/infer.c
index 3d7ef4a..12ae733 100644
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -52,6 +52,7 @@ static void inferexpr(Inferstate *st, Node **np, Type *ret, int *sawret);
static void inferdecl(Inferstate *st, Node *n);
static void typesub(Inferstate *st, Node *n);
static void tybind(Inferstate *st, Type *t);
+static Type *tyfix(Inferstate *st, Node *ctx, Type *orig, int noerr);
static void bind(Inferstate *st, Node *n);
static void tyunbind(Inferstate *st, Type *t);
static void unbind(Inferstate *st, Node *n);
@@ -76,7 +77,7 @@ static void ctxstrcall(char *buf, size_t sz, Inferstate *st, Node *n)
else
p += snprintf(p, end - p, "<e>(");
for (i = 1; i < nargs; i++) {
- et = exprtype(args[i]);
+ et = tyfix(st, NULL, exprtype(args[i]), 1);
if (et != NULL)
t = tystr(et);
else
@@ -89,7 +90,7 @@ static void ctxstrcall(char *buf, size_t sz, Inferstate *st, Node *n)
sep = ", ";
free(t);
}
- t = tystr(exprtype(args[0])->sub[0]);
+ t = tystr(tyfix(st, NULL, exprtype(args[0])->sub[0], 1));
p += snprintf(p, end - p, "): %s", t);
free(t);
}
@@ -97,9 +98,9 @@ static void ctxstrcall(char *buf, size_t sz, Inferstate *st, Node *n)
static char *nodetystr(Inferstate *st, Node *n, char *s)
{
if (n->type == Nexpr && exprtype(n) != NULL)
- return tystr(tf(st, exprtype(n)));
+ return tystr(tyfix(st, NULL, exprtype(n), 1));
else if (n->type == Ndecl && decltype(n) != NULL)
- return tystr(tf(st, decltype(n)));
+ return tystr(tyfix(st, NULL, decltype(n), 1));
else
return strdup(s);
}
@@ -211,14 +212,16 @@ static void delayedcheck(Inferstate *st, Node *n, Stab *s)
static void typeerror(Inferstate *st, Type *a, Type *b, Node *ctx, char *msg)
{
char *t1, *t2, *c;
+ int line;
- t1 = tystr(a);
- t2 = tystr(b);
+ t1 = tystr(tyfix(st, NULL, a, 1));
+ t2 = tystr(tyfix(st, NULL, b, 1));
+ line = ctx->loc.line;
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 line %d, line %d, %s: %s", t1, t2, line, c, msg);
else
- fatal(ctx, "Type \"%s\" incompatible with \"%s\" near %s", t1, t2, c);
+ fatal(ctx, "Type \"%s\" incompatible with \"%s\" near line %d, line %d, %s", t1, t2, line, c);
free(t1);
free(t2);
free(c);
@@ -675,7 +678,7 @@ static void constrain(Inferstate *st, Node *ctx, Type *a, Trait *c)
a->traits = mkbs();
settrait(a, c);
} else if (!a->traits || !bshas(a->traits, c->uid)) {
- fatal(ctx, "%s needs %s near %s", tystr(a), namestr(c->name), ctxstr(st, ctx));
+ fatal(ctx, "%s needs %s near line %d, line %d, %s", tystr(a), namestr(c->name), ctx->loc.line, ctxstr(st, ctx));
}
}
@@ -719,7 +722,7 @@ static void mergetraits(Inferstate *st, Node *ctx, Type *a, Type *b)
}
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));
+ fatal(ctx, "%s missing traits %s for %s near line %d, %s", bbuf, traitbuf, abuf, ctx->loc.line, ctxstr(st, ctx));
}
}
}
@@ -775,7 +778,7 @@ static void unionunify(Inferstate *st, Node *ctx, Type *u, Type *v)
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 line %d, %s\n", tystr(u), tystr(v), ctx->loc.line, ctxstr(st, ctx));
for (i = 0; i < u->nmemb; i++) {
found = 0;
@@ -788,10 +791,10 @@ static void unionunify(Inferstate *st, Node *ctx, Type *u, Type *v)
else if (u->udecls[i]->etype && v->udecls[i]->etype)
unify(st, ctx, u->udecls[i]->etype, v->udecls[i]->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 line %d, %s\n", tystr(u), tystr(v), ctx->loc.line, ctxstr(st, ctx));
}
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 line %d, %s\n", tystr(u), tystr(v), ctx->loc.line, ctxstr(st, ctx));
}
}
@@ -801,7 +804,7 @@ static void structunify(Inferstate *st, Node *ctx, Type *u, Type *v)
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 line %d, %s\n", tystr(u), tystr(v), ctx->loc.line, ctxstr(st, ctx));
for (i = 0; i < u->nmemb; i++) {
found = 0;
@@ -812,7 +815,7 @@ static void structunify(Inferstate *st, Node *ctx, Type *u, Type *v)
unify(st, u->sdecls[i], type(st, u->sdecls[i]), type(st, v->sdecls[i]));
}
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 line %d, %s\n", tystr(u), tystr(v), ctx->loc.line, ctxstr(st, ctx));
}
}
@@ -940,7 +943,7 @@ static void unifycall(Inferstate *st, Node *n)
/* first arg: function itself */
for (i = 1; i < n->expr.nargs; i++)
if (exprtype(n->expr.args[i])->type == Tyvoid)
- fatal(n, "void passed where value expected, near %s", ctxstr(st, n));
+ fatal(n, "void passed where value expected, near line %d, %s", n->loc.line, ctxstr(st, n));
for (i = 1; i < n->expr.nargs; i++) {
if (i == ft->nsub)
fatal(n, "%s arity mismatch (expected %zd args, got %zd)",
@@ -982,7 +985,7 @@ static void unifyparams(Inferstate *st, Node *ctx, Type *a, Type *b)
return;
if (a->narg != b->narg)
- fatal(ctx, "Mismatched parameter list sizes: %s with %s near %s", tystr(a), tystr(b), ctxstr(st, ctx));
+ fatal(ctx, "Mismatched parameter list sizes: %s with %s near line %d, %s", tystr(a), tystr(b), ctx->loc.line, ctxstr(st, ctx));
for (i = 0; i < a->narg; i++)
unify(st, ctx, a->arg[i], b->arg[i]);
}
@@ -1177,7 +1180,7 @@ static void inferpat(Inferstate *st, Node **np, Node *val, Node ***bind, size_t
else if (s->decl.isconst)
t = s->decl.type;
else
- fatal(n, "Can't match against non-constant variables near %s", ctxstr(st, n));
+ fatal(n, "Can't match against non-constant variables near line %d, %s", n->loc.line, ctxstr(st, n));
} else {
t = mktyvar(n->loc);
s = mkdecl(n->loc, n->expr.args[0], t);
@@ -1495,8 +1498,8 @@ static void specializeimpl(Inferstate *st, Node *n)
}
}
if (!proto)
- fatal(n, "Declaration %s missing in %s, near %s",
- namestr(dcl->decl.name), namestr(t->name), ctxstr(st, n));
+ fatal(n, "Declaration %s missing in %s, near line %d, %s",
+ namestr(dcl->decl.name), namestr(t->name), n->loc.line, ctxstr(st, n));
/* infer and unify types */
if (n->impl.type->type == Tygeneric || n->impl.type->type == Typaram)
@@ -1584,7 +1587,7 @@ static void infernode(Inferstate *st, Node **np, Type *ret, int *sawret)
bind(st, n);
inferdecl(st, n);
if (type(st, n)->type == Typaram && !st->ingeneric)
- fatal(n, "Generic type %s in non-generic near %s", tystr(type(st, n)), ctxstr(st, n));
+ fatal(n, "Generic type %s in non-generic near line %d, %s", tystr(type(st, n)), n->loc.line, ctxstr(st, n));
unbind(st, n);
st->indentdepth--;
if (debugopt['u'])
@@ -1630,7 +1633,7 @@ static void infernode(Inferstate *st, Node **np, Type *ret, int *sawret)
case Nmatchstmt:
infernode(st, &n->matchstmt.val, NULL, sawret);
if (tybase(type(st, n->matchstmt.val))->type == Tyvoid)
- fatal(n, "Can't match against a void type near %s", ctxstr(st, n->matchstmt.val));
+ fatal(n, "Can't match against a void type near line %d, %s", n->loc.line, ctxstr(st, n->matchstmt.val));
for (i = 0; i < n->matchstmt.nmatches; i++) {
infernode(st, &n->matchstmt.matches[i], ret, sawret);
unify(st, n->matchstmt.matches[i]->match.pat, type(st, n->matchstmt.val), type(st, n->matchstmt.matches[i]->match.pat));
@@ -1671,7 +1674,7 @@ static void infernode(Inferstate *st, Node **np, Type *ret, int *sawret)
/* returns the final type for t, after all unifications
* and default constraint selections */
-static Type *tyfix(Inferstate *st, Node *ctx, Type *orig)
+static Type *tyfix(Inferstate *st, Node *ctx, Type *orig, int noerr)
{
static Type *tyint, *tyflt;
Type *t, *delayed;
@@ -1689,8 +1692,8 @@ static Type *tyfix(Inferstate *st, Node *ctx, Type *orig)
delayed = htget(st->delayed, orig);
if (t->type == Tyvar)
t = delayed;
- else if (tybase(t)->type != delayed->type)
- fatal(ctx, "Type %s not compatible with %s near %s\n", tystr(t), tystr(delayed), ctxstr(st, ctx));
+ else if (tybase(t)->type != delayed->type && !noerr)
+ fatal(ctx, "Type %s not compatible with %s near line %d, %s\n", tystr(t), tystr(delayed), ctx->loc.line, ctxstr(st, ctx));
}
if (t->type == Tyvar) {
if (hastrait(t, traittab[Tcint]) && checktraits(t, tyint))
@@ -1709,20 +1712,20 @@ static Type *tyfix(Inferstate *st, Node *ctx, Type *orig)
} else if (t->type == Tyunion) {
for (i = 0; i < t->nmemb; i++) {
if (t->udecls[i]->etype)
- t->udecls[i]->etype = tyfix(st, ctx, t->udecls[i]->etype);
+ t->udecls[i]->etype = tyfix(st, ctx, t->udecls[i]->etype, noerr);
}
} else if (t->type == Tyname) {
for (i = 0; i < t->narg; i++)
- t->arg[i] = tyfix(st, ctx, t->arg[i]);
+ t->arg[i] = tyfix(st, ctx, t->arg[i], noerr);
}
for (i = 0; i < t->nsub; i++)
- t->sub[i] = tyfix(st, ctx, t->sub[i]);
+ t->sub[i] = tyfix(st, ctx, t->sub[i], noerr);
}
- if (t->type == Tyvar) {
+ if (t->type == Tyvar && !noerr) {
if (debugopt['T'])
dump(file, stdout);
- lfatal(t->loc, "underconstrained type %s near %s", tyfmt(buf, 1024, t), ctxstr(st, ctx));
+ lfatal(t->loc, "underconstrained type %s near line %d, %s", tyfmt(buf, 1024, t), ctx->loc.line, ctxstr(st, ctx));
}
if (debugopt['u'] && !tyeq(orig, t)) {
@@ -1774,7 +1777,7 @@ static void infercompn(Inferstate *st, Node *n)
if (tybase(t)->type == Typtr)
t = tybase(tf(st, t->sub[0]));
if (tybase(t)->type != Tystruct)
- fatal(n, "type %s does not support member operators near %s", tystr(t), ctxstr(st, n));
+ fatal(n, "type %s does not support member operators near line %d, %s", tystr(t), n->loc.line, ctxstr(st, n));
nl = t->sdecls;
for (i = 0; i < t->nmemb; i++) {
if (!strcmp(namestr(memb), declname(nl[i]))) {
@@ -1785,8 +1788,8 @@ static void infercompn(Inferstate *st, Node *n)
}
}
if (!found)
- fatal(aggr, "Type %s has no member \"%s\" near %s",
- tystr(type(st, aggr)), ctxstr(st, memb), ctxstr(st, aggr));
+ fatal(aggr, "Type %s has no member \"%s\" near line %d, %s",
+ tystr(type(st, aggr)), ctxstr(st, memb), n->loc.line, ctxstr(st, aggr));
}
static void checkstruct(Inferstate *st, Node *n)
@@ -1797,7 +1800,7 @@ static void checkstruct(Inferstate *st, Node *n)
t = tybase(tf(st, n->lit.type));
if (t->type != Tystruct)
- fatal(n, "Type %s for struct literal is not struct near %s", tystr(t), ctxstr(st, n));
+ fatal(n, "Type %s for struct literal is not struct near line %d, %s", tystr(t), n->loc.line, ctxstr(st, n));
for (i = 0; i < n->expr.nargs; i++) {
val = n->expr.args[i];
@@ -1812,8 +1815,8 @@ static void checkstruct(Inferstate *st, Node *n)
}
if (!et)
- fatal(n, "Could not find member %s in struct %s, near %s",
- namestr(name), tystr(t), ctxstr(st, n));
+ fatal(n, "Could not find member %s in struct %s, near line %d, %s",
+ namestr(name), tystr(t), n->loc.line, ctxstr(st, n));
unify(st, val, et, type(st, val));
}
@@ -1863,7 +1866,7 @@ static void stabsub(Inferstate *st, Stab *s)
for (i = 0; i < n; i++) {
t = tysearch(gettype(s, k[i]));
updatetype(s, k[i], t);
- tyfix(st, k[i], t);
+ tyfix(st, k[i], t, 0);
}
free(k);
@@ -1871,7 +1874,7 @@ static void stabsub(Inferstate *st, Stab *s)
for (i = 0; i < n; i++) {
d = getdcl(s, k[i]);
if (d)
- d->decl.type = tyfix(st, d, d->decl.type);
+ d->decl.type = tyfix(st, d, d->decl.type, 0);
}
free(k);
}
@@ -1931,7 +1934,7 @@ static void typesub(Inferstate *st, Node *n)
popstab();
break;
case Ndecl:
- settype(st, n, tyfix(st, n, type(st, n)));
+ settype(st, n, tyfix(st, n, type(st, n), 0));
if (n->decl.init)
typesub(st, n->decl.init);
break;
@@ -1968,7 +1971,7 @@ static void typesub(Inferstate *st, Node *n)
typesub(st, n->match.block);
break;
case Nexpr:
- settype(st, n, tyfix(st, n, type(st, n)));
+ settype(st, n, tyfix(st, n, type(st, n), 0));
typesub(st, n->expr.idx);
if (exprop(n) == Ocast && exprop(n->expr.args[0]) == Olit && n->expr.args[0]->expr.args[0]->lit.littype == Lint) {
settype(st, n->expr.args[0], exprtype(n));
@@ -1979,14 +1982,14 @@ static void typesub(Inferstate *st, Node *n)
break;
case Nfunc:
pushstab(n->func.scope);
- settype(st, n, tyfix(st, n, n->func.type));
+ settype(st, n, tyfix(st, n, n->func.type, 0));
for (i = 0; i < n->func.nargs; i++)
typesub(st, n->func.args[i]);
typesub(st, n->func.body);
popstab();
break;
case Nlit:
- settype(st, n, tyfix(st, n, type(st, n)));
+ settype(st, n, tyfix(st, n, type(st, n), 0));
switch (n->lit.littype) {
case Lfunc:
typesub(st, n->lit.fnval); break;
@@ -2219,10 +2222,11 @@ static void specialize(Inferstate *st, Node *f)
void applytraits(Inferstate *st, Node *f)
{
- size_t i;
- Node *n;
+ char *ctx, *name;
Trait *trait;
Type *ty;
+ size_t i;
+ Node *n;
pushstab(f->file.globls);
/* for now, traits can only be declared globally */
@@ -2230,8 +2234,12 @@ void applytraits(Inferstate *st, Node *f)
if (f->file.stmts[i]->type == Nimpl) {
n = f->file.stmts[i];
trait = gettrait(f->file.globls, n->impl.traitname);
- if (!trait)
- fatal(n, "trait %s does not exist near %s", namestr(n->impl.traitname), ctxstr(st, n));
+ if (!trait) {
+ name = namestr(n->impl.traitname);
+ ctx = ctxstr(st, n);
+ fatal(n, "trait %s does not exist near line %d, %s", name, n->loc.line, ctx);
+ free(ctx);
+ }
ty = tf(st, n->impl.type);
settrait(ty, trait);
}