ref: 3dc461b0b09aae0b89c6310fe572f1bd7f693395
parent: ee50a71ce18d4721e868e575d26d894bc8f13e37
author: Ori Bernstein <ori@eigenstate.org>
date: Thu Dec 24 13:46:34 EST 2015
Fix importing/exporting traits.
--- a/6/simp.c
+++ b/6/simp.c
@@ -534,7 +534,7 @@
proto = tr->funcs[i];
dcl = htget(proto->decl.impls, ty);
var = mkexpr(loc, Ovar, dcl->decl.name, NULL);
- var->expr.type = dcl->decl.type;
+ var->expr.type = codetype(dcl->decl.type);
var->expr.did = dcl->decl.did;
return var;
}
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -2212,7 +2212,7 @@
default: break;
}
break;
- case Nimpl: putimpl(curstab(), n); break;
+ case Nimpl: putimpl(curstab(), n);
case Nname:
case Nuse: break;
case Nnone: die("Nnone should not be seen as node type!"); break;
@@ -2356,45 +2356,23 @@
Type *t;
st = file->file.globls;
- k = htkeys(st->dcl, &n);
- for (i = 0; i < n; i++) {
- s = getdcl(st, k[i]);
- if (s->decl.vis == Visexport)
- nodetag(st, s, 0, hidelocal);
- }
- free(k);
- k = htkeys(st->impl, &n);
- for (i = 0; i < n; i++) {
- s = getimpl(st, k[i]);
- if (s->impl.vis == Visexport)
- nodetag(st, s, 0, hidelocal);
- }
- free(k);
-
+ /* tag the initializers */
for (i = 0; i < file->file.ninit; i++)
nodetag(st, file->file.init[i], 0, hidelocal);
if (file->file.localinit)
nodetag(st, file->file.localinit, 0, hidelocal);
- k = htkeys(st->tr, &n);
+ /* tag the exported nodes */
+ k = htkeys(st->dcl, &n);
for (i = 0; i < n; i++) {
- tr = gettrait(st, k[i]);
- if (tr->vis == Visexport) {
- tr->param->vis = Visexport;
- for (i = 0; i < tr->nmemb; i++) {
- tr->memb[i]->decl.vis = Visexport;
- nodetag(st, tr->memb[i], 0, hidelocal);
- }
- for (i = 0; i < tr->nfuncs; i++) {
- tr->funcs[i]->decl.vis = Visexport;
- nodetag(st, tr->funcs[i], 0, hidelocal);
- }
- }
+ s = getdcl(st, k[i]);
+ if (s->decl.vis == Visexport)
+ nodetag(st, s, 0, hidelocal);
}
free(k);
- /* get the explicitly exported symbols */
+ /* get the explicitly exported types */
k = htkeys(st->ty, &n);
for (i = 0; i < n; i++) {
t = gettype(st, k[i]);
@@ -2415,7 +2393,35 @@
taghidden(t->gparam[j]);
}
}
+
+ /* tag the traits */
free(k);
+ k = htkeys(st->tr, &n);
+ for (i = 0; i < n; i++) {
+ tr = gettrait(st, k[i]);
+ if (tr->vis == Visexport) {
+ tr->param->vis = Visexport;
+ for (i = 0; i < tr->nmemb; i++) {
+ tr->memb[i]->decl.vis = Visexport;
+ nodetag(st, tr->memb[i], 0, hidelocal);
+ }
+ for (i = 0; i < tr->nfuncs; i++) {
+ tr->funcs[i]->decl.vis = Visexport;
+ nodetag(st, tr->funcs[i], 0, hidelocal);
+ }
+ }
+ }
+ free(k);
+
+ /* tag the impls */
+ k = htkeys(st->impl, &n);
+ for (i = 0; i < n; i++) {
+ s = getimpl(st, k[i]);
+ if (s->impl.vis == Visexport)
+ nodetag(st, s, 0, hidelocal);
+ }
+ free(k);
+
}
/* Take generics and build new versions of them
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -369,6 +369,7 @@
size_t ndecls;
Vis vis;
char isproto;
+ char isextern;
} impl;
};
};
--- a/parse/stab.c
+++ b/parse/stab.c
@@ -414,6 +414,9 @@
{
Vis vis;
+ /* extern traits should be deduped in use.c. */
+ if (old->impl.isextern && new->impl.isextern)
+ return 1;
if (old->impl.vis > new->impl.vis)
vis = old->impl.vis;
else
@@ -431,7 +434,18 @@
void putimpl(Stab *st, Node *n)
{
- Node *impl;
+ Node *impl, *name;
+ Stab *ns;
+
+ name = n->impl.traitname;
+ if (name->name.ns) {
+ ns = getns(file, name->name.ns);
+ if (!ns) {
+ ns = mkstab(0);
+ updatens(ns, name->name.ns);
+ }
+ st = ns;
+ }
impl = getimpl(st, n);
if (impl && !mergeimpl(impl, n))
--- a/parse/use.c
+++ b/parse/use.c
@@ -821,7 +821,7 @@
for (i = 0; i < tr->nfuncs; i++) {
protoname = declname(tr->funcs[i]);
len = strlen(protoname);
- if (strstr(dclname, protoname) == dclname && dclname[len] == '$')
+ if (strstr(dclname, protoname))
htput(tr->funcs[i]->decl.impls, ty, dcl);
}
}
@@ -837,8 +837,9 @@
tr = impl->impl.trait;
/* FIXME: handle duplicate impls properly */
- if (!getimpl(st, impl))
- putimpl(st, impl);
+ if (getimpl(st, impl))
+ continue;
+ putimpl(st, impl);
settrait(impl->impl.type, tr);
for (j = 0; j < impl->impl.ndecls; j++) {
putdcl(file->file.globls, impl->impl.decls[j]);
@@ -979,6 +980,8 @@
break;
case 'I':
impl = unpickle(f);
+ impl->impl.isextern = 1;
+ impl->impl.vis = vis;
/* specialized declarations always go into the global stab */
for (i = 0; i < impl->impl.ndecls; i++) {
impl->impl.decls[i]->decl.isglobl = 1;