[] and struct in interfaces.
other [] cleanup.

convert() is gone.

R=r
DELTA=352  (144 added, 68 deleted, 140 changed)
OCL=21660
CL=21662
diff --git a/src/cmd/6g/align.c b/src/cmd/6g/align.c
index 2a93052..9ced220 100644
--- a/src/cmd/6g/align.c
+++ b/src/cmd/6g/align.c
@@ -160,6 +160,8 @@
 		if(t->funarg)
 			fatal("dowidth fn struct %T", t);
 		w = widstruct(t, 0, 1);
+		if(w == 0)
+			w = maxround;
 		offmod(t);
 		break;
 
diff --git a/src/cmd/6g/obj.c b/src/cmd/6g/obj.c
index 13a9c9b..e060f06 100644
--- a/src/cmd/6g/obj.c
+++ b/src/cmd/6g/obj.c
@@ -668,14 +668,11 @@
 
 	// first field of an type signature contains
 	// the element parameters and is not a real entry
-	if(t->methptr & 2)
-		t = types[tptr];
-
 	// sigi[0].hash = elemalg
-	gensatac(wi, algtype(t));
+	gensatac(wi, algtype(t0));
 
 	// sigi[0].offset = width
-	gensatac(wi, t->width);
+	gensatac(wi, t0->width);
 
 	// skip the function
 	gensatac(widthptr, 0);
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
index c0faddd..9dfd0ec 100644
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -311,7 +311,7 @@
 	OINDEX, OINDEXPTR, OSLICE,
 	ONOT, OCOM, OPLUS, OMINUS, OSEND, ORECV,
 	OLITERAL, OREGISTER, OINDREG,
-	OCONV, OKEY,
+	OCONV, OCOMP, OKEY,
 	OBAD,
 
 	OEND,
diff --git a/src/cmd/gc/go.y b/src/cmd/gc/go.y
index 60a88a2..f6568a3 100644
--- a/src/cmd/gc/go.y
+++ b/src/cmd/gc/go.y
@@ -60,7 +60,7 @@
 %type	<node>		interfacedcl_list_r interfacedcl
 %type	<node>		structdcl_list_r structdcl embed
 %type	<node>		fnres Afnres Bfnres fnliteral xfndcl fndcl fnbody
-%type	<node>		keyexpr_list braced_keyexpr_list keyval_list_r keyval
+%type	<node>		braced_keyexpr_list keyval_list_r keyval
 
 %type	<type>		typedclname new_type
 %type	<type>		type Atype Btype
@@ -864,11 +864,6 @@
 		$$ = nod(ONEW, $5, N);
 		$$->type = $3;
 	}
-|	LCONVERT '(' type ',' keyexpr_list ')'
-	{
-		$$ = nod(OCONV, $5, N);
-		$$->type = $3;
-	}
 |	latype '(' expr ')'
 	{
 		$$ = nod(OCONV, $3, N);
@@ -884,7 +879,7 @@
 			$$ = nod(OEMPTY, N, N);
 		if(!iscomposite($1))
 			yyerror("illegal composite literal type %T", $1);
-		$$ = nod(OCONV, $$, N);
+		$$ = nod(OCOMP, $$, N);
 		$$->type = $1;
 	}
 |	fnliteral
@@ -987,7 +982,6 @@
 |	LNEW
 |	LBASETYPE
 |	LTYPEOF
-|	LCONVERT
 
 /*
  * keywords that we can
@@ -1674,13 +1668,6 @@
 		$$ = nod(OLIST, $1, $3);
 	}
 
-keyexpr_list:
-	keyval_list_r
-	{
-		$$ = rev($1);
-	}
-|	expr_list
-
 /*
  * have to spell this out using _r lists to avoid yacc conflict
  */
diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c
index dc2ec61..874265a 100644
--- a/src/cmd/gc/lex.c
+++ b/src/cmd/gc/lex.c
@@ -1051,7 +1051,6 @@
 	"chan",		LCHAN,		Txxx,
 	"const",	LCONST,		Txxx,
 	"continue",	LCONTINUE,	Txxx,
-	"convert",	LCONVERT,	Txxx,
 	"default",	LDEFAULT,	Txxx,
 	"else",		LELSE,		Txxx,
 	"export",	LEXPORT,	Txxx,
