shithub: mc

Download patch

ref: 80b458a8b54bf72741c4d61a7723b0997e157fb8
parent: 57d353555aedbad8ad4f2bb022a58d6b01cb941b
author: Ori Bernstein <[email protected]>
date: Wed Feb 19 15:42:46 EST 2014

Try to unify trait definitions and infer types.

    We still don't properly specialize.

--- a/parse/infer.c
+++ b/parse/infer.c
@@ -46,6 +46,7 @@
 
 static void infernode(Inferstate *st, Node *n, Type *ret, int *sawret);
 static void inferexpr(Inferstate *st, Node *n, 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 void bind(Inferstate *st, Node *n);
@@ -561,7 +562,7 @@
             sep = "";
             n = 0;
             for (i = 0; bsiter(a->traits, &i); i++) {
-                if (!bshas(b->traits, i))
+                if (!b->traits || !bshas(b->traits, i))
                     n += snprintf(traitbuf + n, sizeof(traitbuf) - n, "%s%s", sep, namestr(traittab[i]->name));
                 sep = ",";
             }
@@ -1295,6 +1296,38 @@
         unify(st, n, type(st, n)->sub[0], mktype(-1, Tyvoid));
 }
 
+static void specializeimpl(Inferstate *st, Node *n)
+{
+    Trait *t;
+    Node *dcl, *proto;
+    size_t i, j;
+
+    t = gettrait(curstab(), n->impl.traitname);
+    if (!t)
+        fatal(n->line, "No trait %s\n", namestr(n->impl.traitname));
+
+    dcl = NULL;
+    proto = NULL;
+    for (i = 0; i < n->impl.ndecls; i++) {
+        /* look up the prototype */
+        proto = NULL;
+        dcl = n->impl.decls[i];
+        for (j = 0; j < t->nfuncs; i++) {
+            if (nameeq(dcl->decl.name, t->funcs[j]->decl.name)) {
+                proto = t->funcs[j];
+                break;
+            }
+        }
+        if (!dcl || !proto)
+            fatal(n->line, "Declaration %s missing in %s, near %s\n",
+                  namestr(dcl), namestr(t->name), ctxstr(st, n));
+
+        /* infer and unify types */
+        inferdecl(st, dcl);
+        unify(st, n, type(st, dcl), type(st, proto));
+    }
+}
+
 static void inferdecl(Inferstate *st, Node *n)
 {
     Type *t;
@@ -1435,6 +1468,7 @@
             popstab();
             break;
         case Nimpl:
+            specializeimpl(st, n);
             break;
         case Nname:
         case Nlit: