summaryrefslogtreecommitdiff
path: root/parse
diff options
context:
space:
mode:
Diffstat (limited to 'parse')
-rw-r--r--parse/export.c19
-rw-r--r--parse/gram.y23
-rw-r--r--parse/infer.c100
-rw-r--r--parse/node.c5
-rw-r--r--parse/parse.h7
-rw-r--r--parse/stab.c16
-rw-r--r--parse/tok.c1
-rw-r--r--parse/type.c68
-rw-r--r--parse/use.c44
9 files changed, 189 insertions, 94 deletions
diff --git a/parse/export.c b/parse/export.c
index 0a777e7..314f880 100644
--- a/parse/export.c
+++ b/parse/export.c
@@ -87,12 +87,19 @@ tagtype(Stab *st, Type *t, int ingeneric, int hidelocal)
tagtype(st, t->udecls[i]->etype, ingeneric, hidelocal);
break;
case Tyname:
+ case Tygeneric:
tagreflect(t);
for (i = 0; i < t->narg; i++)
tagtype(st, t->arg[i], ingeneric, hidelocal);
- case Tygeneric:
for (i = 0; i < t->ngparam; i++)
tagtype(st, t->gparam[i], ingeneric, hidelocal);
+ for (i = 0; i < t->narg; i++)
+ tagtype(st, t->arg[i], ingeneric, hidelocal);
+ break;
+ case Typaram:
+ if (t->trneed)
+ for (i = 0; bsiter(t->trneed, &i); i++)
+ tagtrait(st, traittab[i], ingeneric, hidelocal);
break;
default:
break;
@@ -271,18 +278,14 @@ tagexports(Node *file, int hidelocal)
free(k);
/* tag the impls */
- k = htkeys(st->impl, &n);
- for (i = 0; i < n; i++) {
- s = getimpl(st, k[i]);
+ for (i = 0; i < file->file.nimpl; i++) {
+ s = file->file.impl[i];
if (s->impl.vis != Visexport)
continue;
tagnode(st, s, 0, hidelocal);
tr = s->impl.trait;
tagtrait(st, tr, 0, hidelocal);
for (j = 0; j < tr->naux; j++)
- tr->aux[j]->vis = Visexport;
+ tr->aux[j]->vis = tr->vis;
}
- free(k);
-
}
-
diff --git a/parse/gram.y b/parse/gram.y
index 424538e..08e50a2 100644
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -31,7 +31,6 @@ int yylex(void);
static Op binop(int toktype);
static Node *mkpseudodecl(Srcloc l, Type *t);
static void installucons(Stab *st, Type *t);
-static void addtrait(Type *t, char *str);
static void setattrs(Node *dcl, char **attrs, size_t nattrs);
static void setupinit(Node *n);
@@ -85,7 +84,6 @@ static void setupinit(Node *n);
%token<tok> Ttype /* type */
%token<tok> Tfor /* for */
-%token<tok> Tin /* in */
%token<tok> Twhile /* while */
%token<tok> Tif /* if */
%token<tok> Telse /* else */
@@ -499,13 +497,13 @@ generictype
: Ttyparam {$$ = mktyparam($1->loc, $1->id);}
| Ttyparam Twith name {
$$ = mktyparam($1->loc, $1->id);
- addtrait($$, $3->name.name);
+ lappend(&$$->traits, &$$->ntraits, $3);
}
| Ttyparam Twith Toparen typaramlist Tcparen {
size_t i;
$$ = mktyparam($1->loc, $1->id);
for (i = 0; i < $4.nn; i++)
- addtrait($$, $4.nl[i]->name.name);
+ lappend(&$$->traits, &$$->ntraits, $4.nl[i]);
}
;
@@ -947,8 +945,6 @@ continue : Tcontinue
forstmt : Tfor optexprln loopcond optexprln block
{$$ = mkloopstmt($1->loc, $2, $3, $4, $5);}
- | Tfor expr Tin exprln block
- {$$ = mkiterstmt($1->loc, $2, $4, $5);}
| Tfor expr Tcolon exprln block
{$$ = mkiterstmt($1->loc, $2, $4, $5);}
| Tfor decl Tendln loopcond optexprln block {
@@ -1075,21 +1071,6 @@ static void setupinit(Node *n)
n->decl.name->name.name = strdup(s);
}
-static void addtrait(Type *t, char *str)
-{
- size_t i;
-
- for (i = 0; i < ntraittab; i++) {
- if (!strcmp(namestr(traittab[i]->name), str)) {
- if (!t->trneed)
- t->trneed = mkbs();
- bsput(t->trneed, i);
- return;
- }
- }
- lfatal(t->loc, "Constraint %s does not exist", str);
-}
-
static Node *mkpseudodecl(Srcloc l, Type *t)
{
static int nextpseudoid;
diff --git a/parse/infer.c b/parse/infer.c
index a05dd64..3d84dd1 100644
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -33,7 +33,7 @@ struct Traitmap {
static void infernode(Node **np, Type *ret, int *sawret);
static void inferexpr(Node **np, Type *ret, int *sawret);
static void inferdecl(Node *n);
-static int tryconstrain(Type *ty, Trait *tr);
+static int tryconstrain(Type *ty, Trait *tr, int update);
static Type *tf(Type *t);
@@ -353,6 +353,7 @@ occurs_rec(Type *sub, Bitset *bs)
{
size_t i;
+ sub = tf(sub);
if (bshas(bs, sub->tid))
return 1;
bsput(bs, sub->tid);
@@ -390,8 +391,9 @@ occursin(Type *a, Type *b)
int r;
bs = mkbs();
- bsput(bs, b->tid);
- r = occurs_rec(a, bs);
+ a = tf(a);
+ bsput(bs, a->tid);
+ r = occurs_rec(b, bs);
bsfree(bs);
return r;
}
@@ -413,6 +415,7 @@ needfreshenrec(Type *t, Bitset *visited)
{
size_t i;
+ t = tysearch(t);
if (bshas(visited, t->tid))
return 0;
bsput(visited, t->tid);
@@ -480,10 +483,10 @@ static void
tyresolve(Type *t)
{
size_t i;
+ Trait *tr;
if (t->resolved)
return;
-
/* type resolution should never throw errors about non-generic
* showing up within a generic type, so we push and pop a generic
* around resolution */
@@ -523,6 +526,15 @@ tyresolve(Type *t)
break;
}
+ for (i = 0; i < t->ntraits; i++) {
+ tr = gettrait(curstab(), t->traits[i]);
+ if (!tr)
+ lfatal(t->loc, "trait %s does not exist", ctxstr(t->traits[i]));
+ if (!t->trneed)
+ t->trneed = mkbs();
+ bsput(t->trneed, tr->uid);
+ }
+
for (i = 0; i < t->nsub; i++) {
t->sub[i] = tf(t->sub[i]);
if (t->sub[i] == t) {
@@ -629,8 +641,10 @@ tf(Type *orig)
popenv(orig->env);
} else if (orig->type == Typaram) {
tt = boundtype(t);
- if (tt)
+ if (tt) {
+ tyresolve(tt);
t = tt;
+ }
}
ingeneric -= isgeneric;
return t;
@@ -768,7 +782,7 @@ tymatchrank(Type *pat, Type *to)
if (!pat->trneed)
return 0;
for (i = 0; bsiter(pat->trneed, &i); i++)
- if (!tryconstrain(to, traittab[i]))
+ if (!tryconstrain(to, traittab[i], 0))
return -1;
return 0;
} else if (pat->type == Tyvar) {
@@ -848,7 +862,7 @@ tymatchrank(Type *pat, Type *to)
}
static int
-tryconstrain(Type *base, Trait *tr)
+tryconstrain(Type *base, Trait *tr, int update)
{
Traitmap *tm;
Bitset *bs;
@@ -859,12 +873,14 @@ tryconstrain(Type *base, Trait *tr)
ty = base;
tm = traitmap->sub[ty->type];
while (1) {
- if (ty->type == Typaram && bshas(ty->trneed, tr->uid))
- return 1;
+ if (ty->type == Typaram)
+ if (ty->trneed && bshas(ty->trneed, tr->uid))
+ return 1;
if (ty->type == Tyvar) {
if (!ty->trneed)
ty->trneed = mkbs();
- bsput(ty->trneed, tr->uid);
+ if (update)
+ bsput(ty->trneed, tr->uid);
return 1;
}
if (bshas(tm->traits, tr->uid))
@@ -880,11 +896,12 @@ tryconstrain(Type *base, Trait *tr)
if (tymatchrank(tm->filter[i], ty) >= 0)
return 1;
}
- if (!tm->sub[ty->type])
+ if (!ty->sub || ty->nsub != 1)
break;
- assert(ty->nsub == 1);
- tm = tm->sub[ty->type];
ty = ty->sub[0];
+ tm = tm->sub[ty->type];
+ if (!tm)
+ break;
}
if (base->type != Tyname)
break;
@@ -900,7 +917,7 @@ tryconstrain(Type *base, Trait *tr)
static void
constrain(Node *ctx, Type *base, Trait *tr)
{
- if (!tryconstrain(base, tr))
+ if (!tryconstrain(base, tr, 1))
fatal(ctx, "%s needs trait %s near %s", tystr(base), namestr(tr->name), ctxstr(ctx));
}
@@ -908,6 +925,7 @@ static void
traitsfor(Type *base, Bitset *dst)
{
Traitmap *tm;
+ Bitset *bs;
Type *ty;
size_t i;
@@ -917,7 +935,12 @@ traitsfor(Type *base, Bitset *dst)
while (1) {
if (ty->type == Tyvar)
break;
- bsunion(dst, tm->traits);
+ if (ty->type == Tyname && ty->ngparam == 0)
+ bs = htget(tm->name, ty->name);
+ else
+ bs = tm->traits;
+ if (bs)
+ bsunion(dst, bs);
for (i = 0; i < tm->nfilter; i++) {
if (tymatchrank(tm->filter[i], ty) >= 0)
bsput(dst, tm->filtertr[i]->uid);
@@ -1247,7 +1270,6 @@ unifycall(Node *n)
Type *ft;
ft = type(n->expr.args[0]);
-
if (ft->type == Tyvar) {
/* the first arg is the function itself, so it shouldn't be counted */
ft = mktyfunc(n->loc, &n->expr.args[1], n->expr.nargs - 1, mktyvar(n->loc));
@@ -1643,7 +1665,7 @@ inferexpr(Node **np, Type *ret, int *sawret)
case Odiveq: /* @a /= @a -> @a */
infersub(n, ret, sawret, &isconst);
t = type(args[0]);
- constrain(n, type(args[0]), traittab[Tcnum]);
+ constrain(n, t, traittab[Tcnum]);
isconst = args[0]->expr.isconst;
for (i = 1; i < nargs; i++) {
isconst = isconst && args[i]->expr.isconst;
@@ -1671,8 +1693,8 @@ inferexpr(Node **np, Type *ret, int *sawret)
case Obsreq: /* @a >>= @a -> @a */
infersub(n, ret, sawret, &isconst);
t = type(args[0]);
- constrain(n, type(args[0]), traittab[Tcnum]);
- constrain(n, type(args[0]), traittab[Tcint]);
+ constrain(n, t, traittab[Tcnum]);
+ constrain(n, t, traittab[Tcint]);
isconst = args[0]->expr.isconst;
for (i = 1; i < nargs; i++) {
isconst = isconst && args[i]->expr.isconst;
@@ -1901,19 +1923,21 @@ specializeimpl(Node *n)
Node *dcl, *proto, *name, *sym;
Tysubst *subst;
Type *ty;
- Trait *t;
+ Trait *tr;
size_t i, j;
int generic;
+ char *traitns;
- t = gettrait(curstab(), n->impl.traitname);
- if (!t)
+ tr = gettrait(curstab(), n->impl.traitname);
+ if (!tr)
fatal(n, "no trait %s\n", namestr(n->impl.traitname));
- n->impl.trait = t;
+ n->impl.trait = tr;
+ traitns = tr->name->name.ns;
dcl = NULL;
- if (n->impl.naux != t->naux)
+ if (n->impl.naux != tr->naux)
fatal(n, "%s incompatibly specialized with %zd types instead of %zd types",
- namestr(n->impl.traitname), n->impl.naux, t->naux);
+ namestr(n->impl.traitname), n->impl.naux, tr->naux);
n->impl.type = tf(n->impl.type);
pushenv(n->impl.type->env);
for (i = 0; i < n->impl.naux; i++)
@@ -1931,25 +1955,27 @@ specializeimpl(Node *n)
here.
*/
if (file->file.globls->name)
- setns(dcl->decl.name, file->file.globls->name);
- for (j = 0; j < t->nproto; j++) {
- if (nsnameeq(dcl->decl.name, t->proto[j]->decl.name)) {
- proto = t->proto[j];
+ setns(dcl->decl.name, traitns);
+ for (j = 0; j < tr->nproto; j++) {
+ if (nsnameeq(dcl->decl.name, tr->proto[j]->decl.name)) {
+ proto = tr->proto[j];
break;
}
}
if (!proto)
fatal(n, "declaration %s missing in %s, near %s", namestr(dcl->decl.name),
- namestr(t->name), ctxstr(n));
+ namestr(tr->name), ctxstr(n));
/* infer and unify types */
- verifytraits(n, t->param, n->impl.type);
+ pushenv(proto->decl.env);
+ verifytraits(n, tr->param, n->impl.type);
subst = mksubst();
- substput(subst, t->param, n->impl.type);
- for (j = 0; j < t->naux; j++)
- substput(subst, t->aux[j], n->impl.aux[j]);
+ substput(subst, tr->param, n->impl.type);
+ for (j = 0; j < tr->naux; j++)
+ substput(subst, tr->aux[j], n->impl.aux[j]);
ty = tyspecialize(type(proto), subst, delayed, NULL);
substfree(subst);
+ popenv(proto->decl.env);
generic = hasparams(ty);
if (generic)
@@ -1963,7 +1989,7 @@ specializeimpl(Node *n)
sym = getdcl(file->file.globls, name);
if (sym)
fatal(n, "trait %s already specialized with %s on %s:%d",
- namestr(t->name), tystr(n->impl.type),
+ namestr(tr->name), tystr(n->impl.type),
fname(sym->loc), lnum(sym->loc));
dcl->decl.name = name;
putdcl(file->file.globls, dcl);
@@ -1974,7 +2000,7 @@ specializeimpl(Node *n)
lappend(&proto->decl.gimpl, &proto->decl.ngimpl, dcl);
lappend(&proto->decl.gtype, &proto->decl.ngtype, ty);
}
- dcl->decl.vis = t->vis;
+ dcl->decl.vis = tr->vis;
lappend(&impldecl, &nimpldecl, dcl);
if (generic)
@@ -2792,7 +2818,7 @@ addtraittab(Traitmap *m, Trait *tr, Type *ty)
size_t i;
if (!m->sub[ty->type])
- m = mktraitmap();
+ m->sub[ty->type] = mktraitmap();
mm = m->sub[ty->type];
switch (ty->type) {
case Tygeneric:
diff --git a/parse/node.c b/parse/node.c
index 4a8df7d..d32d4ab 100644
--- a/parse/node.c
+++ b/parse/node.c
@@ -247,6 +247,7 @@ Node *
mkimplstmt(Srcloc loc, Node *name, Type *t, Type **aux, size_t naux, Node **decls, size_t ndecls)
{
Node *n;
+ size_t i;
n = mknode(loc, Nimpl);
n->impl.traitname = name;
@@ -256,6 +257,9 @@ mkimplstmt(Srcloc loc, Node *name, Type *t, Type **aux, size_t naux, Node **decl
n->impl.decls = decls;
n->impl.ndecls = ndecls;
lappend(&impltab, &nimpltab, n);
+ if (name->name.ns)
+ for (i = 0; i < ndecls; i++)
+ setns(decls[i]->decl.name, name->name.ns);
if (hasparams(t)) {
n->impl.env = mkenv();
bindtype(n->impl.env, t);
@@ -550,7 +554,6 @@ void
setns(Node *n, char *ns)
{
assert(!ns || !n->name.ns || !strcmp(n->name.ns, ns));
-
if (!ns)
return;
n->name.ns = strdup(ns);
diff --git a/parse/parse.h b/parse/parse.h
index edb65c6..9c6a658 100644
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -120,11 +120,14 @@ struct Tyenv {
struct Type {
Ty type;
- int tid;
+ uint32_t tid;
Srcloc loc;
Vis vis;
+ Node **traits; /* trait list */
+ size_t ntraits; /* trait list size */
+
Type **gparam; /* Tygeneric: type parameters that match the type args */
size_t ngparam; /* Tygeneric: count of type parameters */
Type **arg; /* Tyname: type arguments instantiated */
@@ -202,6 +205,8 @@ struct Node {
Node **init; /* all __init__ function names of our deps. NB, this
is a Nname, not an Ndecl */
size_t ninit;
+ Node **impl; /* impls defined in this file, across all namespaces */
+ size_t nimpl;
Node *localinit;/* and the local one, if any */
Stab *globls; /* global symtab */
Stab *builtins; /* global symtab */
diff --git a/parse/stab.c b/parse/stab.c
index 7c031f9..49fc776 100644
--- a/parse/stab.c
+++ b/parse/stab.c
@@ -505,12 +505,18 @@ putucon(Stab *st, Ucon *uc)
static int
mergetrait(Trait *old, Trait *new)
{
+ int hidden;
+
+ hidden = old->ishidden && new->ishidden;
if (old->isproto && !new->isproto)
*old = *new;
else if (new->isproto && !old->isproto)
*new = *old;
else if (!new->isimport && !old->isimport)
- return new->vis == Vishidden || old->vis == Vishidden;
+ if (new->vis == Vishidden || old->vis == Vishidden)
+ return 0;
+ new->ishidden = hidden;
+ old->ishidden = hidden;
return 1;
}
@@ -523,9 +529,12 @@ puttrait(Stab *st, Node *n, Trait *c)
st = findstab(st, n);
t = gettrait(st, n);
- if (t && !mergetrait(t, c))
+ if (t) {
+ if (mergetrait(t, c))
+ return;
fatal(n, "trait %s already defined on %s:%d",
namestr(n), fname(t->loc), lnum(t->loc));
+ }
ty = gettype(st, n);
if (ty)
fatal(n, "trait %s defined as a type on %s:%d",
@@ -572,6 +581,9 @@ putimpl(Stab *st, Node *n)
fatal(n, "trait %s already implemented over %s at %s:%d",
namestr(n->impl.traitname), tystr(n->impl.type),
fname(n->loc), lnum(n->loc));
+ /* if this is not a duplicate, record it for later export */
+ if (!impl)
+ lappend(&file->file.impl, &file->file.nimpl, n);
/*
The impl is not defined in this file, so setting the
trait name would be a bug here.
diff --git a/parse/tok.c b/parse/tok.c
index 119d637..eb5ba1c 100644
--- a/parse/tok.c
+++ b/parse/tok.c
@@ -191,7 +191,6 @@ kwd(char *s)
{"goto", Tgoto},
{"if", Tif},
{"impl", Timpl},
- {"in", Tin},
{"match", Tmatch},
{"pkg", Tpkg},
{"pkglocal", Tattr},
diff --git a/parse/type.c b/parse/type.c
index 7eb4146..ddd2cc5 100644
--- a/parse/type.c
+++ b/parse/type.c
@@ -15,6 +15,7 @@
#include "parse.h"
typedef struct Typename Typename;
+typedef struct Typair Typair;
Type **tytab = NULL;
Type **types = NULL;
size_t ntypes;
@@ -22,6 +23,13 @@ Trait **traittab;
size_t ntraittab;
Node **impltab;
size_t nimpltab;
+Htab *eqcache;
+
+struct Typair {
+ uint32_t atid;
+ uint32_t btid;
+};
+
static Htab *tydeduptab;
/* Built in type constraints */
@@ -731,10 +739,48 @@ tyhash(void *ty)
return hash;
}
+static ulong
+typairhash(void *pp)
+{
+ Typair *p;
+
+ p = pp;
+ return inthash(p->atid) ^ inthash(p->btid);
+}
+
+static int
+typaireq(void *a, void *b)
+{
+ Typair *pa, *pb;
+ pa = a;
+ pb = b;
+ return pa->atid == pb->atid && pa->btid == pb->btid;
+}
+
+static void
+equate(int32_t ta, int32_t tb)
+{
+ Typair *pa, *pb;
+
+ /*
+ * unfortunately, we can't negatively cache
+ * here because tyvars may unify down and
+ * eventually make the negative result inaccurate.
+ */
+ pa = zalloc(sizeof(Typair));
+ *pa = (Typair){ta, tb};
+ pb = zalloc(sizeof(Typair));
+ *pb = (Typair){ta, tb};
+
+ htput(eqcache, pa, pa);
+ htput(eqcache, pb, pb);
+}
+
int
tyeq_rec(Type *a, Type *b, Bitset *avisited, Bitset *bvisited, int search)
{
Type *x, *y;
+ Typair p;
size_t i;
int ret;
@@ -752,6 +798,9 @@ tyeq_rec(Type *a, Type *b, Bitset *avisited, Bitset *bvisited, int search)
return 0;
if (a->nmemb != b->nmemb)
return 0;
+ p = (Typair){a->tid, b->tid};
+ if (hthas(eqcache, &p))
+ return 1;
if (a->tid == b->tid)
return 1;
@@ -800,16 +849,22 @@ tyeq_rec(Type *a, Type *b, Bitset *avisited, Bitset *bvisited, int search)
break;
}
break;
+ case Tygeneric:
+ if (!nameeq(a->name, b->name))
+ ret = 0;
+ for (i = 0; i < a->ngparam; i++) {
+ ret = ret && tyeq_rec(a->gparam[i], b->gparam[i], avisited, bvisited, search);
+ if (!ret)
+ break;
+ }
+ break;
case Tyname:
if (!nameeq(a->name, b->name))
ret = 0;
for (i = 0; i < a->narg; i++) {
- x = a->arg[i];
- y = b->arg[i];
- if (!tyeq_rec(x, y, avisited, bvisited, search)) {
- ret = 0;
+ ret = ret && tyeq_rec(a->arg[i], b->arg[i], avisited, bvisited, search);
+ if (!ret)
break;
- }
}
break;
case Tyarray:
@@ -829,6 +884,8 @@ tyeq_rec(Type *a, Type *b, Bitset *avisited, Bitset *bvisited, int search)
}
}
}
+ if (ret)
+ equate(a->tid, b->tid);
bsdel(avisited, a->tid);
bsdel(bvisited, b->tid);
@@ -1042,6 +1099,7 @@ tyinit(Stab *st)
Type *ty;
Trait *tr;
+ eqcache = mkht(typairhash, typaireq);
tydeduptab = mkht(tyhash, tystricteq);
/* this must be done after all the types are created, otherwise we will
* clobber the memoized bunch of types with the type params. */
diff --git a/parse/use.c b/parse/use.c
index 51c0f85..28c48f6 100644
--- a/parse/use.c
+++ b/parse/use.c
@@ -856,7 +856,9 @@ protomap(Trait *tr, Type *ty, Node *dcl)
dclname = declname(dcl);
for (i = 0; i < tr->nproto; i++) {
- proto = tr->proto[i];
+ proto = getdcl(curstab(), tr->proto[i]->decl.name);
+ if (!proto)
+ proto = tr->proto[i];
protoname = declname(proto);
len = strlen(protoname);
p = strstr(dclname, protoname);
@@ -996,12 +998,11 @@ foundextlib:
break;
case 'R':
tr = traitunpickle(f);
- if (!tr->ishidden) {
- tr->vis = vis;
- puttrait(s, tr->name, tr);
- for (i = 0; i < tr->nproto; i++) {
- putdcl(s, tr->proto[i]);
- }
+ tr->vis = vis;
+ puttrait(s, tr->name, tr);
+ for (i = 0; i < tr->nproto; i++) {
+ putdcl(s, tr->proto[i]);
+ tr->proto[i]->decl.ishidden = tr->ishidden;
}
break;
case 'T':
@@ -1031,10 +1032,17 @@ foundextlib:
impl = unpickle(f);
impl->impl.isextern = 1;
impl->impl.vis = vis;
- /* specialized declarations always go into the global stab */
+ /*
+ * Unfortunately, impls can insert their symbols into whatever
+ * namespace the trait comes from. This complicates things a bit.
+ */
for (i = 0; i < impl->impl.ndecls; i++) {
- impl->impl.decls[i]->decl.isglobl = 1;
- putdcl(file->file.globls, impl->impl.decls[i]);
+ dcl = impl->impl.decls[i];
+ dcl->decl.isglobl = 1;
+ ns = file->file.globls;
+ if (dcl->decl.name->name.ns)
+ ns = findstab(s, dcl->decl.name->name.ns);
+ putdcl(ns, dcl);
}
break;
case EOF:
@@ -1043,7 +1051,6 @@ foundextlib:
}
fixtypemappings(s);
fixtraitmappings(s);
- fiximplmappings(s);
htfree(tidmap);
for (i = starttype; i < ntypes; i++) {
ty = types[i];
@@ -1075,6 +1082,7 @@ foundextlib:
bindtype(impl->impl.env, impl->impl.type);
}
}
+ fiximplmappings(s);
popstab();
return 1;
}
@@ -1167,6 +1175,7 @@ writeuse(FILE *f, Node *file)
{
Stab *st;
void **k;
+ Trait *tr;
Node *s, *u;
size_t i, n;
@@ -1211,25 +1220,24 @@ writeuse(FILE *f, Node *file)
}
for (i = 0; i < ntraittab; i++) {
- if (i < Ntraits || i != traittab[i]->uid)
+ tr = traittab[i];
+ if (tr->uid < Ntraits)
continue;
- if (traittab[i]->vis == Visexport || traittab[i]->vis == Vishidden) {
+ if (tr->vis == Visexport || tr->vis == Vishidden) {
wrbyte(f, 'R');
- traitpickle(f, traittab[i]);
+ traitpickle(f, tr);
}
}
- k = htkeys(st->impl, &n);
- for (i = 0; i < n; i++) {
+ for (i = 0; i < nimpltab; i++) {
/* merging during inference should remove all protos */
- s = getimpl(st, k[i]);
+ s = impltab[i];
assert(!s->impl.isproto);
if (s->impl.vis == Visexport || s->impl.vis == Vishidden) {
wrbyte(f, 'I');
pickle(f, s);
}
}
- free(k);
k = htkeys(st->dcl, &n);
for (i = 0; i < n; i++) {