shithub: mc

Download patch

ref: 685a0afcb76c7509ab97fcbc639b330478598bca
parent: 9e41da83ab7022ef3abffad13e0b30d08a1c4da5
author: Ori Bernstein <[email protected]>
date: Wed Feb 26 16:04:35 EST 2014

Add a back link for traits, instead of a bool.

    This allows us to link the impls to the trait, look
    them up, and generate trait-local specialized names,
    instead of hoping that we can hack around the decl
    id and such when hashing.

--- a/parse/dump.c
+++ b/parse/dump.c
@@ -138,8 +138,8 @@
                 outnode(n->file.stmts[i], fd, depth + 1);
             break;
         case Ndecl:
-            fprintf(fd, "(did = %zd, isconst = %d, isgeneric = %d, istraitfn=%d, isextern = %d, vis = %d)\n",
-                    n->decl.did, n->decl.isconst, n->decl.isgeneric, n->decl.istraitfn, n->decl.isextern, n->decl.vis);
+            fprintf(fd, "(did = %zd, trait=%s, isconst = %d, isgeneric = %d, isextern = %d, vis = %d)\n",
+                    n->decl.did, namestr(n->decl.trait->name), n->decl.isconst, n->decl.isgeneric, n->decl.isextern, n->decl.vis);
             outsym(n, fd, depth + 1);
             outnode(n->decl.init, fd, depth + 1);
             break;
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -342,8 +342,10 @@
         | Ttrait Tident generictype Tasn traitbody Tendblk /* trait definition */ {
                 size_t i;
                 $$ = mktrait($1->line, mkname($2->line, $2->str), $3, NULL, 0, $5.nl, $5.nn, 0);
-                for (i = 0; i < $5.nn; i++)
+                for (i = 0; i < $5.nn; i++) {
+                    $5.nl[i]->decl.trait = $$;
                     $5.nl[i]->decl.isgeneric = 1;
+                }
             }
         ;
 
@@ -354,7 +356,6 @@
                 $$ = $1;
                 d = mkdecl($2->line, mkname($2->line, $2->str), $4);
                 d->decl.isgeneric = 1;
-                d->decl.istraitfn = 1;
                 lappend(&$$.nl, &$$.nn, d);
             }
         ;
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -256,16 +256,17 @@
             Node *init;
             Node **impls;
             size_t nimpls;
+            /* 
+             If we have a link to a trait, we should only look it up
+             when specializing, but we should not create a new decl
+             node for it. That will be done when specializing the
+             impl.
+            */
+            Trait *trait;
             char  vis;
             char  isglobl;
             char  isconst;
             char  isgeneric;
-            /* 
-               specializations should only look up these, not generate
-               specialized versions. In fact, these should never have
-               initializers.
-            */
-            char  istraitfn;
             char  isextern;
             char  ishidden;
         } decl;
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -394,7 +394,7 @@
         printf("depth[%d] specializing [%d]%s => %s\n", stabstkoff, n->line, namestr(n->decl.name), namestr(*name));
     if (d)
         return d;
-    if (n->decl.istraitfn)
+    if (n->decl.trait)
         fatal(n->line, "No trait implemented for for %s\n", namestr(n->decl.name));
     /* namespaced names need to be looked up in their correct
      * context. */
--- a/parse/use.c
+++ b/parse/use.c
@@ -16,7 +16,7 @@
 static void wrstab(FILE *fd, Stab *val);
 static Stab *rdstab(FILE *fd);
 static void wrsym(FILE *fd, Node *val);
-static Node *rdsym(FILE *fd);
+static Node *rdsym(FILE *fd, Trait *ctx);
 static void pickle(FILE *fd, Node *n);
 static Node *unpickle(FILE *fd);
 
@@ -79,7 +79,7 @@
     st->name = unpickle(fd);
     n = rdint(fd);
     for (i = 0; i < n; i++)
-        putdcl(st, rdsym(fd));
+        putdcl(st, rdsym(fd, NULL));
 
     /* read types */
     n = rdint(fd);
@@ -146,13 +146,12 @@
     wrbool(fd, val->decl.isconst);
     wrbool(fd, val->decl.isgeneric);
     wrbool(fd, val->decl.isextern);
-    wrbool(fd, val->decl.istraitfn);
 
-    if (val->decl.isgeneric && !val->decl.istraitfn)
+    if (val->decl.isgeneric && !val->decl.trait)
         pickle(fd, val->decl.init);
 }
 
-static Node *rdsym(FILE *fd)
+static Node *rdsym(FILE *fd, Trait *ctx)
 {
     int line;
     Node *name;
@@ -165,13 +164,12 @@
 
     if (rdint(fd) == Vishidden)
         n->decl.ishidden = 1;
+    n->decl.trait = ctx;
     n->decl.isconst = rdbool(fd);
     n->decl.isgeneric = rdbool(fd);
     n->decl.isextern = rdbool(fd);
-    n->decl.istraitfn = rdbool(fd);
 
-
-    if (n->decl.isgeneric && !n->decl.istraitfn)
+    if (n->decl.isgeneric && !ctx)
         n->decl.init = unpickle(fd);
     return n;
 }
@@ -380,10 +378,10 @@
     tr->param = tyunpickle(fd);
     n = rdint(fd);
     for (i = 0; i < n; i++)
-        lappend(&tr->memb, &tr->nmemb, rdsym(fd));
+        lappend(&tr->memb, &tr->nmemb, rdsym(fd, tr));
     n = rdint(fd);
     for (i = 0; i < n; i++)
-        lappend(&tr->funcs, &tr->nfuncs, rdsym(fd));
+        lappend(&tr->funcs, &tr->nfuncs, rdsym(fd, tr));
     htput(trmap, (void*)uid, tr);
     return tr;
 }
@@ -492,7 +490,6 @@
             wrint(fd, n->decl.isconst);
             wrint(fd, n->decl.isgeneric);
             wrint(fd, n->decl.isextern);
-            wrint(fd, n->decl.istraitfn);
 
             /* init */
             pickle(fd, n->decl.init);
@@ -623,7 +620,6 @@
             n->decl.isconst = rdint(fd);
             n->decl.isgeneric = rdint(fd);
             n->decl.isextern = rdint(fd);
-            n->decl.istraitfn = rdint(fd);
 
             /* init */
             n->decl.init = unpickle(fd);
@@ -770,7 +766,7 @@
                 break;
             case 'G':
             case 'D':
-                dcl = rdsym(f);
+                dcl = rdsym(f, NULL);
                 putdcl(s, dcl);
                 break;
             case 'R':
@@ -896,7 +892,7 @@
     for (i = 0; i < n; i++) {
         s = getdcl(st, k[i]);
         /* trait functions get written out with their traits */
-        if (s->decl.istraitfn)
+        if (s->decl.trait)
             continue;
         if (s && s->decl.isgeneric)
             wrbyte(f, 'G');