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) ...@@ -431,7 +431,7 @@ agen(Node *n, Node *res)
if(n == N || n->type == T) if(n == N || n->type == T)
return; return;
if(!isptr[res->type->etype]) if(!isptr[res->type->etype] && res->type->etype != TUINTPTR)
fatal("agen: not tptr: %T", res->type); fatal("agen: not tptr: %T", res->type);
while(n->op == OCONVNOP) while(n->op == OCONVNOP)
......
...@@ -133,25 +133,22 @@ bitno(int32 b) ...@@ -133,25 +133,22 @@ bitno(int32 b)
int int
Qconv(Fmt *fp) Qconv(Fmt *fp)
{ {
char str[STRINGSZ], ss[STRINGSZ], *s;
Bits bits; Bits bits;
int i; int i, first;
str[0] = 0; first = 1;
bits = va_arg(fp->args, Bits); bits = va_arg(fp->args, Bits);
while(bany(&bits)) { while(bany(&bits)) {
i = bnum(bits); i = bnum(bits);
if(str[0]) if(first)
strcat(str, " "); first = 0;
if(var[i].sym == S) { else
sprint(ss, "$%lld", var[i].offset); fmtprint(fp, " ");
s = ss; if(var[i].sym == S)
} else fmtprint(fp, "$%lld", var[i].offset);
s = var[i].sym->name; else
if(strlen(str) + strlen(s) + 1 >= STRINGSZ) fmtprint(fp, var[i].sym->name);
break;
strcat(str, s);
bits.b[i/32] &= ~(1L << (i%32)); bits.b[i/32] &= ~(1L << (i%32));
} }
return fmtstrcpy(fp, str); return 0;
} }
...@@ -33,18 +33,22 @@ char *runtimeimport = ...@@ -33,18 +33,22 @@ char *runtimeimport =
"func \"\".stringiter (? string, ? int) int\n" "func \"\".stringiter (? string, ? int) int\n"
"func \"\".stringiter2 (? string, ? int) (retk int, retv int)\n" "func \"\".stringiter2 (? string, ? int) (retk int, retv int)\n"
"func \"\".slicecopy (to any, fr any, wid uint32) int\n" "func \"\".slicecopy (to any, fr any, wid uint32) int\n"
"func \"\".ifaceI2E (iface any) any\n" "func \"\".convI2E (elem any) any\n"
"func \"\".ifaceE2I (typ *uint8, iface any) any\n" "func \"\".convI2I (typ *uint8, elem any) any\n"
"func \"\".ifaceT2E (typ *uint8, elem any) any\n" "func \"\".convT2E (typ *uint8, elem any) any\n"
"func \"\".ifaceE2T (typ *uint8, elem any) any\n" "func \"\".convT2I (typ *uint8, typ2 *uint8, elem any) any\n"
"func \"\".ifaceE2I2 (typ *uint8, iface any) (ret any, ok bool)\n" "func \"\".assertE2E (typ *uint8, iface any) any\n"
"func \"\".ifaceE2T2 (typ *uint8, elem any) (ret any, ok bool)\n" "func \"\".assertE2E2 (typ *uint8, iface any) (ret any, ok bool)\n"
"func \"\".ifaceT2I (typ1 *uint8, typ2 *uint8, elem any) any\n" "func \"\".assertE2I (typ *uint8, iface any) any\n"
"func \"\".ifaceI2T (typ *uint8, iface any) any\n" "func \"\".assertE2I2 (typ *uint8, iface any) (ret any, ok bool)\n"
"func \"\".ifaceI2T2 (typ *uint8, iface any) (ret any, ok bool)\n" "func \"\".assertE2T (typ *uint8, iface any) any\n"
"func \"\".ifaceI2I (typ *uint8, iface any) any\n" "func \"\".assertE2T2 (typ *uint8, iface any) (ret any, ok bool)\n"
"func \"\".ifaceI2Ix (typ *uint8, iface any) any\n" "func \"\".assertI2E (typ *uint8, iface any) any\n"
"func \"\".ifaceI2I2 (typ *uint8, iface any) (ret any, ok bool)\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 \"\".ifaceeq (i1 any, i2 any) bool\n"
"func \"\".efaceeq (i1 any, i2 any) bool\n" "func \"\".efaceeq (i1 any, i2 any) bool\n"
"func \"\".ifacethash (i1 any) uint32\n" "func \"\".ifacethash (i1 any) uint32\n"
......
...@@ -119,6 +119,7 @@ walkclosure(Node *func, NodeList **init) ...@@ -119,6 +119,7 @@ walkclosure(Node *func, NodeList **init)
Node *xtype, *v, *addr, *xfunc, *call, *clos; Node *xtype, *v, *addr, *xfunc, *call, *clos;
NodeList *l, *in; NodeList *l, *in;
static int closgen; static int closgen;
char *p;
/* /*
* wrap body in external function * wrap body in external function
...@@ -134,8 +135,9 @@ walkclosure(Node *func, NodeList **init) ...@@ -134,8 +135,9 @@ walkclosure(Node *func, NodeList **init)
if(v->op == 0) if(v->op == 0)
continue; continue;
addr = nod(ONAME, N, N); addr = nod(ONAME, N, N);
snprint(namebuf, sizeof namebuf, "&%s", v->sym->name); p = smprint("&%s", v->sym->name);
addr->sym = lookup(namebuf); addr->sym = lookup(p);
free(p);
addr->ntype = nod(OIND, typenod(v->type), N); addr->ntype = nod(OIND, typenod(v->type), N);
addr->class = PPARAM; addr->class = PPARAM;
addr->addable = 1; addr->addable = 1;
......
...@@ -93,8 +93,11 @@ convlit1(Node **np, Type *t, int explicit) ...@@ -93,8 +93,11 @@ convlit1(Node **np, Type *t, int explicit)
return; return;
case OLITERAL: case OLITERAL:
// target is invalid type for a constant? leave alone. // 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; return;
}
break; break;
case OLSH: case OLSH:
case ORSH: case ORSH:
...@@ -109,10 +112,8 @@ convlit1(Node **np, Type *t, int explicit) ...@@ -109,10 +112,8 @@ convlit1(Node **np, Type *t, int explicit)
} }
// avoided repeated calculations, errors // avoided repeated calculations, errors
if(cvttype(n->type, t) == 1) { if(eqtype(n->type, t))
n->type = t;
return; return;
}
ct = consttype(n); ct = consttype(n);
if(ct < 0) if(ct < 0)
...@@ -968,6 +969,8 @@ defaultlit(Node **np, Type *t) ...@@ -968,6 +969,8 @@ defaultlit(Node **np, Type *t)
break; break;
case CTBOOL: case CTBOOL:
n->type = types[TBOOL]; n->type = types[TBOOL];
if(t != T && t->etype == TBOOL)
n->type = t;
break; break;
case CTINT: case CTINT:
n->type = types[TINT]; n->type = types[TINT];
......
...@@ -281,6 +281,7 @@ updatetype(Type *n, Type *t) ...@@ -281,6 +281,7 @@ updatetype(Type *n, Type *t)
local = n->local; local = n->local;
vargen = n->vargen; vargen = n->vargen;
*n = *t; *n = *t;
n->orig = t->orig;
n->sym = s; n->sym = s;
n->local = local; n->local = local;
n->siggen = 0; n->siggen = 0;
...@@ -759,7 +760,7 @@ typedcl2(Type *pt, Type *t) ...@@ -759,7 +760,7 @@ typedcl2(Type *pt, Type *t)
if(pt->etype == TFORW) if(pt->etype == TFORW)
goto ok; 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); yyerror("inconsistent definition for type %S during import\n\t%lT\n\t%lT", pt->sym, pt, t);
return; return;
...@@ -1154,7 +1155,7 @@ Sym* ...@@ -1154,7 +1155,7 @@ Sym*
methodsym(Sym *nsym, Type *t0) methodsym(Sym *nsym, Type *t0)
{ {
Sym *s; Sym *s;
char buf[NSYMB]; char *p;
Type *t; Type *t;
t = t0; t = t0;
...@@ -1177,8 +1178,10 @@ methodsym(Sym *nsym, Type *t0) ...@@ -1177,8 +1178,10 @@ methodsym(Sym *nsym, Type *t0)
if(t != t0 && t0->sym) if(t != t0 && t0->sym)
t0 = ptrto(t); t0 = ptrto(t);
snprint(buf, sizeof(buf), "%#hT·%s", t0, nsym->name); p = smprint("%#hT·%s", t0, nsym->name);
return pkglookup(buf, s->pkg); s = pkglookup(p, s->pkg);
free(p);
return s;
bad: bad:
yyerror("illegal receiver type: %T", t0); yyerror("illegal receiver type: %T", t0);
...@@ -1200,7 +1203,7 @@ Node* ...@@ -1200,7 +1203,7 @@ Node*
methodname1(Node *n, Node *t) methodname1(Node *n, Node *t)
{ {
char *star; char *star;
char buf[NSYMB]; char *p;
star = ""; star = "";
if(t->op == OIND) { if(t->op == OIND) {
...@@ -1209,8 +1212,10 @@ methodname1(Node *n, Node *t) ...@@ -1209,8 +1212,10 @@ methodname1(Node *n, Node *t)
} }
if(t->sym == S || isblank(n)) if(t->sym == S || isblank(n))
return newname(n->sym); return newname(n->sym);
snprint(buf, sizeof(buf), "%s%S·%S", star, t->sym, n->sym); p = smprint("%s%S·%S", star, t->sym, n->sym);
return newname(pkglookup(buf, t->sym->pkg)); n = newname(pkglookup(p, t->sym->pkg));
free(p);
return n;
} }
/* /*
......
...@@ -182,10 +182,22 @@ dumpexporttype(Sym *s) ...@@ -182,10 +182,22 @@ dumpexporttype(Sym *s)
Bprint(bout, "type %#T %l#T\n", t, t); 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 void
dumpsym(Sym *s) dumpsym(Sym *s)
{ {
Type *f, *t; Type *f, *t;
Type **m;
int i, n;
if(s->flags & SymExported) if(s->flags & SymExported)
return; return;
...@@ -207,14 +219,23 @@ dumpsym(Sym *s) ...@@ -207,14 +219,23 @@ dumpsym(Sym *s)
break; break;
case OTYPE: case OTYPE:
t = s->def->type; t = s->def->type;
// TODO(rsc): sort methods by name n = 0;
for(f=t->method; f!=T; f=f->down) for(f=t->method; f!=T; f=f->down) {
dumpprereq(f); 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); 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", Bprint(bout, "\tfunc (%#T) %hS %#hhT\n",
f->type->type->type, f->sym, f->type); f->type->type->type, f->sym, f->type);
}
break; break;
case ONAME: case ONAME:
dumpexportvar(s); dumpexportvar(s);
...@@ -357,7 +378,7 @@ importvar(Sym *s, Type *t, int ctxt) ...@@ -357,7 +378,7 @@ importvar(Sym *s, Type *t, int ctxt)
importsym(s, ONAME); importsym(s, ONAME);
if(s->def != N && s->def->op == ONAME) { if(s->def != N && s->def->op == ONAME) {
if(cvttype(t, s->def->type)) if(eqtype(t, s->def->type))
return; return;
yyerror("inconsistent definition for var %S during import\n\t%T\n\t%T", yyerror("inconsistent definition for var %S during import\n\t%T\n\t%T",
s, s->def->type, t); s, s->def->type, t);
......
...@@ -158,6 +158,7 @@ struct Type ...@@ -158,6 +158,7 @@ struct Type
uchar isddd; // TFIELD is ... argument uchar isddd; // TFIELD is ... argument
Node* nod; // canonical OTYPE node Node* nod; // canonical OTYPE node
Type* orig; // original type (type literal or predefined type)
int lineno; int lineno;
// TFUNCT // TFUNCT
...@@ -361,11 +362,12 @@ enum ...@@ -361,11 +362,12 @@ enum
OCLOSURE, OCLOSURE,
OCMPIFACE, OCMPSTR, OCMPIFACE, OCMPSTR,
OCOMPLIT, OMAPLIT, OSTRUCTLIT, OARRAYLIT, OCOMPLIT, OMAPLIT, OSTRUCTLIT, OARRAYLIT,
OCONV, OCONVNOP, OCONVIFACE, OCONVSLICE, OCONV, OCONVIFACE, OCONVNOP, OCONVSLICE,
OCOPY, OCOPY,
ODCL, ODCLFUNC, ODCLFIELD, ODCLCONST, ODCLTYPE, ODCL, ODCLFUNC, ODCLFIELD, ODCLCONST, ODCLTYPE,
ODOT, ODOTPTR, ODOTMETH, ODOTINTER, OXDOT, ODOT, ODOTPTR, ODOTMETH, ODOTINTER, OXDOT,
ODOTTYPE, ODOTTYPE,
ODOTTYPE2,
OEQ, ONE, OLT, OLE, OGE, OGT, OEQ, ONE, OLT, OLE, OGE, OGT,
OIND, OIND,
OINDEX, OINDEXSTR, OINDEXMAP, OINDEX, OINDEXSTR, OINDEXMAP,
...@@ -904,26 +906,21 @@ NodeList* list(NodeList*, Node*); ...@@ -904,26 +906,21 @@ NodeList* list(NodeList*, Node*);
NodeList* concat(NodeList*, NodeList*); NodeList* concat(NodeList*, NodeList*);
int count(NodeList*); int count(NodeList*);
Node* liststmt(NodeList*); Node* liststmt(NodeList*);
Type** getthis(Type*); Type** getthis(Type*);
Type** getoutarg(Type*); Type** getoutarg(Type*);
Type** getinarg(Type*); Type** getinarg(Type*);
Type* getthisx(Type*); Type* getthisx(Type*);
Type* getoutargx(Type*); Type* getoutargx(Type*);
Type* getinargx(Type*); Type* getinargx(Type*);
Type* structfirst(Iter*, Type**); Type* structfirst(Iter*, Type**);
Type* structnext(Iter*); Type* structnext(Iter*);
Type* funcfirst(Iter*, Type*); Type* funcfirst(Iter*, Type*);
Type* funcnext(Iter*); Type* funcnext(Iter*);
int brcom(int); int brcom(int);
int brrev(int); int brrev(int);
void setmaxarg(Type*); void setmaxarg(Type*);
int dotoffset(Node*, int*, Node**); int dotoffset(Node*, int*, Node**);
void tempname(Node*, Type*); void tempname(Node*, Type*);
int Econv(Fmt*); int Econv(Fmt*);
int Jconv(Fmt*); int Jconv(Fmt*);
int Lconv(Fmt*); int Lconv(Fmt*);
...@@ -934,23 +931,22 @@ int Nconv(Fmt*); ...@@ -934,23 +931,22 @@ int Nconv(Fmt*);
void exprfmt(Fmt*, Node*, int); void exprfmt(Fmt*, Node*, int);
int Wconv(Fmt*); int Wconv(Fmt*);
int Zconv(Fmt*); int Zconv(Fmt*);
int lookdot0(Sym*, Type*, Type**); int lookdot0(Sym*, Type*, Type**);
int adddot1(Sym*, Type*, int, Type**); int adddot1(Sym*, Type*, int, Type**);
Node* adddot(Node*); Node* adddot(Node*);
void expandmeth(Sym*, Type*); void expandmeth(Sym*, Type*);
void genwrapper(Type*, Type*, Sym*); void genwrapper(Type*, Type*, Sym*);
int simsimtype(Type*); int simsimtype(Type*);
int powtwo(Node*); int powtwo(Node*);
Type* tounsigned(Type*); Type* tounsigned(Type*);
void smagic(Magic*); void smagic(Magic*);
void umagic(Magic*); void umagic(Magic*);
void redeclare(Sym*, char*); void redeclare(Sym*, char*);
Sym* ngotype(Node*); 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 * dcl.c
...@@ -1053,7 +1049,6 @@ void walkstmt(Node**); ...@@ -1053,7 +1049,6 @@ void walkstmt(Node**);
void walkstmtlist(NodeList*); void walkstmtlist(NodeList*);
void walkexprlist(NodeList*, NodeList**); void walkexprlist(NodeList*, NodeList**);
void walkconv(Node**, NodeList**); void walkconv(Node**, NodeList**);
void walkdottype(Node*, NodeList**);
void walkas(Node*); void walkas(Node*);
void walkswitch(Node*); void walkswitch(Node*);
void walkrange(Node*); void walkrange(Node*);
...@@ -1071,8 +1066,6 @@ Type* fixchan(Type*); ...@@ -1071,8 +1066,6 @@ Type* fixchan(Type*);
Node* ifacecvt(Type*, Node*, int, NodeList**); Node* ifacecvt(Type*, Node*, int, NodeList**);
int ifaceas(Type*, Type*, int); int ifaceas(Type*, Type*, int);
int ifaceas1(Type*, Type*, int); int ifaceas1(Type*, Type*, int);
void ifacecheck(Type*, Type*, int, int);
void runifacechecks(void);
Node* convas(Node*, NodeList**); Node* convas(Node*, NodeList**);
Node* colas(NodeList*, NodeList*); Node* colas(NodeList*, NodeList*);
void colasdefn(NodeList*, Node*); void colasdefn(NodeList*, Node*);
...@@ -1090,10 +1083,10 @@ void typecheckswitch(Node*); ...@@ -1090,10 +1083,10 @@ void typecheckswitch(Node*);
void typecheckselect(Node*); void typecheckselect(Node*);
void typecheckrange(Node*); void typecheckrange(Node*);
Node* typecheckconv(Node*, Node*, Type*, int, char*); Node* typecheckconv(Node*, Node*, Type*, int, char*);
int checkconv(Type*, Type*, int, int*, int*, char*);
Node* typecheck(Node**, int); Node* typecheck(Node**, int);
int islvalue(Node*); int islvalue(Node*);
void queuemethod(Node*); void queuemethod(Node*);
int exportassignok(Type*, char*);
/* /*
* const.c * const.c
...@@ -1242,4 +1235,4 @@ int duintptr(Sym *s, int off, uint64 v); ...@@ -1242,4 +1235,4 @@ int duintptr(Sym *s, int off, uint64 v);
int duintxx(Sym *s, int off, uint64 v, int wid); int duintxx(Sym *s, int off, uint64 v, int wid);
void genembedtramp(Type*, Type*, Sym*); void genembedtramp(Type*, Type*, Sym*);
int gen_as_init(Node*); int gen_as_init(Node*);
int anyregalloc(); int anyregalloc(void);
...@@ -148,8 +148,21 @@ main(int argc, char *argv[]) ...@@ -148,8 +148,21 @@ main(int argc, char *argv[])
typecheckok = 1; typecheckok = 1;
if(debug['f']) if(debug['f'])
frame(1); 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(); 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(); resumecheckwidth();
for(l=xtop; l; l=l->next) for(l=xtop; l; l=l->next)
if(l->n->op == ODCLFUNC) if(l->n->op == ODCLFUNC)
...@@ -164,7 +177,6 @@ main(int argc, char *argv[]) ...@@ -164,7 +177,6 @@ main(int argc, char *argv[])
} }
dclchecks(); dclchecks();
runifacechecks();
if(nerrors) if(nerrors)
errorexit(); errorexit();
...@@ -1155,7 +1167,7 @@ loop: ...@@ -1155,7 +1167,7 @@ loop:
int int
escchar(int e, int *escflg, vlong *val) escchar(int e, int *escflg, vlong *val)
{ {
int i, c; int i, u, c;
vlong l; vlong l;
*escflg = 0; *escflg = 0;
...@@ -1177,6 +1189,7 @@ escchar(int e, int *escflg, vlong *val) ...@@ -1177,6 +1189,7 @@ escchar(int e, int *escflg, vlong *val)
return 0; return 0;
} }
u = 0;
c = getr(); c = getr();
switch(c) { switch(c) {
case 'x': case 'x':
...@@ -1186,10 +1199,12 @@ escchar(int e, int *escflg, vlong *val) ...@@ -1186,10 +1199,12 @@ escchar(int e, int *escflg, vlong *val)
case 'u': case 'u':
i = 4; i = 4;
u = 1;
goto hex; goto hex;
case 'U': case 'U':
i = 8; i = 8;
u = 1;
goto hex; goto hex;
case '0': case '0':
...@@ -1239,6 +1254,10 @@ hex: ...@@ -1239,6 +1254,10 @@ hex:
ungetc(c); ungetc(c);
break; break;
} }
if(u && l > Runemax) {
yyerror("invalid Unicode code point in escape sequence: %#llx", l);
l = Runeerror;
}
*val = l; *val = l;
return 0; return 0;
...@@ -1388,7 +1407,6 @@ lexinit(void) ...@@ -1388,7 +1407,6 @@ lexinit(void)
// (the type of x in var x string or var x = "hello"). // (the type of x in var x string or var x = "hello").
// this is the ideal form // this is the ideal form
// (the type of x in const x = "hello"). // (the type of x in const x = "hello").
// TODO(rsc): this may need some more thought.
idealstring = typ(TSTRING); idealstring = typ(TSTRING);
idealbool = typ(TBOOL); idealbool = typ(TBOOL);
......
...@@ -39,6 +39,8 @@ exprfmt(Fmt *f, Node *n, int prec) ...@@ -39,6 +39,8 @@ exprfmt(Fmt *f, Node *n, int prec)
case ODOTPTR: case ODOTPTR:
case ODOTINTER: case ODOTINTER:
case ODOTMETH: case ODOTMETH:
case ODOTTYPE:
case ODOTTYPE2:
case OARRAYBYTESTR: case OARRAYBYTESTR:
case OCAP: case OCAP:
case OCLOSE: case OCLOSE:
...@@ -54,7 +56,6 @@ exprfmt(Fmt *f, Node *n, int prec) ...@@ -54,7 +56,6 @@ exprfmt(Fmt *f, Node *n, int prec)
case OCONV: case OCONV:
case OCONVNOP: case OCONVNOP:
case OCONVSLICE: case OCONVSLICE:
case OCONVIFACE:
case OMAKESLICE: case OMAKESLICE:
case ORUNESTR: case ORUNESTR:
case OADDR: case OADDR:
...@@ -64,6 +65,7 @@ exprfmt(Fmt *f, Node *n, int prec) ...@@ -64,6 +65,7 @@ exprfmt(Fmt *f, Node *n, int prec)
case ONOT: case ONOT:
case OPLUS: case OPLUS:
case ORECV: case ORECV:
case OCONVIFACE:
nprec = 7; nprec = 7;
break; break;
...@@ -277,6 +279,7 @@ exprfmt(Fmt *f, Node *n, int prec) ...@@ -277,6 +279,7 @@ exprfmt(Fmt *f, Node *n, int prec)
break; break;
case ODOTTYPE: case ODOTTYPE:
case ODOTTYPE2:
exprfmt(f, n->left, 7); exprfmt(f, n->left, 7);
fmtprint(f, ".("); fmtprint(f, ".(");
if(n->right != N) if(n->right != N)
...@@ -336,9 +339,9 @@ exprfmt(Fmt *f, Node *n, int prec) ...@@ -336,9 +339,9 @@ exprfmt(Fmt *f, Node *n, int prec)
break; break;
case OCONV: case OCONV:
case OCONVIFACE:
case OCONVNOP: case OCONVNOP:
case OCONVSLICE: case OCONVSLICE:
case OCONVIFACE:
case OARRAYBYTESTR: case OARRAYBYTESTR:
case ORUNESTR: case ORUNESTR:
if(n->type == T || n->type->sym == S) if(n->type == T || n->type->sym == S)
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
void void
typecheckrange(Node *n) typecheckrange(Node *n)
{ {
int op, et; char *why;
Type *t, *t1, *t2; Type *t, *t1, *t2;
Node *v1, *v2; Node *v1, *v2;
NodeList *ll; NodeList *ll;
...@@ -66,13 +66,13 @@ typecheckrange(Node *n) ...@@ -66,13 +66,13 @@ typecheckrange(Node *n)
if(v1->defn == n) if(v1->defn == n)
v1->type = t1; v1->type = t1;
else if(v1->type != T && checkconv(t1, v1->type, 0, &op, &et, "range") < 0) else if(v1->type != T && assignop(t1, v1->type, &why) == 0)
yyerror("cannot assign type %T to %+N", t1, v1); yyerror("cannot assign type %T to %+N in range%s", t1, v1, why);
if(v2) { if(v2) {
if(v2->defn == n) if(v2->defn == n)
v2->type = t2; v2->type = t2;
else if(v2->type != T && checkconv(t2, v2->type, 0, &op, &et, "range") < 0) else if(v2->type != T && assignop(t2, v2->type, &why) == 0)
yyerror("cannot assign type %T to %+N", t1, v1); yyerror("cannot assign type %T to %+N in range%s", t2, v2, why);
} }
out: out:
......
...@@ -47,18 +47,26 @@ func stringiter(string, int) int ...@@ -47,18 +47,26 @@ func stringiter(string, int) int
func stringiter2(string, int) (retk int, retv int) func stringiter2(string, int) (retk int, retv int)
func slicecopy(to any, fr any, wid uint32) int func slicecopy(to any, fr any, wid uint32) int
func ifaceI2E(iface any) (ret any) // interface conversions
func ifaceE2I(typ *byte, iface any) (ret any) func convI2E(elem any) (ret any)
func ifaceT2E(typ *byte, elem any) (ret any) func convI2I(typ *byte, elem any) (ret any)
func ifaceE2T(typ *byte, elem any) (ret any) func convT2E(typ *byte, elem any) (ret any)
func ifaceE2I2(typ *byte, iface any) (ret any, ok bool) func convT2I(typ *byte, typ2 *byte, elem any) (ret any)
func ifaceE2T2(typ *byte, elem any) (ret any, ok bool)
func ifaceT2I(typ1 *byte, typ2 *byte, elem any) (ret any) // interface type assertions x.(T)
func ifaceI2T(typ *byte, iface any) (ret any) func assertE2E(typ *byte, iface any) (ret any)
func ifaceI2T2(typ *byte, iface any) (ret any, ok bool) func assertE2E2(typ *byte, iface any) (ret any, ok bool)
func ifaceI2I(typ *byte, iface any) (ret any) func assertE2I(typ *byte, iface any) (ret any)
func ifaceI2Ix(typ *byte, iface any) (ret any) func assertE2I2(typ *byte, iface any) (ret any, ok bool)
func ifaceI2I2(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 ifaceeq(i1 any, i2 any) (ret bool)
func efaceeq(i1 any, i2 any) (ret bool) func efaceeq(i1 any, i2 any) (ret bool)
func ifacethash(i1 any) (ret uint32) 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) ...@@ -177,26 +177,26 @@ copyout(Type *t, void **src, void *dst)
algarray[alg].copy(wid, dst, *src); 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 #pragma textflag 7
void void
·ifaceT2I(InterfaceType *inter, Type *t, ...) ·convT2I(Type *t, InterfaceType *inter, ...)
{ {
byte *elem; byte *elem;
Iface *ret; Iface *ret;
int32 wid; int32 wid;
elem = (byte*)(&t+1); elem = (byte*)(&inter+1);
wid = t->size; wid = t->size;
ret = (Iface*)(elem + rnd(wid, Structrnd)); ret = (Iface*)(elem + rnd(wid, Structrnd));
ret->tab = itab(inter, t, 0); ret->tab = itab(inter, t, 0);
copyin(t, elem, &ret->data); copyin(t, elem, &ret->data);
} }
// ifaceT2E(sigt *byte, elem any) (ret Eface); // func convT2E(typ *byte, elem any) (ret any)
#pragma textflag 7 #pragma textflag 7
void void
·ifaceT2E(Type *t, ...) ·convT2E(Type *t, ...)
{ {
byte *elem; byte *elem;
Eface *ret; Eface *ret;
...@@ -205,15 +205,14 @@ void ...@@ -205,15 +205,14 @@ void
elem = (byte*)(&t+1); elem = (byte*)(&t+1);
wid = t->size; wid = t->size;
ret = (Eface*)(elem + rnd(wid, Structrnd)); ret = (Eface*)(elem + rnd(wid, Structrnd));
ret->type = t; ret->type = t;
copyin(t, elem, &ret->data); copyin(t, elem, &ret->data);
} }
// ifaceI2T(sigt *byte, iface any) (ret any); // func ifaceI2T(typ *byte, iface any) (ret any)
#pragma textflag 7 #pragma textflag 7
void void
·ifaceI2T(Type *t, Iface i, ...) ·assertI2T(Type *t, Iface i, ...)
{ {
Itab *tab; Itab *tab;
byte *ret; byte *ret;
...@@ -236,10 +235,10 @@ void ...@@ -236,10 +235,10 @@ void
copyout(t, &i.data, ret); 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 #pragma textflag 7
void void
·ifaceI2T2(Type *t, Iface i, ...) ·assertI2T2(Type *t, Iface i, ...)
{ {
byte *ret; byte *ret;
bool *ok; bool *ok;
...@@ -259,10 +258,10 @@ void ...@@ -259,10 +258,10 @@ void
copyout(t, &i.data, ret); copyout(t, &i.data, ret);
} }
// ifaceE2T(sigt *byte, e Eface) (ret any); // func ifaceE2T(typ *byte, iface any) (ret any)
#pragma textflag 7 #pragma textflag 7
void void
·ifaceE2T(Type *t, Eface e, ...) ·assertE2T(Type *t, Eface e, ...)
{ {
byte *ret; byte *ret;
Eface err; Eface err;
...@@ -284,10 +283,10 @@ void ...@@ -284,10 +283,10 @@ void
copyout(t, &e.data, ret); 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 #pragma textflag 7
void void
·ifaceE2T2(Type *t, Eface e, ...) ·assertE2T2(Type *t, Eface e, ...)
{ {
byte *ret; byte *ret;
bool *ok; bool *ok;
...@@ -307,50 +306,82 @@ void ...@@ -307,50 +306,82 @@ void
copyout(t, &e.data, ret); copyout(t, &e.data, ret);
} }
// ifaceI2E(sigi *byte, iface any) (ret any); // func convI2E(elem any) (ret any)
// TODO(rsc): Move to back end, throw away function. #pragma textflag 7
void void
·ifaceI2E(Iface i, Eface ret) ·convI2E(Iface i, Eface ret)
{ {
Itab *tab; Itab *tab;
ret.data = i.data; ret.data = i.data;
tab = i.tab; if((tab = i.tab) == nil)
if(tab == nil)
ret.type = nil; ret.type = nil;
else else
ret.type = tab->type; ret.type = tab->type;
FLUSH(&ret); FLUSH(&ret);
} }
// ifaceI2I(sigi *byte, iface any) (ret any); // func ifaceI2E(typ *byte, iface any) (ret any)
// called only for implicit (no type assertion) conversions. #pragma textflag 7
// converting nil is okay.
void void
·ifaceI2I(InterfaceType *inter, Iface i, Iface ret) ·assertI2E(InterfaceType* inter, Iface i, Eface ret)
{ {
Itab *tab; Itab *tab;
Eface err;
tab = i.tab; tab = i.tab;
if(tab == nil) { if(tab == nil) {
// If incoming interface is uninitialized (zeroed) // explicit conversions require non-nil interface value.
// make the outgoing interface zeroed as well. ·newTypeAssertionError(nil, nil, inter,
ret.tab = nil; nil, nil, inter->string,
ret.data = nil; 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 { } else {
ret = i; ret.type = tab->type;
if(tab->inter != inter) ok = 1;
ret.tab = itab(inter, tab->type, 0);
} }
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); FLUSH(&ret);
} }
// ifaceI2Ix(sigi *byte, iface any) (ret any);
// called only for explicit conversions (with type assertion).
// converting nil is not okay.
void void
·ifaceI2Ix(InterfaceType *inter, Iface i, Iface ret) ifaceI2I(InterfaceType *inter, Iface i, Iface *ret)
{ {
Itab *tab; Itab *tab;
Eface err; Eface err;
...@@ -362,45 +393,40 @@ void ...@@ -362,45 +393,40 @@ void
nil, nil, inter->string, nil, nil, inter->string,
nil, &err); nil, &err);
·panic(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 void
·ifaceI2I2(InterfaceType *inter, Iface i, Iface ret, bool ok) ·assertI2I2(InterfaceType *inter, Iface i, Iface ret, bool ok)
{ {
Itab *tab; Itab *tab;
tab = i.tab; tab = i.tab;
if(tab == nil) { if(tab != nil && (tab->inter == inter || (tab = itab(inter, tab->type, 1)) != nil)) {
// If incoming interface is nil, the conversion fails. ret.data = i.data;
ret.tab = nil; ret.tab = tab;
ret.data = nil; ok = 1;
ok = false;
} else { } else {
ret = i; ret.data = 0;
ok = true; ret.tab = 0;
if(tab->inter != inter) { ok = 0;
ret.tab = itab(inter, tab->type, 1);
if(ret.tab == nil) {
ret.data = nil;
ok = false;
}
} }
}
FLUSH(&ret); FLUSH(&ret);
FLUSH(&ok); FLUSH(&ok);
} }
// ifaceE2I(sigi *byte, iface any) (ret any);
// Called only for explicit conversions (with type assertion).
void void
ifaceE2I(InterfaceType *inter, Eface e, Iface *ret) ifaceE2I(InterfaceType *inter, Eface e, Iface *ret)
{ {
...@@ -414,41 +440,67 @@ ifaceE2I(InterfaceType *inter, Eface e, Iface *ret) ...@@ -414,41 +440,67 @@ ifaceE2I(InterfaceType *inter, Eface e, Iface *ret)
nil, nil, inter->string, nil, nil, inter->string,
nil, &err); nil, &err);
·panic(err); ·panic(err);
} else { }
ret->data = e.data; ret->data = e.data;
ret->tab = itab(inter, t, 0); ret->tab = itab(inter, t, 0);
}
} }
// ifaceE2I(sigi *byte, iface any) (ret any); // func ifaceE2I(sigi *byte, iface any) (ret any)
// Called only for explicit conversions (with type assertion). #pragma textflag 7
void void
·ifaceE2I(InterfaceType *inter, Eface e, Iface ret) ·assertE2I(InterfaceType* inter, Eface e, Iface ret)
{ {
ifaceE2I(inter, e, &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 void
·ifaceE2I2(InterfaceType *inter, Eface e, Iface ret, bool ok) ·assertE2I2(InterfaceType *inter, Eface e, Iface ret, bool ok)
{ {
Type *t; if(e.type == nil) {
ok = 0;
t = e.type;
ok = true;
if(t == nil) {
// If incoming interface is nil, the conversion fails.
ret.data = nil; ret.data = nil;
ret.tab = nil; ret.tab = nil;
ok = false; } else if((ret.tab = itab(inter, e.type, 1)) == nil) {
ok = 0;
ret.data = nil;
} else { } else {
ok = 1;
ret.data = e.data; 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(&ret);
FLUSH(&ok); 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) ...@@ -18,8 +18,9 @@ var f2 = []int(e)
var g = []int(nil) var g = []int(nil)
type H *[4]int type H []int
type J []int type J []int
var h H var h H
var j1 J = h // ERROR "compat|illegal|cannot|cannot" var j1 J = h // ERROR "compat|illegal|cannot"
var j2 = J(h) var j2 = J(h)
...@@ -34,14 +34,14 @@ func (t1) M(p1.T) {} ...@@ -34,14 +34,14 @@ func (t1) M(p1.T) {}
var i0 I0 = t0(0) // ok var i0 I0 = t0(0) // ok
var i1 I1 = t1(0) // ok var i1 I1 = t1(0) // ok
var i2 I0 = t1(0) // ERROR "is not|incompatible" var i2 I0 = t1(0) // ERROR "does not implement|incompatible"
var i3 I1 = t0(0) // ERROR "is not|incompatible" var i3 I1 = t0(0) // ERROR "does not implement|incompatible"
var p0i p0.I = t0(0) // ok var p0i p0.I = t0(0) // ok
var p1i p1.I = t1(0) // ok var p1i p1.I = t1(0) // ok
var p0i1 p0.I = t1(0) // ERROR "is not|incompatible" var p0i1 p0.I = t1(0) // ERROR "does not implement|incompatible"
var p0i2 p1.I = t0(0) // ERROR "is not|incompatible" var p0i2 p1.I = t0(0) // ERROR "does not implement|incompatible"
func main() { func main() {
// check that cannot assign one to the other, // check that cannot assign one to the other,
...@@ -52,14 +52,14 @@ func main() { ...@@ -52,14 +52,14 @@ func main() {
v0 = p0.T(v1) v0 = p0.T(v1)
v1 = p1.T(v0) v1 = p1.T(v0)
i0 = i1 // ERROR "need type assertion|incompatible" i0 = i1 // ERROR "cannot use|incompatible"
i1 = i0 // ERROR "need type assertion|incompatible" i1 = i0 // ERROR "cannot use|incompatible"
p0i = i1 // ERROR "need type assertion|incompatible" p0i = i1 // ERROR "cannot use|incompatible"
p1i = i0 // ERROR "need type assertion|incompatible" p1i = i0 // ERROR "cannot use|incompatible"
i0 = p1i // ERROR "need type assertion|incompatible" i0 = p1i // ERROR "cannot use|incompatible"
i1 = p0i // ERROR "need type assertion|incompatible" i1 = p0i // ERROR "cannot use|incompatible"
p0i = p1i // ERROR "need type assertion|incompatible" p0i = p1i // ERROR "cannot use|incompatible"
p1i = p0i // ERROR "need type assertion|incompatible" p1i = p0i // ERROR "cannot use|incompatible"
i0 = p0i i0 = p0i
p0i = i0 p0i = i0
......
...@@ -16,6 +16,6 @@ type I2 interface { ...@@ -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 i2 I2
var i2a I2 = i1 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. // Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
......
...@@ -180,58 +180,3 @@ BUG: bug260 failed ...@@ -180,58 +180,3 @@ BUG: bug260 failed
=========== bugs/bug274.go =========== bugs/bug274.go
BUG: errchk: command succeeded unexpectedly 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 @@ ...@@ -8,34 +8,45 @@
package main package main
type T struct { a int } type T struct {
a int
}
var t *T var t *T
type I interface { M() } type I interface {
M()
}
var i I var i I
type I2 interface { M(); N(); } type I2 interface {
M()
N()
}
var i2 I2 var i2 I2
type E interface { } type E interface{}
var e E var e E
func main() { func main() {
e = t; // ok e = t // ok
t = e; // ERROR "need explicit|need type assertion" t = e // ERROR "need explicit|need type assertion"
// neither of these can work, // neither of these can work,
// because i has an extra method // because i has an extra method
// that t does not, so i cannot contain a t. // that t does not, so i cannot contain a t.
i = t; // ERROR "missing|incompatible|is not" i = t // ERROR "incompatible|missing M method"
t = i; // ERROR "missing|incompatible|is not" t = i // ERROR "incompatible|need type assertion"
i = i2; // ok i = i2 // ok
i2 = i; // ERROR "need explicit|need type assertion" i2 = i // ERROR "missing N method"
i = I(i2); // ok i = I(i2) // ok
i2 = I2(i); // ERROR "need explicit|need type assertion" i2 = I2(i) // ERROR "missing N method"
e = E(t); // ok e = E(t) // ok
t = T(e); // ERROR "need explicit|need type assertion|incompatible" t = T(e) // ERROR "need explicit|need type assertion|incompatible"
} }
...@@ -9,28 +9,28 @@ ...@@ -9,28 +9,28 @@
package main package main
type Inst interface { type Inst interface {
Next() *Inst; Next() *Inst
} }
type Regexp struct { type Regexp struct {
code []Inst; code []Inst
start Inst; start Inst
} }
type Start struct { type Start struct {
foo *Inst; foo *Inst
} }
func (start *Start) Next() *Inst { return nil } func (start *Start) Next() *Inst { return nil }
func AddInst(Inst) *Inst { func AddInst(Inst) *Inst {
print("ok in addinst\n"); print("ok in addinst\n")
return nil return nil
} }
func main() { func main() {
print("call addinst\n"); print("call addinst\n")
var x Inst = AddInst(new(Start)); // ERROR "illegal|incompatible|is not" var x Inst = AddInst(new(Start)) // ERROR "pointer to interface"
print("return from addinst\n"); print("return from addinst\n")
} }
...@@ -9,41 +9,50 @@ ...@@ -9,41 +9,50 @@
package main package main
type T int type T int
func (t T) V() func (t T) V()
func (t *T) P() func (t *T) P()
type V interface { V() } type V interface {
type P interface { P(); V() } V()
}
type P interface {
P()
V()
}
type S struct { T; } type S struct {
type SP struct { *T; } T
}
type SP struct {
*T
}
func main() { func main() {
var t T; var t T
var v V; var v V
var p P; var p P
var s S; var s S
var sp SP; var sp SP
v = t; v = t
p = t; // ERROR "is not|requires a pointer" p = t // ERROR "does not implement|requires a pointer"
_, _= v, p; _, _ = v, p
v = &t; v = &t
p = &t; p = &t
_, _= v, p; _, _ = v, p
v = s; v = s
p = s; // ERROR "is not|requires a pointer" p = s // ERROR "does not implement|requires a pointer"
_, _= v, p; _, _ = v, p
v = &s; v = &s
p = &s; p = &s
_, _= v, p; _, _ = v, p
v = sp; v = sp
p = sp; // no error! p = sp // no error!
_, _= v, p; _, _ = v, p
v = &sp; v = &sp
p = &sp; p = &sp
_, _= v, p; _, _ = v, p
} }
...@@ -46,236 +46,236 @@ func isString(x interface{}) { _ = x.(String) } ...@@ -46,236 +46,236 @@ func isString(x interface{}) { _ = x.(String) }
func main() { func main() {
var ( var (
a Array; a Array
b Bool = true; b Bool = true
c Chan = make(Chan); c Chan = make(Chan)
f Float = 1; f Float = 1
i Int = 1; i Int = 1
m Map = make(Map); m Map = make(Map)
slice Slice = make(Slice, 10); slice Slice = make(Slice, 10)
str String = "hello"; str String = "hello"
) )
asArray(a); asArray(a)
isArray(a); isArray(a)
asArray(*&a); asArray(*&a)
isArray(*&a); isArray(*&a)
asArray(Array{}); asArray(Array{})
isArray(Array{}); isArray(Array{})
asBool(b); asBool(b)
isBool(b); isBool(b)
asBool(!b); asBool(!b)
isBool(!b); isBool(!b)
asBool(true); asBool(true)
asBool(*&b); asBool(*&b)
isBool(*&b); isBool(*&b)
asBool(Bool(true)); asBool(Bool(true))
isBool(Bool(true)); isBool(Bool(true))
asChan(c); asChan(c)
isChan(c); isChan(c)
asChan(make(Chan)); asChan(make(Chan))
isChan(make(Chan)); isChan(make(Chan))
asChan(*&c); asChan(*&c)
isChan(*&c); isChan(*&c)
asChan(Chan(nil)); asChan(Chan(nil))
isChan(Chan(nil)); isChan(Chan(nil))
asFloat(f); asFloat(f)
isFloat(f); isFloat(f)
asFloat(-f); asFloat(-f)
isFloat(-f); isFloat(-f)
asFloat(+f); asFloat(+f)
isFloat(+f); isFloat(+f)
asFloat(f+1); asFloat(f + 1)
isFloat(f+1); isFloat(f + 1)
asFloat(1+f); asFloat(1 + f)
isFloat(1+f); isFloat(1 + f)
asFloat(f+f); asFloat(f + f)
isFloat(f+f); isFloat(f + f)
f++; f++
f+=2; f += 2
asFloat(f-1); asFloat(f - 1)
isFloat(f-1); isFloat(f - 1)
asFloat(1-f); asFloat(1 - f)
isFloat(1-f); isFloat(1 - f)
asFloat(f-f); asFloat(f - f)
isFloat(f-f); isFloat(f - f)
f--; f--
f-=2; f -= 2
asFloat(f*2.5); asFloat(f * 2.5)
isFloat(f*2.5); isFloat(f * 2.5)
asFloat(2.5*f); asFloat(2.5 * f)
isFloat(2.5*f); isFloat(2.5 * f)
asFloat(f*f); asFloat(f * f)
isFloat(f*f); isFloat(f * f)
f*=4; f *= 4
asFloat(f/2.5); asFloat(f / 2.5)
isFloat(f/2.5); isFloat(f / 2.5)
asFloat(2.5/f); asFloat(2.5 / f)
isFloat(2.5/f); isFloat(2.5 / f)
asFloat(f/f); asFloat(f / f)
isFloat(f/f); isFloat(f / f)
f/=4; f /= 4
asFloat(f); asFloat(f)
isFloat(f); isFloat(f)
f = 5; f = 5
asFloat(*&f); asFloat(*&f)
isFloat(*&f); isFloat(*&f)
asFloat(234); asFloat(234)
asFloat(Float(234)); asFloat(Float(234))
isFloat(Float(234)); isFloat(Float(234))
asFloat(1.2); asFloat(1.2)
asFloat(Float(i)); asFloat(Float(i))
isFloat(Float(i)); isFloat(Float(i))
asInt(i); asInt(i)
isInt(i); isInt(i)
asInt(-i); asInt(-i)
isInt(-i); isInt(-i)
asInt(^i); asInt(^i)
isInt(^i); isInt(^i)
asInt(+i); asInt(+i)
isInt(+i); isInt(+i)
asInt(i+1); asInt(i + 1)
isInt(i+1); isInt(i + 1)
asInt(1+i); asInt(1 + i)
isInt(1+i); isInt(1 + i)
asInt(i+i); asInt(i + i)
isInt(i+i); isInt(i + i)
i++; i++
i+=1; i += 1
asInt(i-1); asInt(i - 1)
isInt(i-1); isInt(i - 1)
asInt(1-i); asInt(1 - i)
isInt(1-i); isInt(1 - i)
asInt(i-i); asInt(i - i)
isInt(i-i); isInt(i - i)
i--; i--
i-=1; i -= 1
asInt(i*2); asInt(i * 2)
isInt(i*2); isInt(i * 2)
asInt(2*i); asInt(2 * i)
isInt(2*i); isInt(2 * i)
asInt(i*i); asInt(i * i)
isInt(i*i); isInt(i * i)
i*=2; i *= 2
asInt(i/5); asInt(i / 5)
isInt(i/5); isInt(i / 5)
asInt(5/i); asInt(5 / i)
isInt(5/i); isInt(5 / i)
asInt(i/i); asInt(i / i)
isInt(i/i); isInt(i / i)
i/=2; i /= 2
asInt(i%5); asInt(i % 5)
isInt(i%5); isInt(i % 5)
asInt(5%i); asInt(5 % i)
isInt(5%i); isInt(5 % i)
asInt(i%i); asInt(i % i)
isInt(i%i); isInt(i % i)
i%=2; i %= 2
asInt(i&5); asInt(i & 5)
isInt(i&5); isInt(i & 5)
asInt(5&i); asInt(5 & i)
isInt(5&i); isInt(5 & i)
asInt(i&i); asInt(i & i)
isInt(i&i); isInt(i & i)
i&=2; i &= 2
asInt(i&^5); asInt(i &^ 5)
isInt(i&^5); isInt(i &^ 5)
asInt(5&^i); asInt(5 &^ i)
isInt(5&^i); isInt(5 &^ i)
asInt(i&^i); asInt(i &^ i)
isInt(i&^i); isInt(i &^ i)
i&^=2; i &^= 2
asInt(i|5); asInt(i | 5)
isInt(i|5); isInt(i | 5)
asInt(5|i); asInt(5 | i)
isInt(5|i); isInt(5 | i)
asInt(i|i); asInt(i | i)
isInt(i|i); isInt(i | i)
i|=2; i |= 2
asInt(i^5); asInt(i ^ 5)
isInt(i^5); isInt(i ^ 5)
asInt(5^i); asInt(5 ^ i)
isInt(5^i); isInt(5 ^ i)
asInt(i^i); asInt(i ^ i)
isInt(i^i); isInt(i ^ i)
i^=2; i ^= 2
asInt(i<<4); asInt(i << 4)
isInt(i<<4); isInt(i << 4)
i<<=2; i <<= 2
asInt(i>>4); asInt(i >> 4)
isInt(i>>4); isInt(i >> 4)
i>>=2; i >>= 2
asInt(i); asInt(i)
isInt(i); isInt(i)
asInt(0); asInt(0)
asInt(Int(0)); asInt(Int(0))
isInt(Int(0)); isInt(Int(0))
i = 10; i = 10
asInt(*&i); asInt(*&i)
isInt(*&i); isInt(*&i)
asInt(23); asInt(23)
asInt(Int(f)); asInt(Int(f))
isInt(Int(f)); isInt(Int(f))
asMap(m); asMap(m)
isMap(m); isMap(m)
asMap(nil); asMap(nil)
m = nil; m = nil
asMap(make(Map)); asMap(make(Map))
isMap(make(Map)); isMap(make(Map))
asMap(*&m); asMap(*&m)
isMap(*&m); isMap(*&m)
asMap(Map(nil)); asMap(Map(nil))
isMap(Map(nil)); isMap(Map(nil))
asMap(Map{}); asMap(Map{})
isMap(Map{}); isMap(Map{})
asSlice(slice); asSlice(slice)
isSlice(slice); isSlice(slice)
asSlice(make(Slice, 5)); asSlice(make(Slice, 5))
isSlice(make(Slice, 5)); isSlice(make(Slice, 5))
asSlice([]byte{1,2,3}); asSlice([]byte{1, 2, 3})
asSlice([]byte{1,2,3}[0:2]); asSlice([]byte{1, 2, 3}[0:2])
asSlice(slice[0:4]); asSlice(slice[0:4])
isSlice(slice[0:4]); isSlice(slice[0:4])
asSlice(slice[3:8]); asSlice(slice[3:8])
isSlice(slice[3:8]); isSlice(slice[3:8])
asSlice(nil); asSlice(nil)
asSlice(Slice(nil)); asSlice(Slice(nil))
isSlice(Slice(nil)); isSlice(Slice(nil))
slice = nil; slice = nil
asSlice(Slice{1,2,3}); asSlice(Slice{1, 2, 3})
isSlice(Slice{1,2,3}); isSlice(Slice{1, 2, 3})
asSlice(Slice{}); asSlice(Slice{})
isSlice(Slice{}); isSlice(Slice{})
asSlice(*&slice); asSlice(*&slice)
isSlice(*&slice); isSlice(*&slice)
asString(str); asString(str)
isString(str); isString(str)
asString(str+"a"); asString(str + "a")
isString(str+"a"); isString(str + "a")
asString("a"+str); asString("a" + str)
isString("a"+str); isString("a" + str)
asString(str+str); asString(str + str)
isString(str+str); isString(str + str)
str += "a"; str += "a"
str += str; str += str
asString(String('a')); asString(String('a'))
isString(String('a')); isString(String('a'))
asString(String(slice)); asString(String([]byte(slice)))
isString(String(slice)); isString(String([]byte(slice)))
asString(String([]byte(nil))); asString(String([]byte(nil)))
isString(String([]byte(nil))); isString(String([]byte(nil)))
asString("hello"); asString("hello")
asString(String("hello")); asString(String("hello"))
isString(String("hello")); isString(String("hello"))
str = "hello"; str = "hello"
isString(str); isString(str)
asString(*&str); asString(*&str)
isString(*&str); isString(*&str)
} }
...@@ -12,46 +12,57 @@ package main ...@@ -12,46 +12,57 @@ package main
type Bool bool type Bool bool
type Map map[int]int type Map map[int]int
func (Map) M() {} func (Map) M() {}
type Slice []byte
var slice Slice
func asBool(Bool) {} func asBool(Bool) {}
func asString(String) {}
type String string
func main() { func main() {
var ( var (
b Bool = true; b Bool = true
i, j int; i, j int
c = make(chan int); c = make(chan int)
m = make(Map); m = make(Map)
) )
asBool(b); asBool(b)
asBool(!b); asBool(!b)
asBool(true); asBool(true)
asBool(*&b); asBool(*&b)
asBool(Bool(true)); asBool(Bool(true))
asBool(1!=2); // ERROR "cannot use.*type bool.*as type Bool" asBool(1 != 2) // ERROR "cannot use.*type bool.*as type Bool"
asBool(i < j); // 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" _, b = m[2] // ERROR "cannot .* bool.*type Bool"
m[2] = 1, b; // ERROR "cannot use.*type Bool.*as 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 = c <- 1 // ERROR "cannot use.*type bool.*type Bool"
_ = b; _ = b
asBool(c<-1); // ERROR "cannot use.*type bool.*as type Bool" asBool(c <- 1) // ERROR "cannot use.*type bool.*as type Bool"
_, b = <-c; // ERROR "cannot .* bool.*type Bool" _, b = <-c // ERROR "cannot .* bool.*type Bool"
_ = b; _ = b
var inter interface{}; var inter interface{}
_, b = inter.(Map); // ERROR "cannot .* bool.*type Bool" _, b = inter.(Map) // ERROR "cannot .* bool.*type Bool"
_ = b; _ = b
var minter interface{M()}; var minter interface {
_, b = minter.(Map); // ERROR "cannot .* bool.*type Bool" M()
_ = b; }
_, b = minter.(Map) // ERROR "cannot .* bool.*type Bool"
_ = b
asBool(closed(c)); // ERROR "cannot use.*type bool.*as type Bool" asBool(closed(c)) // ERROR "cannot use.*type bool.*as type Bool"
b = closed(c); // ERROR "cannot use.*type bool.*type Bool" b = closed(c) // ERROR "cannot use.*type bool.*type Bool"
_ = b; _ = 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