6g interface changes:
	* allow conversion between nil interface and any type.
	* mark signatures as DUPOK so that multiple .6 can
	  contain sigt.*[]byte and only one gets used.

R=ken
OCL=18538
CL=18542
diff --git a/src/cmd/6g/obj.c b/src/cmd/6g/obj.c
index 8b2a47c..20763cf 100644
--- a/src/cmd/6g/obj.c
+++ b/src/cmd/6g/obj.c
@@ -516,7 +516,6 @@
 	int c, d, o;
 	Prog *p;
 	Type *f;
-	Sym *msym;
 
 	e = lookup(b->name);
 	for(d=0; d<nelem(dotlist); d++) {
@@ -596,292 +595,213 @@
 }
 
 void
-dumpsigt(void)
+dumpsigt(Type *t0, Sym *s)
 {
-	Dcl *d, *x;
-	Type *t, *f;
-	Sym *s1, *s;
-	int et, o;
+	Type *f, *t;
+	Sym *s1;
+	int o;
 	Sig *a, *b;
 	Prog *p;
-	char *sp;
 	char buf[NSYMB];
 
-	/*
-	 * put all the names into a linked
-	 * list so that it may be generated in sorted order.
-	 * the runtime will be linear rather than quadradic
-	 */
-	for(d=signatlist; d!=D; d=d->forw) {
-		if(d->op != OTYPE)
-			continue;
-		t = d->dtype;
-		et = t->etype;
-		if(et == TINTER)
-			continue;
-		at.sym = signame(t, d->block);
-		if(at.sym == S)
+	at.sym = s;
+
+	t = t0;
+	if(isptr[t->etype] && t->type->sym != S) {
+		t = t->type;
+		expandmeth(t->sym, t);
+	}
+
+	a = nil;
+	o = 0;
+	for(f=t->method; f!=T; f=f->down) {
+		if(f->type->etype != TFUNC)
 			continue;
 
-		// make unique
-		if(at.sym->local != 1)
-			continue;
-		at.sym->local = 2;
+		if(f->etype != TFIELD)
+			fatal("dumpsignatures: not field");
 
-		s = d->dsym;
-		if(s == S)
+		s1 = f->sym;
+		if(s1 == nil)
 			continue;
 
-		if(s->name[0] == '_')
-			continue;
+		b = mal(sizeof(*b));
+		b->link = a;
+		a = b;
 
-		if(strcmp(s->opackage, package) != 0)
-			continue;
+		a->name = s1->name;
+		a->hash = PRIME8*stringhash(a->name) + PRIME9*typehash(f->type, 0);
+		a->perm = o;
+		a->sym = methodsym(f->sym, t);
+		a->offset = f->embedded;	// need trampoline
 
-		expandmeth(s, t);
+		o++;
+	}
 
-		a = nil;
-		o = 0;
-		for(f=t->method; f!=T; f=f->down) {
-			if(f->type->etype != TFUNC)
-				continue;
+	a = lsort(a, sigcmp);
+	ot = 0;
+	ot = rnd(ot, maxround);	// base structure
 
-			if(f->etype != TFIELD)
-				fatal("dumpsignatures: not field");
+	// sigi[0].name = ""
+	ginsatoa(widthptr, stringo);
 
-			s1 = f->sym;
-			if(s1 == nil)
-				continue;
+	// save type name for runtime error message.
+	snprint(buf, sizeof buf, "%#T", t0);
+	datastring(buf, strlen(buf)+1);
 
-			b = mal(sizeof(*b));
-			b->link = a;
-			a = b;
+	// first field of an type signature contains
+	// the element parameters and is not a real entry
+	if(t->methptr & 2)
+		t = types[tptr];
 
-			a->name = s1->name;
-			a->hash = PRIME8*stringhash(a->name) + PRIME9*typehash(f->type, 0);
-			a->perm = o;
-			a->sym = methodsym(f->sym, t);
-			a->offset = f->embedded;	// need trampoline
+	// sigi[0].hash = elemalg
+	gensatac(wi, algtype(t));
 
-			o++;
-		}
+	// sigi[0].offset = width
+	gensatac(wi, t->width);
 
-		a = lsort(a, sigcmp);
-		ot = 0;
+	// skip the function
+	gensatac(widthptr, 0);
+
+	for(b=a; b!=nil; b=b->link) {
 		ot = rnd(ot, maxround);	// base structure
 
-		// sigi[0].name = ""
+		// sigx[++].name = "fieldname"
 		ginsatoa(widthptr, stringo);
 
-		// save type name for runtime error message.
-		// TODO(rsc): the * is a botch but right more often than not.
-		snprint(buf, sizeof buf, "*%#T", t);
-		datastring(buf, strlen(buf)+1);
+		// sigx[++].hash = hashcode
+		gensatac(wi, b->hash);
 
-		// first field of an type signature contains
-		// the element parameters and is not a real entry
+		// sigt[++].offset = of embeded struct
+		gensatac(wi, 0);
 
-		t = d->dtype;
-		if(t->methptr & 2)
-			t = types[tptr];
+		// sigt[++].fun = &method
+		gensatad(b->sym);
 
-		// sigi[0].hash = elemalg
-		gensatac(wi, algtype(t));
+		datastring(b->name, strlen(b->name)+1);
 
-		// sigi[0].offset = width
-		gensatac(wi, t->width);
-
-		// skip the function
-		gensatac(widthptr, 0);
-
-		for(b=a; b!=nil; b=b->link) {
-			ot = rnd(ot, maxround);	// base structure
-
-			// sigx[++].name = "fieldname"
-			ginsatoa(widthptr, stringo);
-
-			// sigx[++].hash = hashcode
-			gensatac(wi, b->hash);
-
-			// sigt[++].offset = of embeded struct
-			gensatac(wi, 0);
-
-			// sigt[++].fun = &method
-			gensatad(b->sym);
-
-			datastring(b->name, strlen(b->name)+1);
-
-			if(b->offset)
-				gentramp(d->dtype, b);
-		}
-
-		// nil field name at end
-		ot = rnd(ot, maxround);
-		gensatac(widthptr, 0);
-
-		p = pc;
-		gins(AGLOBL, N, N);
-		p->from = at;
-		p->to = ac;
-		p->to.offset = ot;
+		if(b->offset)
+			gentramp(t0, b);
 	}
 
-	if(stringo > 0) {
-		p = pc;
-		gins(AGLOBL, N, N);
-		p->from = ao;
-		p->to = ac;
-		p->to.offset = stringo;
-	}
+	// nil field name at end
+	ot = rnd(ot, maxround);
+	gensatac(widthptr, 0);
 
+	// set DUPOK to allow other .6s to contain
+	// the same signature.  only one will be chosen.
+	p = pc;
+	gins(AGLOBL, N, N);
+	p->from = at;
+	p->from.scale = DUPOK;
+	p->to = ac;
+	p->to.offset = ot;
 }
 
 void
-dumpsigi(void)
+dumpsigi(Type *t, Sym *s)
 {
-	Dcl *d, *x;
-	Type *t, *f;
-	Sym *s1, *s;
-	int et, o;
+	Type *f;
+	Sym *s1;
+	int o;
 	Sig *a, *b;
 	Prog *p;
 	char *sp;
 	char buf[NSYMB];
 
-	/*
-	 * put all the names into a linked
-	 * list so that it may be generated in sorted order.
-	 * the runtime will be linear rather than quadradic
-	 */
+	at.sym = s;
 
-	for(d=signatlist; d!=D; d=d->forw) {
-		if(d->op != OTYPE)
+	a = nil;
+	o = 0;
+	for(f=t->type; f!=T; f=f->down) {
+		if(f->type->etype != TFUNC)
 			continue;
 
-		t = d->dtype;
-		et = t->etype;
-		if(et != TINTER)
+		if(f->etype != TFIELD)
+			fatal("dumpsignatures: not field");
+
+		s1 = f->sym;
+		if(s1 == nil)
+			continue;
+		if(s1->name[0] == '_')
 			continue;
 
-		at.sym = signame(t, d->block);
-		if(at.sym == S)
-			continue;
+		b = mal(sizeof(*b));
+		b->link = a;
+		a = b;
 
-		// make unique
-		if(at.sym->local != 1)
-			continue;
-		at.sym->local = 2;
+		a->name = s1->name;
+		sp = strchr(s1->name, '_');
+		if(sp != nil)
+			a->name = sp+1;
 
-		s = d->dsym;
-		if(s == S)
-			continue;
+		a->hash = PRIME8*stringhash(a->name) + PRIME9*typehash(f->type, 0);
+		a->perm = o;
+		a->sym = methodsym(f->sym, t);
+		a->offset = 0;
 
-		if(s->name[0] == '_')
-			continue;
+		o++;
+	}
 
-		if(strcmp(s->opackage, package) != 0)
-			continue;
+	a = lsort(a, sigcmp);
+	ot = 0;
+	ot = rnd(ot, maxround);	// base structure
 
-//print("sigi: %S\n", s);
+	// sigi[0].name = ""
+	ginsatoa(widthptr, stringo);
 
-		a = nil;
-		o = 0;
-		for(f=t->type; f!=T; f=f->down) {
-			if(f->type->etype != TFUNC)
-				continue;
+	// save type name for runtime error message.
+	snprint(buf, sizeof buf, "%#T", t);
+	datastring(buf, strlen(buf)+1);
 
-			if(f->etype != TFIELD)
-				fatal("dumpsignatures: not field");
+	// first field of an interface signature
+	// contains the count and is not a real entry
 
-			s1 = f->sym;
-			if(s1 == nil)
-				continue;
-			if(s1->name[0] == '_')
-				continue;
+	// sigi[0].hash = 0
+	gensatac(wi, 0);
 
-			b = mal(sizeof(*b));
-			b->link = a;
-			a = b;
+	// sigi[0].offset = count
+	o = 0;
+	for(b=a; b!=nil; b=b->link)
+		o++;
+	gensatac(wi, o);
 
-			a->name = s1->name;
-			sp = strchr(s1->name, '_');
-			if(sp != nil)
-				a->name = sp+1;
-
-			a->hash = PRIME8*stringhash(a->name) + PRIME9*typehash(f->type, 0);
-			a->perm = o;
-			a->sym = methodsym(f->sym, t);
-			a->offset = 0;
-
-			o++;
-		}
-
-		a = lsort(a, sigcmp);
-		ot = 0;
+	for(b=a; b!=nil; b=b->link) {
+//print("	%s\n", b->name);
 		ot = rnd(ot, maxround);	// base structure
 
-		// sigi[0].name = ""
+		// sigx[++].name = "fieldname"
 		ginsatoa(widthptr, stringo);
 
-		// save type name for runtime error message.
-		// TODO(rsc): the * is a botch but right more often than not.
-		snprint(buf, sizeof buf, "%#T", t);
-		datastring(buf, strlen(buf)+1);
+		// sigx[++].hash = hashcode
+		gensatac(wi, b->hash);
 
-		// first field of an interface signature
-		// contains the count and is not a real entry
+		// sigi[++].perm = mapped offset of method
+		gensatac(wi, b->perm);
 
-		// sigi[0].hash = 0
-		gensatac(wi, 0);
-
-		// sigi[0].offset = count
-		o = 0;
-		for(b=a; b!=nil; b=b->link)
-			o++;
-		gensatac(wi, o);
-
-		for(b=a; b!=nil; b=b->link) {
-//print("	%s\n", b->name);
-			ot = rnd(ot, maxround);	// base structure
-
-			// sigx[++].name = "fieldname"
-			ginsatoa(widthptr, stringo);
-
-			// sigx[++].hash = hashcode
-			gensatac(wi, b->hash);
-
-			// sigi[++].perm = mapped offset of method
-			gensatac(wi, b->perm);
-
-			datastring(b->name, strlen(b->name)+1);
-		}
-
-		// nil field name at end
-		ot = rnd(ot, maxround);
-		gensatac(widthptr, 0);
-
-		p = pc;
-		gins(AGLOBL, N, N);
-		p->from = at;
-		p->to = ac;
-		p->to.offset = ot;
+		datastring(b->name, strlen(b->name)+1);
 	}
 
-	if(stringo > 0) {
-		p = pc;
-		gins(AGLOBL, N, N);
-		p->from = ao;
-		p->to = ac;
-		p->to.offset = stringo;
-	}
+	// nil field name at end
+	ot = rnd(ot, maxround);
+	gensatac(widthptr, 0);
+
+	p = pc;
+	gins(AGLOBL, N, N);
+	p->from = at;
+	p->from.scale = DUPOK;
+	p->to = ac;
+	p->to.offset = ot;
 }
 
 void
 dumpsignatures(void)
 {
+	int et;
 	Dcl *d, *x;
 	Type *t;
-	Sym *s;
+	Sym *s, *s1;
+	Prog *p;
 
 	memset(&at, 0, sizeof(at));
 	memset(&ao, 0, sizeof(ao));
@@ -923,19 +843,60 @@
 		if(t == T)
 			continue;
 
-		s = signame(t, 0);
+		s = signame(t);
 		if(s == S)
 			continue;
 
 		x = mal(sizeof(*d));
 		x->op = OTYPE;
-		x->dsym = d->dsym;
-		x->dtype = d->dtype;
+		if(t->etype == TINTER)
+			x->dtype = t;
+		else
+			x->dtype = ptrto(t);
 		x->forw = signatlist;
 		x->block = 0;
 		signatlist = x;
 //print("SIG = %lS %lS %lT\n", d->dsym, s, t);
 	}
-	dumpsigi();
-	dumpsigt();
+
+	// process signatlist
+	for(d=signatlist; d!=D; d=d->forw) {
+		if(d->op != OTYPE)
+			continue;
+		t = d->dtype;
+		et = t->etype;
+		s = signame(t);
+		if(s == S)
+			continue;
+
+		// only emit one
+		if(s->siggen)
+			continue;
+		s->siggen = 1;
+
+//print("dosig %T\n", t);
+		// don't emit signatures for *NamedStruct or interface if
+		// they were defined by other packages.
+		// (optimization)
+		s1 = S;
+		if(isptr[et] && t->type != T)
+			s1 = t->type->sym;
+		else if(et == TINTER)
+			s1 = t->sym;
+		if(s1 != S && strcmp(s1->opackage, package) != 0)
+			continue;
+
+		if(et == TINTER)
+			dumpsigi(t, s);
+		else
+			dumpsigt(t, s);
+	}
+
+	if(stringo > 0) {
+		p = pc;
+		gins(AGLOBL, N, N);
+		p->from = ao;
+		p->to = ac;
+		p->to.offset = stringo;
+	}
 }
diff --git a/src/cmd/6l/l.h b/src/cmd/6l/l.h
index faf5025..b9e8dd3 100644
--- a/src/cmd/6l/l.h
+++ b/src/cmd/6l/l.h
@@ -113,6 +113,7 @@
 	short	become;
 	short	frame;
 	uchar	subtype;
+	uchar	dupok;
 	ushort	file;
 	vlong	value;
 	int32	sig;
diff --git a/src/cmd/6l/obj.c b/src/cmd/6l/obj.c
index 8c001e7..bc7413f 100644
--- a/src/cmd/6l/obj.c
+++ b/src/cmd/6l/obj.c
@@ -972,6 +972,8 @@
 		}
 		if(p->to.offset > s->value)
 			s->value = p->to.offset;
