summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2015-09-29 00:19:22 -0700
committerOri Bernstein <ori@eigenstate.org>2015-09-29 00:19:22 -0700
commit5c7910da4770a4495e90eb5c243993ec778d4e68 (patch)
tree054bd0e3ac65e62913b5538b2abb5362da7314f3
parentc8c4b88ecadf05438561c05f97500e35843218c4 (diff)
downloadmc-5c7910da4770a4495e90eb5c243993ec778d4e68.tar.gz
Complain about missing trait impls.
Because exploding with an abort is confusing for the user.
-rw-r--r--parse/infer.c19
-rw-r--r--parse/stab.c10
2 files changed, 29 insertions, 0 deletions
diff --git a/parse/infer.c b/parse/infer.c
index d9e6844..da9debd 100644
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -2348,6 +2348,24 @@ void applytraits(Inferstate *st, Node *f)
popstab();
}
+void verify(Inferstate *st, Node *f)
+{
+ Node *n;
+ size_t i;
+
+ pushstab(f->file.globls);
+ /* for now, traits can only be declared globally */
+ for (i = 0; i < f->file.nstmts; i++) {
+ if (f->file.stmts[i]->type == Nimpl) {
+ n = f->file.stmts[i];
+ /* we merge, so we need to get it back again when error checking */
+ if (n->impl.isproto)
+ fatal(n, "missing implementation for prototype '%s %s'",
+ namestr(n->impl.traitname), tystr(n->impl.type));
+ }
+ }
+}
+
void infer(Node *file)
{
Inferstate st = {0,};
@@ -2366,5 +2384,6 @@ void infer(Node *file)
/* and replace type vars with actual types */
typesub(&st, file, 0);
specialize(&st, file);
+ verify(&st, file);
}
diff --git a/parse/stab.c b/parse/stab.c
index a17efeb..8e273ab 100644
--- a/parse/stab.c
+++ b/parse/stab.c
@@ -373,12 +373,17 @@ void putucon(Stab *st, Ucon *uc)
static int mergetrait(Trait *old, Trait *new)
{
+ Vis vis;
+
+ vis = max(old->vis, new->vis);
if (old->isproto && !new->isproto)
*old = *new;
else if (new->isproto && !old->isproto)
*new = *old;
else
return 0;
+ old->vis = vis;
+ new->vis = vis;
return 1;
}
@@ -403,12 +408,17 @@ void puttrait(Stab *st, Node *n, Trait *c)
static int mergeimpl(Node *old, Node *new)
{
+ Vis vis;
+
+ vis = max(old->impl.vis, new->impl.vis);
if (old->impl.isproto && !new->impl.isproto)
*old = *new;
else if (new->impl.isproto && !old->impl.isproto)
*new = *old;
else
return 0;
+ old->impl.vis = vis;
+ new->impl.vis = vis;
return 1;
}