diff options
author | Ori Bernstein <ori@eigenstate.org> | 2015-09-29 00:19:22 -0700 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2015-09-29 00:19:22 -0700 |
commit | 5c7910da4770a4495e90eb5c243993ec778d4e68 (patch) | |
tree | 054bd0e3ac65e62913b5538b2abb5362da7314f3 | |
parent | c8c4b88ecadf05438561c05f97500e35843218c4 (diff) | |
download | mc-5c7910da4770a4495e90eb5c243993ec778d4e68.tar.gz |
Complain about missing trait impls.
Because exploding with an abort is confusing for the user.
-rw-r--r-- | parse/infer.c | 19 | ||||
-rw-r--r-- | parse/stab.c | 10 |
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; } |