+		if(p->from.scale & DUPOK)
+			s->dupok = 1;
 		goto loop;
 
 	case ADYNT:
@@ -1017,6 +1019,12 @@
 
 	case ADATA:
 	data:
+		// Assume that AGLOBL comes after ADATA.
+		// If we've seen an AGLOBL that said this sym was DUPOK,
+		// ignore any more ADATA we see, which must be
+		// redefinitions.
+		if(p->from.sym != S && p->from.sym->dupok)
+			goto loop;
 		if(edatap == P)
 			datap = p;
 		else
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
index 025edaa..7e4e22c 100644
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -125,6 +125,7 @@
 	uchar	methptr;	// 1=direct 2=pointer
 	uchar	printed;
 	uchar	embedded;	// TFIELD embedded type
+	uchar	siggen;
 
 	// TFUNCT
 	uchar	thistuple;
@@ -208,6 +209,7 @@
 	uchar	sym;		// huffman encoding in object file
 	uchar	local;		// created in this file
 	uchar	uniq;		// imbedded field name first found
+	uchar	siggen;		// signature generated
 
 	char*	opackage;	// original package name
 	char*	package;	// package name
@@ -596,11 +598,10 @@
 int	isinter(Type*);
 int	isnilinter(Type*);
 int	isddd(Type*);
