shithub: mc

Download patch

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));