shithub: mc

Download patch

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;