-Sym*	globalsig(Type*);
 Type*	ismethod(Type*);
 Type*	methtype(Type*);
 int	needaddr(Type*);
-Sym*	signame(Type*, int);
+Sym*	signame(Type*);
 int	bytearraysz(Type*);
 int	eqtype(Type*, Type*, int);
 void	argtype(Node*, Type*);
diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c
index 15650c8..b6e225f 100644
--- a/src/cmd/gc/subr.c
+++ b/src/cmd/gc/subr.c
@@ -1606,134 +1606,53 @@
 }
 
 Sym*
-globalsig(Type *t)
+signame(Type *t)
 {
-	int et;
-	Sym *s;
-	char buf[NSYMB];
-	char *sigx;
-
-	if(t == T)
-		return S;
-
-	et = t->etype;
-	switch(et) {
-	default:
-		return S;
-
-	case TINTER:
-	case TDDD:
-		if(isnilinter(t)) {
-			sigx = "sigi";
-			strcpy(buf, "inter");
-			goto out;
-		}
-		return S;
-
-	case TPTR32:
-	case TPTR64:
-		if(isptrto(t, TSTRING)) {
-			et = TSTRING;
-			break;
-		}
-		return S;
-
-	case TINT:
-	case TINT8:
-	case TINT16:
-	case TINT32:
-	case TINT64:
-
-	case TUINT:
-	case TUINT8:
-	case TUINT16:
-	case TUINT32:
-	case TUINT64:
-	case TUINTPTR:
-
-	case TFLOAT:
-	case TFLOAT32:
-	case TFLOAT64:
-	case TFLOAT80:
-
-	case TBOOL:
-		break;
-	}
-	if(t->sym == S)
-		return S;
-	if(t->method != T)
-		return S;
-	if(strcmp(t->sym->name, types[et]->sym->name) != 0)
-		return S;
-	sigx = "sigt";
-	snprint(buf, sizeof(buf), "%#T", t);
-
-out:
-	s = pkglookup(buf, sigx);
-	if(s->oname == N) {
-		s->oname = newname(s);
-		s->oname->type = types[TUINT8];
-		s->oname->class = PEXTERN;
-		s->local = s->local;
-	}
-//print("*** %lT %lS\n", t, s);
-	return s;
-}
-
-Sym*
-signame(Type *t, int block)
-{
-	Sym *s, *ss;
+	Sym *ss;
 	char *e;
 	Dcl *x;
 	char buf[NSYMB];
 
+//print("signame %T\n", t);
 	if(t == T)
 		goto bad;
 
-	ss = globalsig(t);
-	if(ss != S)
-		return ss;
-
-	s = t->sym;
-	if(s == S) {
-		if(isptr[t->etype]) {
-			t = t->type;
-			if(t == T)
-				goto bad;
-		}
-		s = t->sym;
-		if(s == S)
-			goto bad;
-	}
-
 	e = "sigt";
 	if(t->etype == TINTER)
 		e = "sigi";
 
-	if(block == 0)
-		block = s->tblock;
-
-	if(block > 1) {
-		// record internal type for signature generation
-		x = mal(sizeof(*x));
-		x->op = OTYPE;
-		x->dsym = s;
-		x->dtype = s->otype;
-		x->forw = signatlist;
-		x->block = block;
-		signatlist = x;
-	}
+	// name is exported name, like *[]byte or *Struct or Interface
+	// (special symbols don't bother the linker).
 	snprint(buf, sizeof(buf), "%#T", t);
+
+	// special case: empty interface is named sigi.empty
+	// so that it can be referred to by the runtime.
+	if(strcmp(buf, "interface { }") == 0)
+		strcpy(buf, "empty");
+
 	ss = pkglookup(buf, e);
 	if(ss->oname == N) {
 		ss->oname = newname(ss);
 		ss->oname->type = types[TUINT8];
 		ss->oname->class = PEXTERN;
-		ss->local = s->local;
-//print("signame: %d %lS\n", ss->local, ss);
 	}
 
+	if(!t->siggen) {
+//print("siggen %T\n", t);
+		// special case: don't generate the empty interface
+		if(strcmp(buf, "empty") == 0)
+			goto out;
+
+		// record internal type for signature generation
+		x = mal(sizeof(*x));
+		x->op = OTYPE;
+		x->dtype = t;
+		x->forw = signatlist;
+		t->siggen = 1;
+		signatlist = x;
+	}
+
+out:
 	return ss;
 
 bad:
diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c
index f0627d4..ceae448 100644
--- a/src/cmd/gc/walk.c
+++ b/src/cmd/gc/walk.c
@@ -919,10 +919,10 @@
 			nnew = nod(ONEW, N, N);
 			nnew->type = nvar->type;
 			nnew = newcompat(nnew);
-			
+
 			nas = nod(OAS, nvar, nnew);
 			addtop = list(addtop, nas);
-			
+
 			nas = nod(OAS, nod(OIND, nvar, N), n->left);
 			addtop = list(addtop, nas);
 
@@ -1761,7 +1761,7 @@
 		return N;
 	}
 