@@ -1268,7 +1267,6 @@
 	LNEW,		"NEW",
 	LLEN,		"LEN",
 	LFALL,		"FALL",
-	LCONVERT,	"CONVERT",
 	LIOTA,		"IOTA",
 	LPRINT,		"PRINT",
 	LPACKAGE,	"PACKAGE",
diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c
index 90cc9dc..3a488ec 100644
--- a/src/cmd/gc/subr.c
+++ b/src/cmd/gc/subr.c
@@ -649,6 +649,7 @@
 	[OFALL]		= "FALL",
 	[OCONV]		= "CONV",
 	[OCOM]		= "COM",
+	[OCOMP]		= "COMP",
 	[OCONST]	= "CONST",
 	[OCONTINUE]	= "CONTINUE",
 	[ODCLARG]	= "DCLARG",
@@ -1657,10 +1658,6 @@
 	if(t->etype == TINTER)
 		e = "sigi";
 
-	// don't allow arrays in interfaces
-	if(t->etype == TARRAY)
-		goto bad;
-
 	// name is exported name, like *[]byte or *Struct or Interface
 	// (special symbols don't bother the linker).
 	snprint(buf, sizeof(buf), "%#T", t);
diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c
index be0dd25..f249334 100644
--- a/src/cmd/gc/walk.c
+++ b/src/cmd/gc/walk.c
@@ -559,8 +559,7 @@
 		if(t == T)
 			goto ret;
 
