Commit 565b5dc0 authored by Russ Cox's avatar Russ Cox

gc: new typechecking rules

* Code for assignment, conversions now mirrors spec.
* Changed some snprint -> smprint.
* Renamed runtime functions to separate
  interface conversions from type assertions:
  convT2I, assertI2T, etc.
* Correct checking of \U sequences.

Fixes #840.
Fixes #830.
Fixes #778.

R=ken2
CC=golang-dev
https://golang.org/cl/1303042
parent 6aaef044
......@@ -431,7 +431,7 @@ agen(Node *n, Node *res)
if(n == N || n->type == T)
return;
if(!isptr[res->type->etype])
if(!isptr[res->type->etype] && res->type->etype != TUINTPTR)
fatal("agen: not tptr: %T", res->type);
while(n->op == OCONVNOP)
......
......@@ -133,25 +133,22 @@ bitno(int32 b)
int
Qconv(Fmt *fp)
{
char str[STRINGSZ], ss[STRINGSZ], *s;
Bits bits;
int i;
int i, first;
str[0] = 0;
first = 1;
bits = va_arg(fp->args, Bits);
while(bany(&bits)) {
i = bnum(bits);
if(str[0])
strcat(str, " ");
if(var[i].sym == S) {
sprint(ss, "$%lld", var[i].offset);
s = ss;
} else
s = var[i].sym->name;
if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
break;
strcat(str, s);
if(first)
first = 0;
else
fmtprint(fp, " ");
if(var[i].sym == S)
fmtprint(fp, "$%lld", var[i].offset);
else
fmtprint(fp, var[i].sym->name);
bits.b[i/32] &= ~(1L << (i%32));
}
return fmtstrcpy(fp, str);
return 0;
}
......@@ -33,18 +33,22 @@ char *runtimeimport =
"func \"\".stringiter (? string, ? int) int\n"
"func \"\".stringiter2 (? string, ? int) (retk int, retv int)\n"
"func \"\".slicecopy (to any, fr any, wid uint32) int\n"
"func \"\".ifaceI2E (iface any) any\n"
"func \"\".ifaceE2I (typ *uint8, iface any) any\n"
"func \"\".ifaceT2E (typ *uint8, elem any) any\n"
"func \"\".ifaceE2T (typ *uint8, elem any) any\n"
"func \"\".ifaceE2I2 (typ *uint8, iface any) (ret any, ok bool)\n"
"func \"\".ifaceE2T2 (typ *uint8, elem any) (ret any, ok bool)\n"
"func \"\".ifaceT2I (typ1 *uint8, typ2 *uint8, elem any) any\n"
"func \"\".ifaceI2T (typ *uint8, iface any) any\n"
"func \"\".ifaceI2T2 (typ *uint8, iface any) (ret any, ok bool)\n"
"func \"\".ifaceI2I (typ *uint8, iface any) any\n"
"func \"\".ifaceI2Ix (typ *uint8, iface any) any\n"
"func \"\".ifaceI2I2 (typ *uint8, iface any) (ret any, ok bool)\n"
"func \"\".convI2E (elem any) any\n"
"func \"\".convI2I (typ *uint8, elem any) any\n"
"func \"\".convT2E (typ *uint8, elem any) any\n"
"func \"\".convT2I (typ *uint8, typ2 *uint8, elem any) any\n"
"func \"\".assertE2E (typ *uint8, iface any) any\n"
"func \"\".assertE2E2 (typ *uint8, iface any) (ret any, ok bool)\n"
"func \"\".assertE2I (typ *uint8, iface any) any\n"
"func \"\".assertE2I2 (typ *uint8, iface any) (ret any, ok bool)\n"
"func \"\".assertE2T (typ *uint8, iface any) any\n"
"func \"\".assertE2T2 (typ *uint8, iface any) (ret any, ok bool)\n"
"func \"\".assertI2E (typ *uint8, iface any) any\n"
"func \"\".assertI2E2 (typ *uint8, iface any) (ret any, ok bool)\n"
"func \"\".assertI2I (typ *uint8, iface any) any\n"
"func \"\".assertI2I2 (typ *uint8, iface any) (ret any, ok bool)\n"
"func \"\".assertI2T (typ *uint8, iface any) any\n"
"func \"\".assertI2T2 (typ *uint8, iface any) (ret any, ok bool)\n"
"func \"\".ifaceeq (i1 any, i2 any) bool\n"
"func \"\".efaceeq (i1 any, i2 any) bool\n"
"func \"\".ifacethash (i1 any) uint32\n"
......
......@@ -119,6 +119,7 @@ walkclosure(Node *func, NodeList **init)
Node *xtype, *v, *addr, *xfunc, *call, *clos;
NodeList *l, *in;
static int closgen;
char *p;
/*
* wrap body in external function
......@@ -134,8 +135,9 @@ walkclosure(Node *func, NodeList **init)
if(v->op == 0)
continue;
addr = nod(ONAME, N, N);
snprint(namebuf, sizeof namebuf, "&%s", v->sym->name);
addr->sym = lookup(namebuf);
p = smprint("&%s", v->sym->name);
addr->sym = lookup(p);
free(p);
addr->ntype = nod(OIND, typenod(v->type), N);
addr->class = PPARAM;
addr->addable = 1;
......
......@@ -93,8 +93,11 @@ convlit1(Node **np, Type *t, int explicit)
return;
case OLITERAL:
// target is invalid type for a constant? leave alone.
if(!okforconst[t->etype] && n->type->etype != TNIL)
if(!okforconst[t->etype] && n->type->etype != TNIL) {
defaultlit(&n, T);
*np = n;
return;
}
break;
case OLSH:
case ORSH:
......@@ -109,10 +112,8 @@ convlit1(Node **np, Type *t, int explicit)
}
// avoided repeated calculations, errors
if(cvttype(n->type, t) == 1) {
n->type = t;
if(eqtype(n->type, t))
return;
}
ct = consttype(n);
if(ct < 0)
......@@ -968,6 +969,8 @@ defaultlit(Node **np, Type *t)
break;
case CTBOOL:
n->type = types[TBOOL];
if(t != T && t->etype == TBOOL)
n->type = t;
break;
case CTINT:
n->type = types[TINT];
......
......@@ -281,6 +281,7 @@ updatetype(Type *n, Type *t)
local = n->local;
vargen = n->vargen;
*n = *t;
n->orig = t->orig;
n->sym = s;
n->local = local;
n->siggen = 0;
......@@ -759,7 +760,7 @@ typedcl2(Type *pt, Type *t)
if(pt->etype == TFORW)
goto ok;
if(!cvttype(pt, t))
if(!eqtype(pt->orig, t))
yyerror("inconsistent definition for type %S during import\n\t%lT\n\t%lT", pt->sym, pt, t);
return;
......@@ -1154,7 +1155,7 @@ Sym*
methodsym(Sym *nsym, Type *t0)
{
Sym *s;
char buf[NSYMB];
char *p;
Type *t;
t = t0;
......@@ -1177,8 +1178,10 @@ methodsym(Sym *nsym, Type *t0)
if(t != t0 && t0->sym)
t0 = ptrto(t);
snprint(buf, sizeof(buf), "%#hT·%s", t0, nsym->name);
return pkglookup(buf, s->pkg);
p = smprint("%#hT·%s", t0, nsym->name);
s = pkglookup(p, s->pkg);
free(p);
return s;
bad:
yyerror("illegal receiver type: %T", t0);
......@@ -1200,7 +1203,7 @@ Node*
methodname1(Node *n, Node *t)
{
char *star;
char buf[NSYMB];
char *p;
star = "";
if(t->op == OIND) {
......@@ -1209,8 +1212,10 @@ methodname1(Node *n, Node *t)
}
if(t->sym == S || isblank(n))
return newname(n->sym);
snprint(buf, sizeof(buf), "%s%S·%S", star, t->sym, n->sym);
return newname(pkglookup(buf, t->sym->pkg));
p = smprint("%s%S·%S", star, t->sym, n->sym);
n = newname(pkglookup(p, t->sym->pkg));
free(p);
return n;
}
/*
......
......@@ -182,10 +182,22 @@ dumpexporttype(Sym *s)
Bprint(bout, "type %#T %l#T\n", t, t);
}
static int
methcmp(const void *va, const void *vb)
{
Type *a, *b;
a = *(Type**)va;
b = *(Type**)vb;
return strcmp(a->sym->name, b->sym->name);
}
void
dumpsym(Sym *s)
{
Type *f, *t;
Type **m;
int i, n;
if(s->flags & SymExported)
return;
......@@ -207,14 +219,23 @@ dumpsym(Sym *s)
break;
case OTYPE:
t = s->def->type;
// TODO(rsc): sort methods by name
for(f=t->method; f!=T; f=f->down)
n = 0;
for(f=t->method; f!=T; f=f->down) {
dumpprereq(f);
n++;
}
m = mal(n*sizeof m[0]);
i = 0;
for(f=t->method; f!=T; f=f->down)
m[i++] = f;
qsort(m, n, sizeof m[0], methcmp);
dumpexporttype(s);
for(f=t->method; f!=T; f=f->down)
for(i=0; i<n; i++) {
f = m[i];
Bprint(bout, "\tfunc (%#T) %hS %#hhT\n",
f->type->type->type, f->sym, f->type);
}
break;
case ONAME:
dumpexportvar(s);
......@@ -357,7 +378,7 @@ importvar(Sym *s, Type *t, int ctxt)
importsym(s, ONAME);
if(s->def != N && s->def->op == ONAME) {
if(cvttype(t, s->def->type))
if(eqtype(t, s->def->type))
return;
yyerror("inconsistent definition for var %S during import\n\t%T\n\t%T",
s, s->def->type, t);
......
......@@ -158,6 +158,7 @@ struct Type
uchar isddd; // TFIELD is ... argument
Node* nod; // canonical OTYPE node
Type* orig; // original type (type literal or predefined type)
int lineno;
// TFUNCT
......@@ -361,11 +362,12 @@ enum
OCLOSURE,
OCMPIFACE, OCMPSTR,
OCOMPLIT, OMAPLIT, OSTRUCTLIT, OARRAYLIT,
OCONV, OCONVNOP, OCONVIFACE, OCONVSLICE,
OCONV, OCONVIFACE, OCONVNOP, OCONVSLICE,
OCOPY,
ODCL, ODCLFUNC, ODCLFIELD, ODCLCONST, ODCLTYPE,
ODOT, ODOTPTR, ODOTMETH, ODOTINTER, OXDOT,
ODOTTYPE,
ODOTTYPE2,
OEQ, ONE, OLT, OLE, OGE, OGT,
OIND,
OINDEX, OINDEXSTR, OINDEXMAP,
......@@ -904,26 +906,21 @@ NodeList* list(NodeList*, Node*);
NodeList* concat(NodeList*, NodeList*);
int count(NodeList*);
Node* liststmt(NodeList*);
Type** getthis(Type*);
Type** getoutarg(Type*);
Type** getinarg(Type*);
Type* getthisx(Type*);
Type* getoutargx(Type*);
Type* getinargx(Type*);
Type* structfirst(Iter*, Type**);
Type* structnext(Iter*);
Type* funcfirst(Iter*, Type*);
Type* funcnext(Iter*);
int brcom(int);
int brrev(int);
void setmaxarg(Type*);
int dotoffset(Node*, int*, Node**);
void tempname(Node*, Type*);
int Econv(Fmt*);
int Jconv(Fmt*);
int Lconv(Fmt*);
......@@ -934,23 +931,22 @@ int Nconv(Fmt*);
void exprfmt(Fmt*, Node*, int);
int Wconv(Fmt*);
int Zconv(Fmt*);
int lookdot0(Sym*, Type*, Type**);
int adddot1(Sym*, Type*, int, Type**);
Node* adddot(Node*);
void expandmeth(Sym*, Type*);
void genwrapper(Type*, Type*, Sym*);
int simsimtype(Type*);
int powtwo(Node*);
Type* tounsigned(Type*);
void smagic(Magic*);
void umagic(Magic*);
void redeclare(Sym*, char*);
Sym* ngotype(Node*);
int convertop(Type*, Type*, char**);
int assignop(Type*, Type*, char**);
Node* assignconv(Node*, Type*, char*);
int implements(Type*, Type*, Type**, Type**);
/*
* dcl.c
......@@ -1053,7 +1049,6 @@ void walkstmt(Node**);
void walkstmtlist(NodeList*);
void walkexprlist(NodeList*, NodeList**);
void walkconv(Node**, NodeList**);
void walkdottype(Node*, NodeList**);
void walkas(Node*);
void walkswitch(Node*);
void walkrange(Node*);
......@@ -1071,8 +1066,6 @@ Type* fixchan(Type*);
Node* ifacecvt(Type*, Node*, int, NodeList**);
int ifaceas(Type*, Type*, int);
int ifaceas1(Type*, Type*, int);
void ifacecheck(Type*, Type*, int, int);
void runifacechecks(void);
Node* convas(Node*, NodeList**);
Node* colas(NodeList*, NodeList*);
void colasdefn(NodeList*, Node*);
......@@ -1090,10 +1083,10 @@ void typecheckswitch(Node*);
void typecheckselect(Node*);
void typecheckrange(Node*);
Node* typecheckconv(Node*, Node*, Type*, int, char*);
int checkconv(Type*, Type*, int, int*, int*, char*);
Node* typecheck(Node**, int);
int islvalue(Node*);
void queuemethod(Node*);
int exportassignok(Type*, char*);
/*
* const.c
......@@ -1242,4 +1235,4 @@ int duintptr(Sym *s, int off, uint64 v);
int duintxx(Sym *s, int off, uint64 v, int wid);
void genembedtramp(Type*, Type*, Sym*);
int gen_as_init(Node*);
int anyregalloc();
int anyregalloc(void);
......@@ -148,8 +148,21 @@ main(int argc, char *argv[])
typecheckok = 1;
if(debug['f'])
frame(1);
// Process top-level declarations in three phases.
// Phase 1: const, type, and names and types of funcs.
// This will gather all the information about types
// and methods but doesn't depend on any of it.
// Phase 2: Variable assignments.
// To check interface assignments, depends on phase 1.
// Phase 3: Function bodies.
defercheckwidth();
typechecklist(xtop, Etop);
for(l=xtop; l; l=l->next)
if(l->n->op != ODCL && l->n->op != OAS)
typecheck(&l->n, Etop);
for(l=xtop; l; l=l->next)
if(l->n->op == ODCL || l->n->op == OAS)
typecheck(&l->n, Etop);
resumecheckwidth();
for(l=xtop; l; l=l->next)
if(l->n->op == ODCLFUNC)
......@@ -164,7 +177,6 @@ main(int argc, char *argv[])
}
dclchecks();
runifacechecks();
if(nerrors)
errorexit();
......@@ -1155,7 +1167,7 @@ loop:
int
escchar(int e, int *escflg, vlong *val)
{
int i, c;
int i, u, c;
vlong l;
*escflg = 0;
......@@ -1177,6 +1189,7 @@ escchar(int e, int *escflg, vlong *val)
return 0;
}
u = 0;
c = getr();
switch(c) {
case 'x':
......@@ -1186,10 +1199,12 @@ escchar(int e, int *escflg, vlong *val)
case 'u':
i = 4;
u = 1;
goto hex;
case 'U':
i = 8;
u = 1;
goto hex;
case '0':
......@@ -1239,6 +1254,10 @@ hex:
ungetc(c);
break;
}
if(u && l > Runemax) {
yyerror("invalid Unicode code point in escape sequence: %#llx", l);
l = Runeerror;
}
*val = l;
return 0;
......@@ -1388,7 +1407,6 @@ lexinit(void)
// (the type of x in var x string or var x = "hello").
// this is the ideal form
// (the type of x in const x = "hello").
// TODO(rsc): this may need some more thought.
idealstring = typ(TSTRING);
idealbool = typ(TBOOL);
......
......@@ -39,6 +39,8 @@ exprfmt(Fmt *f, Node *n, int prec)
case ODOTPTR:
case ODOTINTER:
case ODOTMETH:
case ODOTTYPE:
case ODOTTYPE2:
case OARRAYBYTESTR:
case OCAP:
case OCLOSE:
......@@ -54,7 +56,6 @@ exprfmt(Fmt *f, Node *n, int prec)
case OCONV:
case OCONVNOP:
case OCONVSLICE:
case OCONVIFACE:
case OMAKESLICE:
case ORUNESTR:
case OADDR:
......@@ -64,6 +65,7 @@ exprfmt(Fmt *f, Node *n, int prec)
case ONOT:
case OPLUS:
case ORECV:
case OCONVIFACE:
nprec = 7;
break;
......@@ -277,6 +279,7 @@ exprfmt(Fmt *f, Node *n, int prec)
break;
case ODOTTYPE:
case ODOTTYPE2:
exprfmt(f, n->left, 7);
fmtprint(f, ".(");
if(n->right != N)
......@@ -336,9 +339,9 @@ exprfmt(Fmt *f, Node *n, int prec)
break;
case OCONV:
case OCONVIFACE:
case OCONVNOP:
case OCONVSLICE:
case OCONVIFACE:
case OARRAYBYTESTR:
case ORUNESTR:
if(n->type == T || n->type->sym == S)
......
......@@ -11,7 +11,7 @@
void
typecheckrange(Node *n)
{
int op, et;
char *why;
Type *t, *t1, *t2;
Node *v1, *v2;
NodeList *ll;
......@@ -66,13 +66,13 @@ typecheckrange(Node *n)
if(v1->defn == n)
v1->type = t1;
else if(v1->type != T && checkconv(t1, v1->type, 0, &op, &et, "range") < 0)
yyerror("cannot assign type %T to %+N", t1, v1);
else if(v1->type != T && assignop(t1, v1->type, &why) == 0)
yyerror("cannot assign type %T to %+N in range%s", t1, v1, why);
if(v2) {
if(v2->defn == n)
v2->type = t2;
else if(v2->type != T && checkconv(t2, v2->type, 0, &op, &et, "range") < 0)
yyerror("cannot assign type %T to %+N", t1, v1);
else if(v2->type != T && assignop(t2, v2->type, &why) == 0)
yyerror("cannot assign type %T to %+N in range%s", t2, v2, why);
}
out:
......
......@@ -47,18 +47,26 @@ func stringiter(string, int) int
func stringiter2(string, int) (retk int, retv int)
func slicecopy(to any, fr any, wid uint32) int
func ifaceI2E(iface any) (ret any)
func ifaceE2I(typ *byte, iface any) (ret any)
func ifaceT2E(typ *byte, elem any) (ret any)
func ifaceE2T(typ *byte, elem any) (ret any)
func ifaceE2I2(typ *byte, iface any) (ret any, ok bool)
func ifaceE2T2(typ *byte, elem any) (ret any, ok bool)
func ifaceT2I(typ1 *byte, typ2 *byte, elem any) (ret any)
func ifaceI2T(typ *byte, iface any) (ret any)
func ifaceI2T2(typ *byte, iface any) (ret any, ok bool)
func ifaceI2I(typ *byte, iface any) (ret any)
func ifaceI2Ix(typ *byte, iface any) (ret any)
func ifaceI2I2(typ *byte, iface any) (ret any, ok bool)
// interface conversions
func convI2E(elem any) (ret any)
func convI2I(typ *byte, elem any) (ret any)
func convT2E(typ *byte, elem any) (ret any)
func convT2I(typ *byte, typ2 *byte, elem any) (ret any)
// interface type assertions x.(T)
func assertE2E(typ *byte, iface any) (ret any)
func assertE2E2(typ *byte, iface any) (ret any, ok bool)
func assertE2I(typ *byte, iface any) (ret any)
func assertE2I2(typ *byte, iface any) (ret any, ok bool)
func assertE2T(typ *byte, iface any) (ret any)
func assertE2T2(typ *byte, iface any) (ret any, ok bool)
func assertI2E(typ *byte, iface any) (ret any)
func assertI2E2(typ *byte, iface any) (ret any, ok bool)
func assertI2I(typ *byte, iface any) (ret any)
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 ifaceeq(i1 any, i2 any) (ret bool)
func efaceeq(i1 any, i2 any) (ret bool)
func ifacethash(i1 any) (ret uint32)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// Derived from Inferno's libkern/getfcr-amd64.s
// http://code.google.com/p/inferno-os/source/browse/libkern/getfcr-amd64.s
//
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
// Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
// Portions Copyright 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
TEXT ·SetFPControl(SB), 7, $8
// Set new
MOVL p+0(FP), DI
XORL $(0x3F<<7), DI
ANDL $0xFFC0, DI
WAIT
STMXCSR 0(SP)
MOVL 0(SP), AX
ANDL $~0x3F, AX
ORL DI, AX
MOVL AX, 0(SP)
LDMXCSR 0(SP)
RET
TEXT ·GetFPControl(SB), 7, $0
WAIT
STMXCSR 0(SP)
MOVWLZX 0(SP), AX
ANDL $0xFFC0, AX
XORL $(0x3F<<7), AX
MOVL AX, ret+0(FP)
RET
TEXT ·SetFPStatus(SB), $0
MOVL p+0(FP), DI
ANDL $0x3F, DI
WAIT
STMXCSR 0(SP)
MOVL 0(SP), AX
ANDL $~0x3F, AX
ORL DI, AX
MOVL AX, 0(SP)
LDMXCSR 0(SP)
RET
TEXT ·GetFPStatus(SB), $0
WAIT
STMXCSR 0(SP)
MOVL 0(SP), AX
ANDL $0x3F, AX
MOVL AX, ret+0(FP)
RET
......@@ -177,26 +177,26 @@ copyout(Type *t, void **src, void *dst)
algarray[alg].copy(wid, dst, *src);
}
// ifaceT2I(sigi *byte, sigt *byte, elem any) (ret Iface);
// func convT2I(typ *byte, typ2 *byte, elem any) (ret any)
#pragma textflag 7
void
·ifaceT2I(InterfaceType *inter, Type *t, ...)
·convT2I(Type *t, InterfaceType *inter, ...)
{
byte *elem;
Iface *ret;
int32 wid;
elem = (byte*)(&t+1);
elem = (byte*)(&inter+1);
wid = t->size;
ret = (Iface*)(elem + rnd(wid, Structrnd));
ret->tab = itab(inter, t, 0);
copyin(t, elem, &ret->data);
}
// ifaceT2E(sigt *byte, elem any) (ret Eface);
// func convT2E(typ *byte, elem any) (ret any)
#pragma textflag 7
void
·ifaceT2E(Type *t, ...)
·convT2E(Type *t, ...)
{
byte *elem;
Eface *ret;
......@@ -205,15 +205,14 @@ void
elem = (byte*)(&t+1);
wid = t->size;
ret = (Eface*)(elem + rnd(wid, Structrnd));
ret->type = t;
copyin(t, elem, &ret->data);
}
// ifaceI2T(sigt *byte, iface any) (ret any);
// func ifaceI2T(typ *byte, iface any) (ret any)
#pragma textflag 7
void
·ifaceI2T(Type *t, Iface i, ...)
·assertI2T(Type *t, Iface i, ...)
{
Itab *tab;
byte *ret;
......@@ -236,10 +235,10 @@ void
copyout(t, &i.data, ret);
}
// ifaceI2T2(sigt *byte, i Iface) (ret any, ok bool);
// func ifaceI2T2(typ *byte, iface any) (ret any, ok bool)
#pragma textflag 7
void
·ifaceI2T2(Type *t, Iface i, ...)
·assertI2T2(Type *t, Iface i, ...)
{
byte *ret;
bool *ok;
......@@ -259,10 +258,10 @@ void
copyout(t, &i.data, ret);
}
// ifaceE2T(sigt *byte, e Eface) (ret any);
// func ifaceE2T(typ *byte, iface any) (ret any)
#pragma textflag 7
void
·ifaceE2T(Type *t, Eface e, ...)
·assertE2T(Type *t, Eface e, ...)
{
byte *ret;
Eface err;
......@@ -284,10 +283,10 @@ void
copyout(t, &e.data, ret);
}
// ifaceE2T2(sigt *byte, iface any) (ret any, ok bool);
// func ifaceE2T2(sigt *byte, iface any) (ret any, ok bool);
#pragma textflag 7
void
·ifaceE2T2(Type *t, Eface e, ...)
·assertE2T2(Type *t, Eface e, ...)
{
byte *ret;
bool *ok;
......@@ -307,50 +306,82 @@ void
copyout(t, &e.data, ret);
}
// ifaceI2E(sigi *byte, iface any) (ret any);
// TODO(rsc): Move to back end, throw away function.
// func convI2E(elem any) (ret any)
#pragma textflag 7
void
·ifaceI2E(Iface i, Eface ret)
·convI2E(Iface i, Eface ret)
{
Itab *tab;
ret.data = i.data;
tab = i.tab;
if(tab == nil)
if((tab = i.tab) == nil)
ret.type = nil;
else
ret.type = tab->type;
FLUSH(&ret);
}
// ifaceI2I(sigi *byte, iface any) (ret any);
// called only for implicit (no type assertion) conversions.
// converting nil is okay.
// func ifaceI2E(typ *byte, iface any) (ret any)
#pragma textflag 7
void
·ifaceI2I(InterfaceType *inter, Iface i, Iface ret)
·assertI2E(InterfaceType* inter, Iface i, Eface ret)
{
Itab *tab;
Eface err;
tab = i.tab;
if(tab == nil) {
// If incoming interface is uninitialized (zeroed)
// make the outgoing interface zeroed as well.
ret.tab = nil;
ret.data = nil;
// explicit conversions require non-nil interface value.
·newTypeAssertionError(nil, nil, inter,
nil, nil, inter->string,
nil, &err);
·panic(err);
}
ret.data = i.data;
ret.type = tab->type;
FLUSH(&ret);
}
// func ifaceI2E2(typ *byte, iface any) (ret any, ok bool)
#pragma textflag 7
void
·assertI2E2(InterfaceType* inter, Iface i, Eface ret, bool ok)
{
Itab *tab;
USED(inter);
tab = i.tab;
if(tab == nil) {
ret.type = nil;
ok = 0;
} else {
ret = i;
if(tab->inter != inter)
ret.tab = itab(inter, tab->type, 0);
ret.type = tab->type;
ok = 1;
}
ret.data = i.data;
FLUSH(&ret);
FLUSH(&ok);
}
// func convI2I(typ *byte, elem any) (ret any)
#pragma textflag 7
void
·convI2I(InterfaceType* inter, Iface i, Iface ret)
{
Itab *tab;
ret.data = i.data;
if((tab = i.tab) == nil)
ret.tab = nil;
else if(tab->inter == inter)
ret.tab = tab;
else
ret.tab = itab(inter, tab->type, 0);
FLUSH(&ret);
}
// ifaceI2Ix(sigi *byte, iface any) (ret any);
// called only for explicit conversions (with type assertion).
// converting nil is not okay.
void
·ifaceI2Ix(InterfaceType *inter, Iface i, Iface ret)
ifaceI2I(InterfaceType *inter, Iface i, Iface *ret)
{
Itab *tab;
Eface err;
......@@ -362,45 +393,40 @@ void
nil, nil, inter->string,
nil, &err);
·panic(err);
} else {
ret = i;
if(tab->inter != inter)
ret.tab = itab(inter, tab->type, 0);
}
ret->data = i.data;
ret->tab = itab(inter, tab->type, 0);
}
FLUSH(&ret);
// func ifaceI2I(sigi *byte, iface any) (ret any)
#pragma textflag 7
void
·assertI2I(InterfaceType* inter, Iface i, Iface ret)
{
ifaceI2I(inter, i, &ret);
}
// ifaceI2I2(sigi *byte, iface any) (ret any, ok bool);
// func ifaceI2I2(sigi *byte, iface any) (ret any, ok bool)
#pragma textflag 7
void
·ifaceI2I2(InterfaceType *inter, Iface i, Iface ret, bool ok)
·assertI2I2(InterfaceType *inter, Iface i, Iface ret, bool ok)
{
Itab *tab;
tab = i.tab;
if(tab == nil) {
// If incoming interface is nil, the conversion fails.
ret.tab = nil;
ret.data = nil;
ok = false;
if(tab != nil && (tab->inter == inter || (tab = itab(inter, tab->type, 1)) != nil)) {
ret.data = i.data;
ret.tab = tab;
ok = 1;
} else {
ret = i;
ok = true;
if(tab->inter != inter) {
ret.tab = itab(inter, tab->type, 1);
if(ret.tab == nil) {
ret.data = nil;
ok = false;
}
ret.data = 0;
ret.tab = 0;
ok = 0;
}
}
FLUSH(&ret);
FLUSH(&ok);
}
// ifaceE2I(sigi *byte, iface any) (ret any);
// Called only for explicit conversions (with type assertion).
void
ifaceE2I(InterfaceType *inter, Eface e, Iface *ret)
{
......@@ -414,41 +440,67 @@ ifaceE2I(InterfaceType *inter, Eface e, Iface *ret)
nil, nil, inter->string,
nil, &err);
·panic(err);
} else {
}
ret->data = e.data;
ret->tab = itab(inter, t, 0);
}
}
// ifaceE2I(sigi *byte, iface any) (ret any);
// Called only for explicit conversions (with type assertion).
// func ifaceE2I(sigi *byte, iface any) (ret any)
#pragma textflag 7
void
·ifaceE2I(InterfaceType *inter, Eface e, Iface ret)
·assertE2I(InterfaceType* inter, Eface e, Iface ret)
{
ifaceE2I(inter, e, &ret);
}
// ifaceE2I2(sigi *byte, iface any) (ret any, ok bool);
// ifaceE2I2(sigi *byte, iface any) (ret any, ok bool)
#pragma textflag 7
void
·ifaceE2I2(InterfaceType *inter, Eface e, Iface ret, bool ok)
·assertE2I2(InterfaceType *inter, Eface e, Iface ret, bool ok)
{
Type *t;
t = e.type;
ok = true;
if(t == nil) {
// If incoming interface is nil, the conversion fails.
if(e.type == nil) {
ok = 0;
ret.data = nil;
ret.tab = nil;
ok = false;
} else if((ret.tab = itab(inter, e.type, 1)) == nil) {
ok = 0;
ret.data = nil;
} else {
ok = 1;
ret.data = e.data;
ret.tab = itab(inter, t, 1);
if(ret.tab == nil) {
ret.data = nil;
ok = false;
}
FLUSH(&ret);
FLUSH(&ok);
}
// func ifaceE2E(typ *byte, iface any) (ret any)
#pragma textflag 7
void
·assertE2E(InterfaceType* inter, Eface e, Eface ret)
{
Type *t;
Eface err;
t = e.type;
if(t == nil) {
// explicit conversions require non-nil interface value.
·newTypeAssertionError(nil, nil, inter,
nil, nil, inter->string,
nil, &err);
·panic(err);
}
ret = e;
FLUSH(&ret);
}
// func ifaceE2E2(iface any) (ret any, ok bool)
#pragma textflag 7
void
·assertE2E2(InterfaceType* inter, Eface e, Eface ret, bool ok)
{
USED(inter);
ret = e;
ok = e.type != nil;
FLUSH(&ret);
FLUSH(&ok);
}
......
// errchk $G -e $D/$F.go
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
type (
A [10]int
B []int
C chan int
F func() int
I interface {
m() int
}
M map[int]int
P *int
S struct {
X int
}
A1 [10]int
B1 []int
C1 chan int
F1 func() int
I1 interface {
m() int
}
M1 map[int]int
P1 *int
S1 struct {
X int
}
)
var (
a0 [10]int
b0 []int
c0 chan int
f0 func() int
i0 interface {
m() int
}
m0 map[int]int
p0 *int
s0 struct {
X int
}
a A
b B
c C
f F
i I
m M
p P
s S
a1 A1
b1 B1
c1 C1
f1 F1
i1 I1
m1 M1
p1 P1
s1 S1
pa0 *[10]int
pb0 *[]int
pc0 *chan int
pf0 *func() int
pi0 *interface {
m() int
}
pm0 *map[int]int
pp0 **int
ps0 *struct {
X int
}
pa *A
pb *B
pc *C
pf *F
pi *I
pm *M
pp *P
ps *S
pa1 *A1
pb1 *B1
pc1 *C1
pf1 *F1
pi1 *I1
pm1 *M1
pp1 *P1
ps1 *S1
)
func main() {
a0 = a
a0 = a1
a = a0
a = a1 // ERROR "cannot use"
a1 = a0
a1 = a // ERROR "cannot use"
b0 = b
b0 = b1
b = b0
b = b1 // ERROR "cannot use"
b1 = b0
b1 = b // ERROR "cannot use"
c0 = c
c0 = c1
c = c0
c = c1 // ERROR "cannot use"
c1 = c0
c1 = c // ERROR "cannot use"
f0 = f
f0 = f1
f = f0
f = f1 // ERROR "cannot use"
f1 = f0
f1 = f // ERROR "cannot use"
i0 = i
i0 = i1
i = i0
i = i1
i1 = i0
i1 = i
m0 = m
m0 = m1
m = m0
m = m1 // ERROR "cannot use"
m1 = m0
m1 = m // ERROR "cannot use"
p0 = p
p0 = p1
p = p0
p = p1 // ERROR "cannot use"
p1 = p0
p1 = p // ERROR "cannot use"
s0 = s
s0 = s1
s = s0
s = s1 // ERROR "cannot use"
s1 = s0
s1 = s // ERROR "cannot use"
pa0 = pa // ERROR "cannot use"
pa0 = pa1 // ERROR "cannot use"
pa = pa0 // ERROR "cannot use"
pa = pa1 // ERROR "cannot use"
pa1 = pa0 // ERROR "cannot use"
pa1 = pa // ERROR "cannot use"
pb0 = pb // ERROR "cannot use"
pb0 = pb1 // ERROR "cannot use"
pb = pb0 // ERROR "cannot use"
pb = pb1 // ERROR "cannot use"
pb1 = pb0 // ERROR "cannot use"
pb1 = pb // ERROR "cannot use"
pc0 = pc // ERROR "cannot use"
pc0 = pc1 // ERROR "cannot use"
pc = pc0 // ERROR "cannot use"
pc = pc1 // ERROR "cannot use"
pc1 = pc0 // ERROR "cannot use"
pc1 = pc // ERROR "cannot use"
pf0 = pf // ERROR "cannot use"
pf0 = pf1 // ERROR "cannot use"
pf = pf0 // ERROR "cannot use"
pf = pf1 // ERROR "cannot use"
pf1 = pf0 // ERROR "cannot use"
pf1 = pf // ERROR "cannot use"
pi0 = pi // ERROR "cannot use"
pi0 = pi1 // ERROR "cannot use"
pi = pi0 // ERROR "cannot use"
pi = pi1 // ERROR "cannot use"
pi1 = pi0 // ERROR "cannot use"
pi1 = pi // ERROR "cannot use"
pm0 = pm // ERROR "cannot use"
pm0 = pm1 // ERROR "cannot use"
pm = pm0 // ERROR "cannot use"
pm = pm1 // ERROR "cannot use"
pm1 = pm0 // ERROR "cannot use"
pm1 = pm // ERROR "cannot use"
pp0 = pp // ERROR "cannot use"
pp0 = pp1 // ERROR "cannot use"
pp = pp0 // ERROR "cannot use"
pp = pp1 // ERROR "cannot use"
pp1 = pp0 // ERROR "cannot use"
pp1 = pp // ERROR "cannot use"
ps0 = ps // ERROR "cannot use"
ps0 = ps1 // ERROR "cannot use"
ps = ps0 // ERROR "cannot use"
ps = ps1 // ERROR "cannot use"
ps1 = ps0 // ERROR "cannot use"
ps1 = ps // ERROR "cannot use"
a0 = [10]int(a)
a0 = [10]int(a1)
a = A(a0)
a = A(a1)
a1 = A1(a0)
a1 = A1(a)
b0 = []int(b)
b0 = []int(b1)
b = B(b0)
b = B(b1)
b1 = B1(b0)
b1 = B1(b)
c0 = chan int(c)
c0 = chan int(c1)
c = C(c0)
c = C(c1)
c1 = C1(c0)
c1 = C1(c)
f0 = func() int(f)
f0 = func() int(f1)
f = F(f0)
f = F(f1)
f1 = F1(f0)
f1 = F1(f)
i0 = interface {
m() int
}(i)
i0 = interface {
m() int
}(i1)
i = I(i0)
i = I(i1)
i1 = I1(i0)
i1 = I1(i)
m0 = map[int]int(m)
m0 = map[int]int(m1)
m = M(m0)
m = M(m1)
m1 = M1(m0)
m1 = M1(m)
p0 = (*int)(p)
p0 = (*int)(p1)
p = P(p0)
p = P(p1)
p1 = P1(p0)
p1 = P1(p)
s0 = struct {
X int
}(s)
s0 = struct {
X int
}(s1)
s = S(s0)
s = S(s1)
s1 = S1(s0)
s1 = S1(s)
pa0 = (*[10]int)(pa)
pa0 = (*[10]int)(pa1)
pa = (*A)(pa0)
pa = (*A)(pa1)
pa1 = (*A1)(pa0)
pa1 = (*A1)(pa)
pb0 = (*[]int)(pb)
pb0 = (*[]int)(pb1)
pb = (*B)(pb0)
pb = (*B)(pb1)
pb1 = (*B1)(pb0)
pb1 = (*B1)(pb)
pc0 = (*chan int)(pc)
pc0 = (*chan int)(pc1)
pc = (*C)(pc0)
pc = (*C)(pc1)
pc1 = (*C1)(pc0)
pc1 = (*C1)(pc)
pf0 = (*func() int)(pf)
pf0 = (*func() int)(pf1)
pf = (*F)(pf0)
pf = (*F)(pf1)
pf1 = (*F1)(pf0)
pf1 = (*F1)(pf)
pi0 = (*interface {
m() int
})(pi)
pi0 = (*interface {
m() int
})(pi1)
pi = (*I)(pi0)
pi = (*I)(pi1)
pi1 = (*I1)(pi0)
pi1 = (*I1)(pi)
pm0 = (*map[int]int)(pm)
pm0 = (*map[int]int)(pm1)
pm = (*M)(pm0)
pm = (*M)(pm1)
pm1 = (*M1)(pm0)
pm1 = (*M1)(pm)
pp0 = (**int)(pp)
pp0 = (**int)(pp1)
pp = (*P)(pp0)
pp = (*P)(pp1)
pp1 = (*P1)(pp0)
pp1 = (*P1)(pp)
ps0 = (*struct {
X int
})(ps)
ps0 = (*struct {
X int
})(ps1)
ps = (*S)(ps0)
ps = (*S)(ps1)
ps1 = (*S1)(ps0)
ps1 = (*S1)(ps)
}
......@@ -18,8 +18,9 @@ var f2 = []int(e)
var g = []int(nil)
type H *[4]int
type H []int
type J []int
var h H
var j1 J = h // ERROR "compat|illegal|cannot|cannot"
var j1 J = h // ERROR "compat|illegal|cannot"
var j2 = J(h)
......@@ -34,14 +34,14 @@ func (t1) M(p1.T) {}
var i0 I0 = t0(0) // ok
var i1 I1 = t1(0) // ok
var i2 I0 = t1(0) // ERROR "is not|incompatible"
var i3 I1 = t0(0) // ERROR "is not|incompatible"
var i2 I0 = t1(0) // ERROR "does not implement|incompatible"
var i3 I1 = t0(0) // ERROR "does not implement|incompatible"
var p0i p0.I = t0(0) // ok
var p1i p1.I = t1(0) // ok
var p0i1 p0.I = t1(0) // ERROR "is not|incompatible"
var p0i2 p1.I = t0(0) // ERROR "is not|incompatible"
var p0i1 p0.I = t1(0) // ERROR "does not implement|incompatible"
var p0i2 p1.I = t0(0) // ERROR "does not implement|incompatible"
func main() {
// check that cannot assign one to the other,
......@@ -52,14 +52,14 @@ func main() {
v0 = p0.T(v1)
v1 = p1.T(v0)
i0 = i1 // ERROR "need type assertion|incompatible"
i1 = i0 // ERROR "need type assertion|incompatible"
p0i = i1 // ERROR "need type assertion|incompatible"
p1i = i0 // ERROR "need type assertion|incompatible"
i0 = p1i // ERROR "need type assertion|incompatible"
i1 = p0i // ERROR "need type assertion|incompatible"
p0i = p1i // ERROR "need type assertion|incompatible"
p1i = p0i // ERROR "need type assertion|incompatible"
i0 = i1 // ERROR "cannot use|incompatible"
i1 = i0 // ERROR "cannot use|incompatible"
p0i = i1 // ERROR "cannot use|incompatible"
p1i = i0 // ERROR "cannot use|incompatible"
i0 = p1i // ERROR "cannot use|incompatible"
i1 = p0i // ERROR "cannot use|incompatible"
p0i = p1i // ERROR "cannot use|incompatible"
p1i = p0i // ERROR "cannot use|incompatible"
i0 = p0i
p0i = i0
......
......@@ -16,6 +16,6 @@ type I2 interface {
}
var i1 I1 = i2 // ERROR "need type assertion"
var i1 I1 = i2 // ERROR "missing m method|need type assertion"
var i2 I2
var i2a I2 = i1
// $G $D/$F.go && $L $F.go && ./$A.out || echo BUG: bug285
// $G $D/$F.go && $L $F.$A && ./$A.out || echo BUG: bug285
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
......
......@@ -180,58 +180,3 @@ BUG: bug260 failed
=========== bugs/bug274.go
BUG: errchk: command succeeded unexpectedly
=========== bugs/bug284.go
BUG: errchk: bugs/bug284.go:33: missing expected error: 'cannot'
errchk: bugs/bug284.go:36: missing expected error: 'cannot'
errchk: bugs/bug284.go:37: missing expected error: 'cannot'
errchk: bugs/bug284.go:38: missing expected error: 'cannot'
errchk: bugs/bug284.go:56: missing expected error: 'cannot'
errchk: bugs/bug284.go:59: missing expected error: 'cannot'
errchk: bugs/bug284.go:60: missing expected error: 'cannot'
errchk: bugs/bug284.go:61: missing expected error: 'cannot'
errchk: bugs/bug284.go:71: missing expected error: 'cannot'
errchk: bugs/bug284.go:74: missing expected error: 'cannot'
errchk: bugs/bug284.go:75: missing expected error: 'cannot'
errchk: bugs/bug284.go:76: missing expected error: 'cannot'
errchk: bugs/bug284.go:96: missing expected error: 'cannot'
errchk: bugs/bug284.go:99: missing expected error: 'cannot'
errchk: bugs/bug284.go:101: missing expected error: 'cannot'
errchk: bugs/bug284.go:111: missing expected error: 'cannot'
errchk: bugs/bug284.go:114: missing expected error: 'cannot'
errchk: bugs/bug284.go:115: missing expected error: 'cannot'
errchk: bugs/bug284.go:116: missing expected error: 'cannot'
errchk: bugs/bug284.go:134: missing expected error: 'cannot|need type assertion'
errchk: bugs/bug284.go:137: missing expected error: 'cannot|need type assertion'
errchk: bugs/bug284.go:138: missing expected error: 'cannot|need type assertion'
errchk: bugs/bug284.go:139: missing expected error: 'cannot|need type assertion'
errchk: bugs/bug284.go:149: missing expected error: 'cannot'
errchk: bugs/bug284.go:152: missing expected error: 'cannot'
errchk: bugs/bug284.go:153: missing expected error: 'cannot'
errchk: bugs/bug284.go:154: missing expected error: 'cannot'
errchk: bugs/bug284.go:164: missing expected error: 'cannot'
errchk: bugs/bug284.go:167: missing expected error: 'cannot'
errchk: bugs/bug284.go:168: missing expected error: 'cannot'
errchk: bugs/bug284.go:169: missing expected error: 'cannot'
errchk: bugs/bug284.go:179: missing expected error: 'cannot'
errchk: bugs/bug284.go:182: missing expected error: 'cannot'
errchk: bugs/bug284.go:183: missing expected error: 'cannot'
errchk: bugs/bug284.go:184: missing expected error: 'cannot'
errchk: bugs/bug284.go: unmatched error messages:
==================================================
bugs/bug284.go:190: internal compiler error: typename ideal
==================================================
=========== bugs/bug285.go
bugs/bug285.go:23: invalid map index false - need type B
bugs/bug285.go:80: invalid map index z - need type interface { }
bugs/bug285.go:83: invalid map index new(struct { x int }) - need type interface { }
bugs/bug285.go:84: invalid map index p - need type interface { }
bugs/bug285.go:85: invalid map index false - need type interface { }
bugs/bug285.go:86: invalid map index 17 - need type interface { }
bugs/bug285.go:87: invalid map index "foo" - need type interface { }
bugs/bug285.go:93: invalid map index new(struct { x int }) - need type I1
bugs/bug285.go:94: invalid map index false - need type I1
bugs/bug285.go:95: invalid map index 17 - need type I1
bugs/bug285.go:95: too many errors
BUG: bug285
......@@ -8,34 +8,45 @@
package main
type T struct { a int }
type T struct {
a int
}
var t *T
type I interface { M() }
type I interface {
M()
}
var i I
type I2 interface { M(); N(); }
type I2 interface {
M()
N()
}
var i2 I2
type E interface { }
type E interface{}
var e E
func main() {
e = t; // ok
t = e; // ERROR "need explicit|need type assertion"
e = t // ok
t = e // ERROR "need explicit|need type assertion"
// neither of these can work,
// because i has an extra method
// that t does not, so i cannot contain a t.
i = t; // ERROR "missing|incompatible|is not"
t = i; // ERROR "missing|incompatible|is not"
i = t // ERROR "incompatible|missing M method"
t = i // ERROR "incompatible|need type assertion"
i = i2; // ok
i2 = i; // ERROR "need explicit|need type assertion"
i = i2 // ok
i2 = i // ERROR "missing N method"
i = I(i2); // ok
i2 = I2(i); // ERROR "need explicit|need type assertion"
i = I(i2) // ok
i2 = I2(i) // ERROR "missing N method"
e = E(t); // ok
t = T(e); // ERROR "need explicit|need type assertion|incompatible"
e = E(t) // ok
t = T(e) // ERROR "need explicit|need type assertion|incompatible"
}
......@@ -9,28 +9,28 @@
package main
type Inst interface {
Next() *Inst;
Next() *Inst
}
type Regexp struct {
code []Inst;
start Inst;
code []Inst
start Inst
}
type Start struct {
foo *Inst;
foo *Inst
}
func (start *Start) Next() *Inst { return nil }
func AddInst(Inst) *Inst {
print("ok in addinst\n");
print("ok in addinst\n")
return nil
}
func main() {
print("call addinst\n");
var x Inst = AddInst(new(Start)); // ERROR "illegal|incompatible|is not"
print("return from addinst\n");
print("call addinst\n")
var x Inst = AddInst(new(Start)) // ERROR "pointer to interface"
print("return from addinst\n")
}
......@@ -9,41 +9,50 @@
package main
type T int
func (t T) V()
func (t *T) P()
type V interface { V() }
type P interface { P(); V() }
type V interface {
V()
}
type P interface {
P()
V()
}
type S struct { T; }
type SP struct { *T; }
type S struct {
T
}
type SP struct {
*T
}
func main() {
var t T;
var v V;
var p P;
var s S;
var sp SP;
v = t;
p = t; // ERROR "is not|requires a pointer"
_, _= v, p;
v = &t;
p = &t;
_, _= v, p;
v = s;
p = s; // ERROR "is not|requires a pointer"
_, _= v, p;
v = &s;
p = &s;
_, _= v, p;
v = sp;
p = sp; // no error!
_, _= v, p;
v = &sp;
p = &sp;
_, _= v, p;
var t T
var v V
var p P
var s S
var sp SP
v = t
p = t // ERROR "does not implement|requires a pointer"
_, _ = v, p
v = &t
p = &t
_, _ = v, p
v = s
p = s // ERROR "does not implement|requires a pointer"
_, _ = v, p
v = &s
p = &s
_, _ = v, p
v = sp
p = sp // no error!
_, _ = v, p
v = &sp
p = &sp
_, _ = v, p
}
......@@ -46,236 +46,236 @@ func isString(x interface{}) { _ = x.(String) }
func main() {
var (
a Array;
b Bool = true;
c Chan = make(Chan);
f Float = 1;
i Int = 1;
m Map = make(Map);
slice Slice = make(Slice, 10);
str String = "hello";
a Array
b Bool = true
c Chan = make(Chan)
f Float = 1
i Int = 1
m Map = make(Map)
slice Slice = make(Slice, 10)
str String = "hello"
)
asArray(a);
isArray(a);
asArray(*&a);
isArray(*&a);
asArray(Array{});
isArray(Array{});
asArray(a)
isArray(a)
asArray(*&a)
isArray(*&a)
asArray(Array{})
isArray(Array{})
asBool(b);
isBool(b);
asBool(!b);
isBool(!b);
asBool(true);
asBool(*&b);
isBool(*&b);
asBool(Bool(true));
isBool(Bool(true));
asBool(b)
isBool(b)
asBool(!b)
isBool(!b)
asBool(true)
asBool(*&b)
isBool(*&b)
asBool(Bool(true))
isBool(Bool(true))
asChan(c);
isChan(c);
asChan(make(Chan));
isChan(make(Chan));
asChan(*&c);
isChan(*&c);
asChan(Chan(nil));
isChan(Chan(nil));
asChan(c)
isChan(c)
asChan(make(Chan))
isChan(make(Chan))
asChan(*&c)
isChan(*&c)
asChan(Chan(nil))
isChan(Chan(nil))
asFloat(f);
isFloat(f);
asFloat(-f);
isFloat(-f);
asFloat(+f);
isFloat(+f);
asFloat(f+1);
isFloat(f+1);
asFloat(1+f);
isFloat(1+f);
asFloat(f+f);
isFloat(f+f);
f++;
f+=2;
asFloat(f-1);
isFloat(f-1);
asFloat(1-f);
isFloat(1-f);
asFloat(f-f);
isFloat(f-f);
f--;
f-=2;
asFloat(f*2.5);
isFloat(f*2.5);
asFloat(2.5*f);
isFloat(2.5*f);
asFloat(f*f);
isFloat(f*f);
f*=4;
asFloat(f/2.5);
isFloat(f/2.5);
asFloat(2.5/f);
isFloat(2.5/f);
asFloat(f/f);
isFloat(f/f);
f/=4;
asFloat(f);
isFloat(f);
f = 5;
asFloat(*&f);
isFloat(*&f);
asFloat(234);
asFloat(Float(234));
isFloat(Float(234));
asFloat(1.2);
asFloat(Float(i));
isFloat(Float(i));
asFloat(f)
isFloat(f)
asFloat(-f)
isFloat(-f)
asFloat(+f)
isFloat(+f)
asFloat(f + 1)
isFloat(f + 1)
asFloat(1 + f)
isFloat(1 + f)
asFloat(f + f)
isFloat(f + f)
f++
f += 2
asFloat(f - 1)
isFloat(f - 1)
asFloat(1 - f)
isFloat(1 - f)
asFloat(f - f)
isFloat(f - f)
f--
f -= 2
asFloat(f * 2.5)
isFloat(f * 2.5)
asFloat(2.5 * f)
isFloat(2.5 * f)
asFloat(f * f)
isFloat(f * f)
f *= 4
asFloat(f / 2.5)
isFloat(f / 2.5)
asFloat(2.5 / f)
isFloat(2.5 / f)
asFloat(f / f)
isFloat(f / f)
f /= 4
asFloat(f)
isFloat(f)
f = 5
asFloat(*&f)
isFloat(*&f)
asFloat(234)
asFloat(Float(234))
isFloat(Float(234))
asFloat(1.2)
asFloat(Float(i))
isFloat(Float(i))
asInt(i);
isInt(i);
asInt(-i);
isInt(-i);
asInt(^i);
isInt(^i);
asInt(+i);
isInt(+i);
asInt(i+1);
isInt(i+1);
asInt(1+i);
isInt(1+i);
asInt(i+i);
isInt(i+i);
i++;
i+=1;
asInt(i-1);
isInt(i-1);
asInt(1-i);
isInt(1-i);
asInt(i-i);
isInt(i-i);
i--;
i-=1;
asInt(i*2);
isInt(i*2);
asInt(2*i);
isInt(2*i);
asInt(i*i);
isInt(i*i);
i*=2;
asInt(i/5);
isInt(i/5);
asInt(5/i);
isInt(5/i);
asInt(i/i);
isInt(i/i);
i/=2;
asInt(i%5);
isInt(i%5);
asInt(5%i);
isInt(5%i);
asInt(i%i);
isInt(i%i);
i%=2;
asInt(i&5);
isInt(i&5);
asInt(5&i);
isInt(5&i);
asInt(i&i);
isInt(i&i);
i&=2;
asInt(i&^5);
isInt(i&^5);
asInt(5&^i);
isInt(5&^i);
asInt(i&^i);
isInt(i&^i);
i&^=2;
asInt(i|5);
isInt(i|5);
asInt(5|i);
isInt(5|i);
asInt(i|i);
isInt(i|i);
i|=2;
asInt(i^5);
isInt(i^5);
asInt(5^i);
isInt(5^i);
asInt(i^i);
isInt(i^i);
i^=2;
asInt(i<<4);
isInt(i<<4);
i<<=2;
asInt(i>>4);
isInt(i>>4);
i>>=2;
asInt(i);
isInt(i);
asInt(0);
asInt(Int(0));
isInt(Int(0));
i = 10;
asInt(*&i);
isInt(*&i);
asInt(23);
asInt(Int(f));
isInt(Int(f));
asInt(i)
isInt(i)
asInt(-i)
isInt(-i)
asInt(^i)
isInt(^i)
asInt(+i)
isInt(+i)
asInt(i + 1)
isInt(i + 1)
asInt(1 + i)
isInt(1 + i)
asInt(i + i)
isInt(i + i)
i++
i += 1
asInt(i - 1)
isInt(i - 1)
asInt(1 - i)
isInt(1 - i)
asInt(i - i)
isInt(i - i)
i--
i -= 1
asInt(i * 2)
isInt(i * 2)
asInt(2 * i)
isInt(2 * i)
asInt(i * i)
isInt(i * i)
i *= 2
asInt(i / 5)
isInt(i / 5)
asInt(5 / i)
isInt(5 / i)
asInt(i / i)
isInt(i / i)
i /= 2
asInt(i % 5)
isInt(i % 5)
asInt(5 % i)
isInt(5 % i)
asInt(i % i)
isInt(i % i)
i %= 2
asInt(i & 5)
isInt(i & 5)
asInt(5 & i)
isInt(5 & i)
asInt(i & i)
isInt(i & i)
i &= 2
asInt(i &^ 5)
isInt(i &^ 5)
asInt(5 &^ i)
isInt(5 &^ i)
asInt(i &^ i)
isInt(i &^ i)
i &^= 2
asInt(i | 5)
isInt(i | 5)
asInt(5 | i)
isInt(5 | i)
asInt(i | i)
isInt(i | i)
i |= 2
asInt(i ^ 5)
isInt(i ^ 5)
asInt(5 ^ i)
isInt(5 ^ i)
asInt(i ^ i)
isInt(i ^ i)
i ^= 2
asInt(i << 4)
isInt(i << 4)
i <<= 2
asInt(i >> 4)
isInt(i >> 4)
i >>= 2
asInt(i)
isInt(i)
asInt(0)
asInt(Int(0))
isInt(Int(0))
i = 10
asInt(*&i)
isInt(*&i)
asInt(23)
asInt(Int(f))
isInt(Int(f))
asMap(m);
isMap(m);
asMap(nil);
m = nil;
asMap(make(Map));
isMap(make(Map));
asMap(*&m);
isMap(*&m);
asMap(Map(nil));
isMap(Map(nil));
asMap(Map{});
isMap(Map{});
asMap(m)
isMap(m)
asMap(nil)
m = nil
asMap(make(Map))
isMap(make(Map))
asMap(*&m)
isMap(*&m)
asMap(Map(nil))
isMap(Map(nil))
asMap(Map{})
isMap(Map{})
asSlice(slice);
isSlice(slice);
asSlice(make(Slice, 5));
isSlice(make(Slice, 5));
asSlice([]byte{1,2,3});
asSlice([]byte{1,2,3}[0:2]);
asSlice(slice[0:4]);
isSlice(slice[0:4]);
asSlice(slice[3:8]);
isSlice(slice[3:8]);
asSlice(nil);
asSlice(Slice(nil));
isSlice(Slice(nil));
slice = nil;
asSlice(Slice{1,2,3});
isSlice(Slice{1,2,3});
asSlice(Slice{});
isSlice(Slice{});
asSlice(*&slice);
isSlice(*&slice);
asSlice(slice)
isSlice(slice)
asSlice(make(Slice, 5))
isSlice(make(Slice, 5))
asSlice([]byte{1, 2, 3})
asSlice([]byte{1, 2, 3}[0:2])
asSlice(slice[0:4])
isSlice(slice[0:4])
asSlice(slice[3:8])
isSlice(slice[3:8])
asSlice(nil)
asSlice(Slice(nil))
isSlice(Slice(nil))
slice = nil
asSlice(Slice{1, 2, 3})
isSlice(Slice{1, 2, 3})
asSlice(Slice{})
isSlice(Slice{})
asSlice(*&slice)
isSlice(*&slice)
asString(str);
isString(str);
asString(str+"a");
isString(str+"a");
asString("a"+str);
isString("a"+str);
asString(str+str);
isString(str+str);
str += "a";
str += str;
asString(String('a'));
isString(String('a'));
asString(String(slice));
isString(String(slice));
asString(String([]byte(nil)));
isString(String([]byte(nil)));
asString("hello");
asString(String("hello"));
isString(String("hello"));
str = "hello";
isString(str);
asString(*&str);
isString(*&str);
asString(str)
isString(str)
asString(str + "a")
isString(str + "a")
asString("a" + str)
isString("a" + str)
asString(str + str)
isString(str + str)
str += "a"
str += str
asString(String('a'))
isString(String('a'))
asString(String([]byte(slice)))
isString(String([]byte(slice)))
asString(String([]byte(nil)))
isString(String([]byte(nil)))
asString("hello")
asString(String("hello"))
isString(String("hello"))
str = "hello"
isString(str)
asString(*&str)
isString(*&str)
}
......@@ -12,46 +12,57 @@ package main
type Bool bool
type Map map[int]int
func (Map) M() {}
type Slice []byte
var slice Slice
func asBool(Bool) {}
func asString(String) {}
type String string
func main() {
var (
b Bool = true;
i, j int;
c = make(chan int);
m = make(Map);
b Bool = true
i, j int
c = make(chan int)
m = make(Map)
)
asBool(b);
asBool(!b);
asBool(true);
asBool(*&b);
asBool(Bool(true));
asBool(1!=2); // ERROR "cannot use.*type bool.*as type Bool"
asBool(i < j); // ERROR "cannot use.*type bool.*as type Bool"
asBool(b)
asBool(!b)
asBool(true)
asBool(*&b)
asBool(Bool(true))
asBool(1 != 2) // ERROR "cannot use.*type bool.*as type Bool"
asBool(i < j) // ERROR "cannot use.*type bool.*as type Bool"
_, b = m[2]; // ERROR "cannot .* bool.*type Bool"
m[2] = 1, b; // ERROR "cannot use.*type Bool.*as type bool"
_, b = m[2] // ERROR "cannot .* bool.*type Bool"
m[2] = 1, b // ERROR "cannot use.*type Bool.*as type bool"
b = c<-1; // ERROR "cannot use.*type bool.*type Bool"
_ = b;
asBool(c<-1); // ERROR "cannot use.*type bool.*as type Bool"
b = c <- 1 // ERROR "cannot use.*type bool.*type Bool"
_ = b
asBool(c <- 1) // ERROR "cannot use.*type bool.*as type Bool"
_, b = <-c; // ERROR "cannot .* bool.*type Bool"
_ = b;
_, b = <-c // ERROR "cannot .* bool.*type Bool"
_ = b
var inter interface{};
_, b = inter.(Map); // ERROR "cannot .* bool.*type Bool"
_ = b;
var inter interface{}
_, b = inter.(Map) // ERROR "cannot .* bool.*type Bool"
_ = b
var minter interface{M()};
_, b = minter.(Map); // ERROR "cannot .* bool.*type Bool"
_ = b;
var minter interface {
M()
}
_, b = minter.(Map) // ERROR "cannot .* bool.*type Bool"
_ = b
asBool(closed(c)); // ERROR "cannot use.*type bool.*as type Bool"
b = closed(c); // ERROR "cannot use.*type bool.*type Bool"
_ = b;
}
asBool(closed(c)) // ERROR "cannot use.*type bool.*as type Bool"
b = closed(c) // ERROR "cannot use.*type bool.*type Bool"
_ = b
asString(String(slice)) // ERROR "cannot convert slice"
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment