shithub: mc

Download patch

ref: c89acbc27ac8af0314555f50aff5820e78f48fa1
parent: 6c02c9507bce9da833f0de58f93c589d5882e7e1
author: Ori Bernstein <[email protected]>
date: Fri Feb 7 06:35:08 EST 2014

Empty traits now work for named types.

    Named types are guaranteed to be unique, which means that
    the way we currently set the trait on them will work. Unnamed
    types are not unique, so we need a way to either uniqify them,
    or to set the trait on them as they are created.

--- a/6/simp.c
+++ b/6/simp.c
@@ -1756,6 +1756,7 @@
         n = file->file.stmts[i];
         switch (n->type) {
             case Nuse: /* nothing to do */ 
+            case Nimpl:
                 break;
             case Ndecl:
                 simpglobl(n, globls, &fn, &nfn, &blob, &nblob);
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -1423,7 +1423,6 @@
             popstab();
             break;
         case Nimpl:
-            die("Impl not yet implemented\n");
             break;
         case Nname:
         case Nlit:
@@ -1740,8 +1739,6 @@
             }
             break;
         case Nimpl:
-            die("Trait inference not yet implemented\n");
-            break;
         case Nname:
         case Nuse:
             break;
@@ -1851,7 +1848,6 @@
             nodetag(st, n->func.body, ingeneric);
             break;
         case Nimpl:
-            die("Impl not yet implemented\n");
             break;
 
         case Nuse: case Nname:
@@ -1910,6 +1906,28 @@
     }
 }
 
+void applytraits(Inferstate *st, Node *f)
+{
+    size_t i;
+    Node *n;
+    Trait *trait;
+    Type *ty;
+
+    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];
+            trait = gettrait(f->file.globls, n->impl.traitname);
+            if (!trait)
+                fatal(n->line, "trait %s does not exist near %s", namestr(n->impl.traitname), ctxstr(st, n));
+            ty = tf(st, n->impl.type);
+            settrait(ty, trait);
+        }
+    }
+    popstab();
+}
+
 void infer(Node *file)
 {
     Inferstate st = {0,};
@@ -1916,10 +1934,16 @@
 
     assert(file->type == Nfile);
     st.delayed = mkht(tyhash, tyeq);
+    /* set up the symtabs */
     loaduses(file);
     mergeexports(&st, file);
+
+    /* do the inference */
+    applytraits(&st, file);
     infernode(&st, file, NULL, NULL);
     postcheck(&st, file);
+
+    /* and replace type vars with actual types */
     typesub(&st, file);
     specialize(&st, file);
     tagexports(file->file.exports);