-more:
+
 	a = nod(OAS, nodarg(l, fp), r);
 	a = convas(a);
 	nn = list(a, nn);
@@ -1786,6 +1786,8 @@
 //	if(eqtype(t2, nilptr, 0))
 //		return 1;
 
+	if(isnilinter(t1))
+		return 1;
 	if(isinter(t1)) {
 		if(isinter(t2))
 			return 1;
@@ -1793,6 +1795,8 @@
 			return 1;
 	}
 
+	if(isnilinter(t2))
+		return 1;
 	if(isinter(t2))
 		if(ismethod(t1))
 			return 1;
@@ -2649,13 +2653,13 @@
 				return I2I;
 			return Inone;
 		}
-		if(ismethod(rt) != T)
+		if(isnilinter(lt) || ismethod(rt) != T)
 			return T2I;
 		return Inone;
 	}
 
 	if(isinter(rt)) {
-		if(ismethod(lt) != T)
+		if(isnilinter(rt) || ismethod(lt) != T)
 			return I2T;
 		return Inone;
 	}
@@ -2682,7 +2686,7 @@
 		a = n;				// interface
 		r = a;
 
-		s = signame(tl, 0);		// sigi
+		s = signame(tl);		// sigi
 		if(s == S)
 			fatal("ifaceop: signame I2T");
 		a = s->oname;
