When the first result of a type assertion is blank, the compiler would still copy out a potentially large non-interface type.
Fixes #1021.
R=golang-dev, bradfitz, rsc
CC=golang-dev
https://golang.org/cl/
6812079
"func @\"\".assertI2I2(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any, @\"\".ok bool)\n"
"func @\"\".assertI2T(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any)\n"
"func @\"\".assertI2T2(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any, @\"\".ok bool)\n"
+ "func @\"\".assertI2TOK(@\"\".typ *byte, @\"\".iface any) (@\"\".ok bool)\n"
+ "func @\"\".assertE2TOK(@\"\".typ *byte, @\"\".iface any) (@\"\".ok bool)\n"
"func @\"\".ifaceeq(@\"\".i1 any, @\"\".i2 any) (@\"\".ret bool)\n"
"func @\"\".efaceeq(@\"\".i1 any, @\"\".i2 any) (@\"\".ret bool)\n"
"func @\"\".ifacethash(@\"\".i1 any) (@\"\".ret uint32)\n"
func assertI2I2(typ *byte, iface any) (ret any, ok bool)
func assertI2T(typ *byte, iface any) (ret any)
func assertI2T2(typ *byte, iface any) (ret any, ok bool)
+func assertI2TOK(typ *byte, iface any) (ok bool)
+func assertE2TOK(typ *byte, iface any) (ok bool)
func ifaceeq(i1 any, i2 any) (ret bool)
func efaceeq(i1 any, i2 any) (ret bool)
n->ninit = nil;
r = n->rlist->n;
walkexprlistsafe(n->list, init);
+ if(isblank(n->list->n) && !isinter(r->type)) {
+ strcpy(buf, "assert");
+ p = buf+strlen(buf);
+ if(isnilinter(r->left->type))
+ *p++ = 'E';
+ else
+ *p++ = 'I';
+ *p++ = '2';
+ *p++ = 'T';
+ *p++ = 'O';
+ *p++ = 'K';
+ *p = '\0';
+
+ fn = syslook(buf, 1);
+ ll = list1(typename(r->type));
+ ll = list(ll, r->left);
+ argtype(fn, r->left->type);
+ n1 = nod(OCALL, fn, N);
+ n1->list = ll;
+ n = nod(OAS, n->list->next->n, n1);
+ typecheck(&n, Etop);
+ walkexpr(&n, init);
+ goto ret;
+ }
+
r->op = ODOTTYPE2;
walkexpr(&r, init);
ll = ascompatet(n->op, n->list, &r->type, 0, init);
copyout(t, &i.data, ret);
}
+void
+runtime·assertI2TOK(Type *t, Iface i, bool ok)
+{
+ ok = i.tab!=nil && i.tab->type==t;
+ FLUSH(&ok);
+}
+
static void assertE2Tret(Type *t, Eface e, byte *ret);
// func ifaceE2T(typ *byte, iface any) (ret any)
copyout(t, &e.data, ret);
}
+void
+runtime·assertE2TOK(Type *t, Eface e, bool ok)
+{
+ ok = t==e.type;
+ FLUSH(&ok);
+}
+
// func convI2E(elem any) (ret any)
void
runtime·convI2E(Iface i, Eface ret)