-		if(!iscomposite(t))
-			convlit1(l, t, 1);
+		convlit1(l, t, 1);
 
 		// nil conversion
 		if(eqtype(t, l->type, 0)) {
@@ -595,26 +594,6 @@
 		if(issarray(t) && isdarray(l->type))
 			goto ret;
 
-		// structure literal
-		if(t->etype == TSTRUCT) {
-			indir(n, structlit(n));
-			goto ret;
-		}
-
-		// array literal
-		if(t->etype == TARRAY) {
-			r = arraylit(n);
-			indir(n, r);
-			goto ret;
-		}
-
-		// map literal
-		if(isptr[t->etype] && t->type != t && t->type->etype == TMAP) {
-			r = maplit(n);
-			indir(n, r);
-			goto ret;
-		}
-
 		// interface and structure
 		et = isandss(n->type, l);
 		if(et != Inone) {
@@ -642,6 +621,43 @@
 			yyerror("cannot convert %T to %T", l->type, t);
 		goto ret;
 
+	case OCOMP:
+		if(top == Etop)
+			goto nottop;
+
+		l = n->left;
+		if(l == N)
+			goto ret;
+
+		walktype(l, Erv);
+
+		t = n->type;
+		if(t == T)
+			goto ret;
+
+		// structure literal
+		if(t->etype == TSTRUCT) {
+			indir(n, structlit(n));
+			goto ret;
+		}
+
+		// array literal
+		if(t->etype == TARRAY) {
+			r = arraylit(n);
+			indir(n, r);
+			goto ret;
+		}
+
+		// map literal
+		if(isptr[t->etype] && t->type != t && t->type->etype == TMAP) {
+			r = maplit(n);
+			indir(n, r);
+			goto ret;
+		}
+
+		yyerror("bad composite literal %T", t);
+		goto ret;
+
 	case ORETURN:
 		if(top != Etop)
 			goto nottop;
@@ -944,7 +960,7 @@
 	case OADDR:
 		if(top != Erv)
 			goto nottop;
-		if(n->left->op == OCONV && n->left->type != T)
+		if(n->left->op == OCOMP && n->left->type != T)
 		if(n->left->type->etype == TSTRUCT) {
 			// turn &Point{1, 2} into allocation.
 			// initialize with
@@ -1873,8 +1889,6 @@
 //	if(eqtype(t2, nilptr, 0))
 //		return 1;
 
-	if(issarray(t1))
-		return 0;
 	if(isnilinter(t1))
 		return 1;
 	if(isinter(t1)) {
@@ -2722,11 +2736,8 @@
 				return I2I;
 			return Inone;
 		}
-		if(isnilinter(lt)) {
-			if(!issimple[rt->etype] && !isptr[rt->etype])
-				yyerror("using %T as interface is unimplemented", rt);
+		if(isnilinter(lt))
 			return T2I;
-		}
 		if(ismethod(rt) != T)
 			return T2I;
 		return Inone;
diff --git a/src/lib/fmt/fmt_test.go b/src/lib/fmt/fmt_test.go
index ac5511a..20539df 100644
--- a/src/lib/fmt/fmt_test.go
+++ b/src/lib/fmt/fmt_test.go
@@ -26,15 +26,6 @@
 	out string;
 }
 
-// TODO(rsc): return []byte, but need to be able to pass as interface.
-func Bytes(s string) *[]byte {
-	b := new([]byte, len(s)+1);
-	syscall.StringToBytes(b, s);
-	bp := new(*[]byte);
-	*bp = b[0:len(s)];
-	return bp;
-}
-
 const B32 uint32 = 1<<32 - 1
 const B64 uint64 = 1<<64 - 1
 
@@ -47,12 +38,12 @@
 	FmtTest{ "%q",	"abc",	`"abc"` },
 
 	// basic bytes
-	FmtTest{ "%s",	Bytes("abc"),	"abc" },
-	FmtTest{ "%x",	Bytes("abc"),	"616263" },
-	FmtTest{ "% x",	Bytes("abc"),	"61 62 63" },
-	FmtTest{ "%x",	Bytes("xyz"),	"78797a" },
-	FmtTest{ "%X",	Bytes("xyz"),	"78797A" },
-	FmtTest{ "%q",	Bytes("abc"),	`"abc"` },
+	FmtTest{ "%s",	io.StringBytes("abc"),	"abc" },
+	FmtTest{ "%x",	io.StringBytes("abc"),	"616263" },
+	FmtTest{ "% x",	io.StringBytes("abc"),	"61 62 63" },
+	FmtTest{ "%x",	io.StringBytes("xyz"),	"78797a" },
+	FmtTest{ "%X",	io.StringBytes("xyz"),	"78797A" },
+	FmtTest{ "%q",	io.StringBytes("abc"),	`"abc"` },
 
 	// escaped strings
 	FmtTest{ "%#q",	`abc`,		"`abc`" },
diff --git a/src/lib/fmt/print.go b/src/lib/fmt/print.go
index d32fd53..bb69ba4 100644
--- a/src/lib/fmt/print.go
+++ b/src/lib/fmt/print.go
@@ -253,12 +253,11 @@
 	switch v.Kind() {
 	case reflect.StringKind:
 		return v.(reflect.StringValue).Get(), true;
-	case reflect.PtrKind:
-		if val, ok := v.Interface().(*[]byte); ok {
-			return string(*val), true;
+	case reflect.ArrayKind:
+		if val, ok := v.Interface().([]byte); ok {
+			return string(val), true;
 		}
 	}
-	// TODO(rsc): check for Interface().([]byte) too.
 	return "", false;
 }
 
diff --git a/src/lib/net/ip_test.go b/src/lib/net/ip_test.go
index 7fd8539..131c844 100644
--- a/src/lib/net/ip_test.go
+++ b/src/lib/net/ip_test.go
@@ -14,7 +14,7 @@
 }
 
 func Equal(a []byte, b []byte) bool {
-	if a == b {
+	if a == nil && b == nil {
 		return true
 	}
 	if a == nil || b == nil || len(a) != len(b) {
diff --git a/src/lib/reflect/type.go b/src/lib/reflect/type.go
index e187a54..f978e78 100644
--- a/src/lib/reflect/type.go
+++ b/src/lib/reflect/type.go
@@ -124,7 +124,6 @@
 }
 
 func NewStubType(name string, typ Type) *StubType {
-if typ == nil && len(name) > 0 && name[0] == '*' { panicln("NewStubType", name, typ) }
 	return &StubType{name, typ}
 }
 
diff --git a/src/runtime/iface.c b/src/runtime/iface.c
index a5259db..99beb39 100644
--- a/src/runtime/iface.c
+++ b/src/runtime/iface.c
@@ -8,10 +8,10 @@
 
 typedef	struct	Sigt	Sigt;
 typedef	struct	Sigi	Sigi;
-typedef	struct	Map	Map;
+typedef	struct	Itype	Itype;
 
 /*
- * the layout of Sigt and Sigi are known to the compiler
+ * the layout of Iface, Sigt and Sigi are known to the compiler
  */
 struct	Sigt
 {
@@ -28,17 +28,17 @@
 	uint32	perm;		// location of fun in Sigt // first is size
 };
 
-struct	Map
+struct	Itype
 {
 	Sigi*	sigi;
 	Sigt*	sigt;
-	Map*	link;
+	Itype*	link;
 	int32	bad;
 	int32	unused;
 	void	(*fun[])(void);
 };
 
-static	Map*	hash[1009];
+static	Itype*	hash[1009];
 
 Sigi	sigi·empty[2] =	{ (byte*)"interface { }" };
 
@@ -50,6 +50,8 @@
 
 	sys·printpointer(si);
 	prints("{");
+	prints((int8*)si[0].name);
+	prints(":");
 	for(i=1;; i++) {
 		name = si[i].name;
 		if(name == nil)
@@ -74,6 +76,8 @@
 
 	sys·printpointer(st);
 	prints("{");
+	prints((int8*)st[0].name);
+	prints(":");
 	sys·printint(st[0].hash);	// first element has alg
 	prints(",");
 	sys·printint(st[0].offset);	// first element has width
@@ -96,22 +100,28 @@
 }
 
 static void
-printiface(Map *im, void *it)
+printiface(Iface i)
 {
+	int32 j;
+
 	prints("(");
-	sys·printpointer(im);
+	sys·printpointer(i.type);
 	prints(",");
-	sys·printpointer(it);
+	for(j=0; j<nelem(i.data); j++) {
+		if(j > 0)
+			prints(".");
+		sys·printpointer(i.data[0]);
+	}
 	prints(")");
 }
 
-static Map*
-hashmap(Sigi *si, Sigt *st, int32 canfail)
+static Itype*
+itype(Sigi *si, Sigt *st, int32 canfail)
 {
 	int32 nt, ni;
 	uint32 ihash, h;
 	byte *sname, *iname;
-	Map *m;
+	Itype *m;
 
 	h = ((uint32)(uint64)si + (uint32)(uint64)st) % nelem(hash);
 	for(m=hash[h]; m!=nil; m=m->link) {
@@ -129,7 +139,7 @@
 					goto throw;
 				}
 			}
-			// prints("old hashmap\n");
+			// prints("old itype\n");
 			return m;
 		}
 	}
@@ -177,15 +187,22 @@
 	}
 	m->link = hash[h];
 	hash[h] = m;
