ref: f1e8c8cd310958e8203f4e3753a53141971a7466
parent: ddc3ab88147e458c49b9f3d58bcf0e574babde86
author: Ori Bernstein <[email protected]>
date: Fri Dec 19 20:16:04 EST 2014
Implement impl and trait merging.
--- a/parse/stab.c
+++ b/parse/stab.c
@@ -331,15 +331,28 @@
htput(st->uc, uc->name, uc);
}
+static int mergetrait(Trait *old, Trait *new)
+{
+ if (old->isproto && !new->isproto)
+ *old = *new;
+ else if (new->isproto && !old->isproto)
+ *new = *old;
+ else
+ return 0;
+ return 1;
+}
+
void puttrait(Stab *st, Node *n, Trait *c)
{
Traitdefn *td;
+ Trait *t;
- if (gettrait(st, n))
+ t = gettrait(st, n);
+ if (t && !mergetrait(t, c))
fatal(n, "Trait %s already defined", namestr(n));
if (gettype(st, n))
fatal(n, "Trait %s already defined as a type", namestr(n));
- td = xalloc(sizeof(Tydefn));
+ td = xalloc(sizeof(Traitdefn));
td->loc = n->loc;
td->name = n;
td->trait = c;
@@ -346,9 +359,23 @@
htput(st->tr, td->name, td);
}
+static int mergeimpl(Node *old, Node *new)
+{
+ if (old->impl.isproto && !new->impl.isproto)
+ *old = *new;
+ else if (new->impl.isproto && !old->impl.isproto)
+ *new = *old;
+ else
+ return 0;
+ return 1;
+}
+
void putimpl(Stab *st, Node *n)
{
- if (getimpl(st, n))
+ Node *impl;
+
+ impl = getimpl(st, n);
+ if (impl && !mergeimpl(impl, n))
fatal(n, "Trait %s already implemented over %s", namestr(n->impl.traitname), tystr(n->impl.type));
if (st->name)
setns(n->impl.traitname, namestr(st->name));