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