-	// prints("new hashmap\n");
+	// prints("new itype\n");
 	return m;
 }
 
 // ifaceT2I(sigi *byte, sigt *byte, elem any) (ret any);
 void
-sys·ifaceT2I(Sigi *si, Sigt *st, void *elem, Map *retim, void *retit)
+sys·ifaceT2I(Sigi *si, Sigt *st, ...)
 {
-//	int32 alg, wid;
+	byte *elem;
+	Iface *ret;
+	int32 alg, wid;
+
+	elem = (byte*)(&st+1);
+	wid = st->offset;
+	ret = (Iface*)(elem + rnd(wid, 8));
+	ret->type = itype(si, st, 0);
 
 	if(debug) {
 		prints("T2I sigi=");
@@ -193,39 +210,49 @@
 		prints(" sigt=");
 		printsigt(st);
 		prints(" elem=");
-		sys·printpointer(elem);
+		sys·printpointer(*(void**)elem);
 		prints("\n");
 	}
 
-	retim = hashmap(si, st, 0);
-
-//	alg = st->hash;
-//	wid = st->offset;
-//	algarray[alg].copy(wid, &retit, &elem);
-	retit = elem;		// for speed could do this
+	alg = st->hash;
+	wid = st->offset;
+	if(wid <= sizeof ret->data)
+		algarray[alg].copy(wid, ret->data, elem);
+	else{
+		ret->data[0] = mal(wid);
+		if(debug)
+			printf("T2I mal %d %p\n", wid, ret->data[0]);
+		algarray[alg].copy(wid, ret->data[0], elem);
+	}
 
 	if(debug) {
 		prints("T2I ret=");
-		printiface(retim, retit);
+		printiface(*ret);
 		prints("\n");
 	}
 
-	FLUSH(&retim);
-	FLUSH(&retit);
+	FLUSH(&ret);
 }
 
 // ifaceI2T(sigt *byte, iface any) (ret any);
 void