@@ -2701,14 +2705,14 @@
 		a = n;				// elem
 		r = a;
 
-		s = signame(tr, 0);		// sigt
+		s = signame(tr);		// sigt
 		if(s == S)
 			fatal("ifaceop: signame-1 T2I: %lT", tr);
 		a = s->oname;
 		a = nod(OADDR, a, N);
 		r = list(a, r);
 
-		s = signame(tl, 0);		// sigi
+		s = signame(tl);		// sigi
 		if(s == S) {
 			fatal("ifaceop: signame-2 T2I: %lT", tl);
 		}
@@ -2728,7 +2732,7 @@
 		a = n;				// interface
 		r = a;
 
-		s = signame(tl, 0);		// sigi
+		s = signame(tl);		// sigi
 		if(s == S)
 			fatal("ifaceop: signame I2I");
 		a = s->oname;
diff --git a/src/runtime/iface.c b/src/runtime/iface.c
index 10a4c53..dba4c03 100644
--- a/src/runtime/iface.c
+++ b/src/runtime/iface.c
@@ -45,31 +45,7 @@
 
 static	Map*	hash[1009];
 
-#define	END	nil,0,0,nil
-
-Sigi	sigi·inter[2] =	{ (byte*)"interface {}", 0, 0, nil, 0, 0 };
-
-Sigt	sigt·int8[2] =	{ (byte*)"int8", ASIMP, 1, nil, END };
-Sigt	sigt·int16[2] =	{ (byte*)"int16", ASIMP, 2, nil, END };
-Sigt	sigt·int32[2] =	{ (byte*)"int32", ASIMP, 4, nil, END };
-Sigt	sigt·int64[2] =	{ (byte*)"int64", ASIMP, 8, nil, END };
-
-Sigt	sigt·uint8[2] =	{ (byte*)"uint8", ASIMP, 1, nil, END };
-Sigt	sigt·uint16[2] =	{ (byte*)"uint16", ASIMP, 2, nil, END };
-Sigt	sigt·uint32[2] =	{ (byte*)"uint32", ASIMP, 4, nil, END };
-Sigt	sigt·uint64[2] =	{ (byte*)"uint64", ASIMP, 8, nil, END };
-
-Sigt	sigt·float32[2] =	{ (byte*)"float32", ASIMP, 4, nil, END };
-Sigt	sigt·float64[2] =	{ (byte*)"float64", ASIMP, 8, nil, END };
-//Sigt	sigt·float80[2] =	{ (byte*)"float80", ASIMP, 0, nil, END };
-
-Sigt	sigt·bool[2] =	{ (byte*)"bool", ASIMP, 1, nil, END };
-Sigt	sigt·string[2] =	{ (byte*)"string", ASTRING, 8, nil, END };
-
-Sigt	sigt·int[2] =	{ (byte*)"int", ASIMP, 4, nil, END };
-Sigt	sigt·uint[2] =	{ (byte*)"uint", ASIMP, 4, nil, END };
-Sigt	sigt·uintptr[2] =	{ (byte*)"uintptr", ASIMP, 8, nil, END };
-Sigt	sigt·float[2] =	{ (byte*)"float", ASIMP, 4, nil, END };
+Sigi	sigi·empty[2] =	{ (byte*)"interface { }" };
 
 static void
 printsigi(Sigi *si)
@@ -506,7 +482,7 @@
 		retim = 0;
 		retit = 0;
 	} else {
-		retim = hashmap(sigi·inter, findtype(type), 0);
+		retim = hashmap(sigi·empty, findtype(type), 0);
 		retit = (void*)it;
 	}
 	FLUSH(&retim);