-sys·ifaceI2T(Sigt *st, Map *im, void *it, void *ret)
+sys·ifaceI2T(Sigt *st, Iface i, ...)
 {
+	Itype *im;
+	byte *ret;
+	int32 wid, alg;
+
+	ret = (byte*)(&i+1);
+
 	if(debug) {
 		prints("I2T sigt=");
 		printsigt(st);
 		prints(" iface=");
-		printiface(im, it);
+		printiface(i);
 		prints("\n");
 	}
 
+	im = i.type;
 	if(im == nil) {
 		prints("interface is nil, not ");
 		prints((int8*)st[0].name);
@@ -243,10 +270,16 @@
 		throw("interface conversion");
 	}
 
-	ret = it;
+	alg = st->hash;
+	wid = st->offset;
+	if(wid <= sizeof i.data)
+		algarray[alg].copy(wid, ret, i.data);
+	else
+		algarray[alg].copy(wid, ret, i.data[0]);
+
 	if(debug) {
 		prints("I2T ret=");
-		sys·printpointer(ret);
+		sys·printpointer(*(void**)ret);
 		prints("\n");
 	}
 	FLUSH(&ret);
@@ -254,94 +287,113 @@
 
 // ifaceI2T2(sigt *byte, iface any) (ret any, ok bool);
 void
-sys·ifaceI2T2(Sigt *st, Map *im, void *it, void *ret, bool ok)
+sys·ifaceI2T2(Sigt *st, Iface i, ...)
 {
+	byte *ret;
+	bool *ok;
+	Itype *im;
+	int32 alg, wid;
+
+	ret = (byte*)(&i+1);
+	alg = st->hash;
+	wid = st->offset;
+	ok = (bool*)(ret+rnd(wid, 8));
+
 	if(debug) {
 		prints("I2T2 sigt=");
 		printsigt(st);
 		prints(" iface=");
-		printiface(im, it);
+		printiface(i);
 		prints("\n");
 	}
 
+	im = i.type;
 	if(im == nil || im->sigt != st) {
-		ret = 0;
-		ok = 0;
+		*ok = false;
+		sys·memclr(ret, wid);
 	} else {
-		ret = it;
-		ok = 1;
+		*ok = true;
+		if(wid <= sizeof i.data)
+			algarray[alg].copy(wid, ret, i.data);
+		else
+			algarray[alg].copy(wid, ret, i.data[0]);
 	}
 	if(debug) {
 		prints("I2T2 ret=");
-		sys·printpointer(ret);
-		sys·printbool(ok);
+		sys·printpointer(*(void**)ret);
+		sys·printbool(*ok);
 		prints("\n");
 	}
-	FLUSH(&ret);
-	FLUSH(&ok);
 }
 
 // ifaceI2I(sigi *byte, iface any) (ret any);
 void
-sys·ifaceI2I(Sigi *si, Map *im, void *it, Map *retim, void *retit)
+sys·ifaceI2I(Sigi *si, Iface i, Iface ret)
 {
+	Itype *im;
+	int32 j;
+
 	if(debug) {
 		prints("I2I sigi=");
 		printsigi(si);
 		prints(" iface=");
-		printiface(im, it);
+		printiface(i);
 		prints("\n");
 	}
 
+	im = i.type;
 	if(im == nil) {
 		// If incoming interface is uninitialized (zeroed)
 		// make the outgoing interface zeroed as well.
-		retim = nil;
-		retit = nil;
+		ret.type = nil;
+		for(j=0; j<nelem(ret.data); j++)
+			ret.data[j] = nil;
 	} else {
-		retit = it;
-		retim = im;
+		ret = i;
 		if(im->sigi != si)
-			retim = hashmap(si, im->sigt, 0);
+			ret.type = itype(si, im->sigt, 0);
 	}
 
 	if(debug) {
 		prints("I2I ret=");
-		printiface(retim, retit);
+		printiface(ret);
 		prints("\n");
 	}
 
-	FLUSH(&retim);
-	FLUSH(&retit);
+	FLUSH(&ret);
 }
 
 // ifaceI2I2(sigi *byte, iface any) (ret any, ok bool);
 void
-sys·ifaceI2I2(Sigi *si, Map *im, void *it, Map *retim, void *retit, bool ok)
+sys·ifaceI2I2(Sigi *si, Iface i, Iface ret, bool ok)
 {
+	Itype *im;
+	int32 j;
+
 	if(debug) {
 		prints("I2I2 sigi=");
 		printsigi(si);
 		prints(" iface=");
-		printiface(im, it);
+		printiface(i);
 		prints("\n");
 	}
 
+	im = i.type;
 	if(im == nil) {
 		// If incoming interface is uninitialized (zeroed)
 		// make the outgoing interface zeroed as well.
-		retim = nil;
-		retit = nil;
+		ret.type = nil;
+		for(j=0; j<nelem(ret.data); j++)
+			ret.data[j] = nil;
 		ok = 1;
 	} else {
-		retit = it;
-		retim = im;
+		ret = i;
 		ok = 1;
 		if(im->sigi != si) {
-			retim = hashmap(si, im->sigt, 1);
-			if(retim == nil) {
-				retit = nil;
-				retim = nil;
+			ret.type = itype(si, im->sigt, 1);
+			if(ret.type == nil) {
+				for(j=0; j<nelem(ret.data); j++)
+					ret.data[j] = nil;
 				ok = 0;
 			}
 		}
@@ -349,51 +401,55 @@
 
 	if(debug) {
 		prints("I2I ret=");
-		printiface(retim, retit);
+		printiface(ret);
 		prints("\n");
 	}
 
-	FLUSH(&retim);
-	FLUSH(&retit);
+	FLUSH(&ret);
 	FLUSH(&ok);
 }
 
 // ifaceeq(i1 any, i2 any) (ret bool);
 void
-sys·ifaceeq(Map *im1, void *it1, Map *im2, void *it2, byte ret)
+sys·ifaceeq(Iface i1, Iface i2, bool ret)
 {
 	int32 alg, wid;
 
 	if(debug) {
 		prints("Ieq i1=");
-		printiface(im1, it1);
+		printiface(i1);
 		prints(" i2=");
-		printiface(im2, it2);
+		printiface(i2);
 		prints("\n");
 	}
 
 	ret = false;
 
 	// are they both nil
-	if(im1 == nil) {
-		if(im2 == nil)
+	if(i1.type == nil) {
+		if(i2.type == nil)
 			goto yes;
 		goto no;
 	}
-	if(im2 == nil)
+	if(i2.type == nil)
 		goto no;
 
 	// value
-	alg = im1->sigt->hash;
-	if(alg != im2->sigt->hash)
+	alg = i1.type->sigt->hash;
+	if(alg != i2.type->sigt->hash)
 		goto no;
 
-	wid = im1->sigt->offset;
-	if(wid != im2->sigt->offset)
+	wid = i1.type->sigt->offset;
+	if(wid != i2.type->sigt->offset)
 		goto no;
 
-	if(!algarray[alg].equal(wid, &it1, &it2))
-		goto no;
+	if(wid <= sizeof i1.data) {
+		if(!algarray[alg].equal(wid, i1.data, i2.data))
+			goto no;
+	} else {
+		if(!algarray[alg].equal(wid, i1.data[0], i2.data[0]))
+			goto no;
+	}
 
 yes:
 	ret = true;
@@ -407,13 +463,13 @@
 }
 
 void
-sys·printinter(Map *im, void *it)
+sys·printinter(Iface i)
 {
-	printiface(im, it);
+	printiface(i);
 }
 
 void
-sys·reflect(Map *im, void *it, uint64 retit, string rettype)
+sys·reflect(Itype *im, void *it, uint64 retit, string rettype)
 {
 	if(im == nil) {
 		retit = 0;
@@ -476,13 +532,13 @@
 }
 
 void
-sys·unreflect(uint64 it, string type, Map *retim, void *retit)
+sys·unreflect(uint64 it, string type, Itype *retim, void *retit)
 {
 	if(cmpstring(type, emptystring) == 0) {
 		retim = 0;
 		retit = 0;
 	} else {
-		retim = hashmap(sigi·empty, findtype(type), 0);
+		retim = itype(sigi·empty, findtype(type), 0);
 		retit = (void*)it;
 	}
 	FLUSH(&retim);
diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h
index c0f943a..bb970da 100644
--- a/src/runtime/runtime.h
+++ b/src/runtime/runtime.h
@@ -48,8 +48,10 @@
 typedef	struct	Stktop		Stktop;
 typedef	struct	String		*string;
 typedef	struct	Usema		Usema;
-typedef	struct	SigTab	SigTab;
-typedef	struct	MCache	MCache;
+typedef	struct	SigTab		SigTab;
+typedef	struct	MCache		MCache;
+typedef	struct	Iface		Iface;
+typedef	struct	Itype		Itype;
 
 /*
  * per cpu declaration
@@ -105,6 +107,11 @@
 	int32	len;
 	byte	str[1];
 };
+struct Iface
+{
+	Itype *type;
+	void *data[1];	// could make bigger later
+};
 
 struct	Array
 {				// must not move anything
diff --git a/test/bigalg.go b/test/bigalg.go
index 0f92f66..748ef85 100644
--- a/test/bigalg.go
+++ b/test/bigalg.go
@@ -32,15 +32,16 @@
 	if a == nil || nil == a {
 		println("fail3:", a, "== nil");
 	}
-	if a == NIL || NIL == a {
-		println("fail4:", a, "==", NIL);
+}
+
+func SameArray(a, b []int) bool {
+	if len(a) != len(b) || cap(a) != cap(b) {
+		return false;
 	}
-	if a != a {
-		println("fail5:", a, "!=", a);
+	if len(a) > 0 && &a[0] != &b[0] {
+		return false;
 	}
-	if a1 != a {
-		println("fail6:", a1, "!=", a);
-	}
+	return true;
 }
 
 var t = T{1.5, 123, "hello", 255}
@@ -56,7 +57,7 @@
 
 	ma[1] = a;
 	a1 := ma[1];
-	if a1 != a {
+	if !SameArray(a, a1) {
 		println("fail: map val array", a, a1);
 	}
 }
@@ -93,18 +94,49 @@
 
 	t1 := <-ct;
 	if t1.a != t.a || t1.b != t.b || t1.c != t.c || t1.d != t.d {
-		println("fail: chan struct", t1.a, t1.b, t1.c, t1.d);
+		println("fail: map val struct", t1.a, t1.b, t1.c, t1.d);
 	}
 
 	a1 := <-ca;
-	if a1 != a {
-		println("fail: chan array", a, a1);
+	if !SameArray(a, a1) {
+		println("fail: map val array", a, a1);
 	}
 }
 
+type E struct { }
+var e E
+
+func interfacetest() {
+	var i interface{};
+
+	i = a;
+	a1 := i.([]int);
+	if !SameArray(a, a1) {
+		println("interface <-> []int", a, a1);
+	}
+	pa := new(*[]int);
+	*pa = a;
+	i = pa;
+	a1 = *i.(*[]int);
+	if !SameArray(a, a1) {
+		println("interface <-> *[]int", a, a1);
+	}
+
+	i = t;
+	t1 := i.(T);
+	if t1.a != t.a || t1.b != t.b || t1.c != t.c || t1.d != t.d {
+		println("interface <-> struct", t1.a, t1.b, t1.c, t1.d);
+	}
+
+	i = e;
+	e1 := i.(E);
+	// nothing to check; just verify it doesn't crash
+}
+
 func main() {
 	arraycmptest();
 	maptest();
 	maptest2();
 	chantest();
+	interfacetest();
 }
diff --git a/test/mallocrep1.go b/test/mallocrep1.go
index 50f557b..ae54ab8 100644
--- a/test/mallocrep1.go
+++ b/test/mallocrep1.go
@@ -22,7 +22,7 @@
 var longtest bool;
 var longtest_flag = flag.Bool("l", false, &longtest, "long test");
 
-var b *[]*byte;
+var b []*byte;
 var stats = malloc.GetStats();
 
 func OkAmount(size, n uint64) bool {