mirror of
https://github.com/golang/go
synced 2024-11-21 20:34:40 -07:00
write-only variable _
R=ken OCL=34465 CL=34470
This commit is contained in:
parent
c77c3b0196
commit
5438be4541
@ -48,7 +48,7 @@ compile(Node *fn)
|
|||||||
|
|
||||||
hasdefer = 0;
|
hasdefer = 0;
|
||||||
walk(curfn);
|
walk(curfn);
|
||||||
if(nerrors != 0)
|
if(nerrors != 0 || isblank(curfn->nname))
|
||||||
goto ret;
|
goto ret;
|
||||||
|
|
||||||
allocparams();
|
allocparams();
|
||||||
|
@ -49,7 +49,7 @@ compile(Node *fn)
|
|||||||
|
|
||||||
hasdefer = 0;
|
hasdefer = 0;
|
||||||
walk(curfn);
|
walk(curfn);
|
||||||
if(nerrors != 0)
|
if(nerrors != 0 || isblank(curfn->nname))
|
||||||
goto ret;
|
goto ret;
|
||||||
|
|
||||||
allocparams();
|
allocparams();
|
||||||
|
@ -47,7 +47,7 @@ compile(Node *fn)
|
|||||||
|
|
||||||
hasdefer = 0;
|
hasdefer = 0;
|
||||||
walk(curfn);
|
walk(curfn);
|
||||||
if(nerrors != 0)
|
if(nerrors != 0 || isblank(curfn->nname))
|
||||||
goto ret;
|
goto ret;
|
||||||
|
|
||||||
allocparams();
|
allocparams();
|
||||||
|
@ -139,7 +139,7 @@ dowidth(Type *t)
|
|||||||
w = 0;
|
w = 0;
|
||||||
switch(et) {
|
switch(et) {
|
||||||
default:
|
default:
|
||||||
fatal("dowidth: unknown type: %E", t->etype);
|
fatal("dowidth: unknown type: %T", t);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* compiler-specific stuff */
|
/* compiler-specific stuff */
|
||||||
|
@ -164,6 +164,9 @@ declare(Node *n, int ctxt)
|
|||||||
int gen;
|
int gen;
|
||||||
static int typegen, vargen;
|
static int typegen, vargen;
|
||||||
|
|
||||||
|
if(isblank(n))
|
||||||
|
return;
|
||||||
|
|
||||||
s = n->sym;
|
s = n->sym;
|
||||||
gen = 0;
|
gen = 0;
|
||||||
if(ctxt == PEXTERN) {
|
if(ctxt == PEXTERN) {
|
||||||
@ -301,7 +304,6 @@ variter(NodeList *vl, Node *t, NodeList *el)
|
|||||||
int doexpr;
|
int doexpr;
|
||||||
Node *v, *e;
|
Node *v, *e;
|
||||||
NodeList *init;
|
NodeList *init;
|
||||||
Sym *s;
|
|
||||||
|
|
||||||
init = nil;
|
init = nil;
|
||||||
doexpr = el != nil;
|
doexpr = el != nil;
|
||||||
@ -317,8 +319,6 @@ variter(NodeList *vl, Node *t, NodeList *el)
|
|||||||
e = N;
|
e = N;
|
||||||
|
|
||||||
v = vl->n;
|
v = vl->n;
|
||||||
s = v->sym;
|
|
||||||
|
|
||||||
v->op = ONAME;
|
v->op = ONAME;
|
||||||
declare(v, dclcontext);
|
declare(v, dclcontext);
|
||||||
v->ntype = t;
|
v->ntype = t;
|
||||||
@ -550,6 +550,8 @@ colasdefn(NodeList *left, Node *defn)
|
|||||||
nnew = 0;
|
nnew = 0;
|
||||||
for(l=left; l; l=l->next) {
|
for(l=left; l; l=l->next) {
|
||||||
n = l->n;
|
n = l->n;
|
||||||
|
if(isblank(n))
|
||||||
|
continue;
|
||||||
if(!colasname(n)) {
|
if(!colasname(n)) {
|
||||||
yyerror("non-name %#N on left side of :=", n);
|
yyerror("non-name %#N on left side of :=", n);
|
||||||
continue;
|
continue;
|
||||||
@ -838,7 +840,7 @@ stotype(NodeList *l, int et, Type **t)
|
|||||||
f->sym = f->nname->sym;
|
f->sym = f->nname->sym;
|
||||||
if(pkgimportname != S && !exportname(f->sym->name))
|
if(pkgimportname != S && !exportname(f->sym->name))
|
||||||
f->sym = pkglookup(f->sym->name, structpkg);
|
f->sym = pkglookup(f->sym->name, structpkg);
|
||||||
if(f->sym) {
|
if(f->sym && !isblank(f->nname)) {
|
||||||
for(t1=*t0; t1!=T; t1=t1->down) {
|
for(t1=*t0; t1!=T; t1=t1->down) {
|
||||||
if(t1->sym == f->sym) {
|
if(t1->sym == f->sym) {
|
||||||
yyerror("duplicate field %s", t1->sym->name);
|
yyerror("duplicate field %s", t1->sym->name);
|
||||||
@ -963,6 +965,8 @@ checkarglist(NodeList *all)
|
|||||||
t = n;
|
t = n;
|
||||||
n = N;
|
n = N;
|
||||||
}
|
}
|
||||||
|
if(isblank(n))
|
||||||
|
n = N;
|
||||||
if(n != N && n->sym == S) {
|
if(n != N && n->sym == S) {
|
||||||
t = n;
|
t = n;
|
||||||
n = N;
|
n = N;
|
||||||
|
@ -430,6 +430,60 @@ cgen_dcl(Node *n)
|
|||||||
cgen_as(n->heapaddr, n->alloc);
|
cgen_as(n->heapaddr, n->alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* generate discard of value
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
cgen_discard(Node *nr)
|
||||||
|
{
|
||||||
|
Node tmp;
|
||||||
|
|
||||||
|
if(nr == N)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch(nr->op) {
|
||||||
|
case ONAME:
|
||||||
|
break;
|
||||||
|
|
||||||
|
// unary
|
||||||
|
case OADD:
|
||||||
|
case OAND:
|
||||||
|
case ODIV:
|
||||||
|
case OEQ:
|
||||||
|
case OGE:
|
||||||
|
case OGT:
|
||||||
|
case OLE:
|
||||||
|
case OLSH:
|
||||||
|
case OLT:
|
||||||
|
case OMOD:
|
||||||
|
case OMUL:
|
||||||
|
case ONE:
|
||||||
|
case OOR:
|
||||||
|
case ORSH:
|
||||||
|
case OSUB:
|
||||||
|
case OXOR:
|
||||||
|
cgen_discard(nr->left);
|
||||||
|
cgen_discard(nr->right);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// binary
|
||||||
|
case OCAP:
|
||||||
|
case OCOM:
|
||||||
|
case OLEN:
|
||||||
|
case OMINUS:
|
||||||
|
case ONOT:
|
||||||
|
case OPLUS:
|
||||||
|
cgen_discard(nr->left);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// special enough to just evaluate
|
||||||
|
default:
|
||||||
|
tempname(&tmp, nr->type);
|
||||||
|
cgen_as(&tmp, nr);
|
||||||
|
gused(&tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* generate assignment:
|
* generate assignment:
|
||||||
* nl = nr
|
* nl = nr
|
||||||
@ -450,6 +504,11 @@ cgen_as(Node *nl, Node *nr)
|
|||||||
dump("cgen_as = ", nr);
|
dump("cgen_as = ", nr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(isblank(nl)) {
|
||||||
|
cgen_discard(nr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
iszer = 0;
|
iszer = 0;
|
||||||
if(nr == N || isnil(nr)) {
|
if(nr == N || isnil(nr)) {
|
||||||
// externals and heaps should already be clear
|
// externals and heaps should already be clear
|
||||||
|
@ -6,6 +6,10 @@
|
|||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include <bio.h>
|
#include <bio.h>
|
||||||
|
|
||||||
|
// avoid <ctype.h>
|
||||||
|
#undef isblank
|
||||||
|
#define isblank goisblank
|
||||||
|
|
||||||
#ifndef EXTERN
|
#ifndef EXTERN
|
||||||
#define EXTERN extern
|
#define EXTERN extern
|
||||||
#endif
|
#endif
|
||||||
@ -421,6 +425,7 @@ enum
|
|||||||
// pseudo-types for literals
|
// pseudo-types for literals
|
||||||
TIDEAL,
|
TIDEAL,
|
||||||
TNIL,
|
TNIL,
|
||||||
|
TBLANK,
|
||||||
|
|
||||||
NTYPE,
|
NTYPE,
|
||||||
};
|
};
|
||||||
@ -467,6 +472,7 @@ enum
|
|||||||
Ecall = 1<<4, // call-only expressions are ok
|
Ecall = 1<<4, // call-only expressions are ok
|
||||||
Efnstruct = 1<<5, // multivalue function returns are ok
|
Efnstruct = 1<<5, // multivalue function returns are ok
|
||||||
Eiota = 1<<6, // iota is ok
|
Eiota = 1<<6, // iota is ok
|
||||||
|
Easgn = 1<<7, // assigning to expression
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BITS 5
|
#define BITS 5
|
||||||
@ -803,6 +809,7 @@ int isinter(Type*);
|
|||||||
int isnilinter(Type*);
|
int isnilinter(Type*);
|
||||||
int isddd(Type*);
|
int isddd(Type*);
|
||||||
int isideal(Type*);
|
int isideal(Type*);
|
||||||
|
int isblank(Node*);
|
||||||
Type* maptype(Type*, Type*);
|
Type* maptype(Type*, Type*);
|
||||||
Type* methtype(Type*);
|
Type* methtype(Type*);
|
||||||
Node* typename(Type*);
|
Node* typename(Type*);
|
||||||
|
@ -1352,6 +1352,13 @@ lexinit(void)
|
|||||||
// (the type of x in const x = "hello").
|
// (the type of x in const x = "hello").
|
||||||
// TODO(rsc): this may need some more thought.
|
// TODO(rsc): this may need some more thought.
|
||||||
idealstring = typ(TSTRING);
|
idealstring = typ(TSTRING);
|
||||||
|
|
||||||
|
s = lookup("_");
|
||||||
|
s->block = -100;
|
||||||
|
s->def = nod(ONAME, N, N);
|
||||||
|
s->def->sym = s;
|
||||||
|
types[TBLANK] = typ(TBLANK);
|
||||||
|
s->def->type = types[TBLANK];
|
||||||
}
|
}
|
||||||
|
|
||||||
struct
|
struct
|
||||||
@ -1431,6 +1438,9 @@ mkpackage(char* pkg)
|
|||||||
int32 h;
|
int32 h;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
|
if(strcmp(pkg, "_") == 0)
|
||||||
|
yyerror("invalid package name _");
|
||||||
|
|
||||||
if(package == nopackage) {
|
if(package == nopackage) {
|
||||||
// redefine all names to be this package.
|
// redefine all names to be this package.
|
||||||
for(h=0; h<NHASH; h++)
|
for(h=0; h<NHASH; h++)
|
||||||
|
@ -19,7 +19,7 @@ typecheckrange(Node *n)
|
|||||||
// delicate little dance. see typecheckas2
|
// delicate little dance. see typecheckas2
|
||||||
for(ll=n->list; ll; ll=ll->next)
|
for(ll=n->list; ll; ll=ll->next)
|
||||||
if(ll->n->defn != n)
|
if(ll->n->defn != n)
|
||||||
typecheck(&ll->n, Erv);
|
typecheck(&ll->n, Erv | Easgn);
|
||||||
|
|
||||||
typecheck(&n->right, Erv);
|
typecheck(&n->right, Erv);
|
||||||
if((t = n->right->type) == T)
|
if((t = n->right->type) == T)
|
||||||
@ -121,7 +121,7 @@ walkrange(Node *n)
|
|||||||
|
|
||||||
case TARRAY:
|
case TARRAY:
|
||||||
hv1 = nod(OXXX, N, n);
|
hv1 = nod(OXXX, N, n);
|
||||||
tempname(hv1, v1->type);
|
tempname(hv1, types[TINT]);
|
||||||
|
|
||||||
init = list(init, nod(OAS, hv1, N));
|
init = list(init, nod(OAS, hv1, N));
|
||||||
n->ntest = nod(OLT, hv1, nod(OLEN, ha, N));
|
n->ntest = nod(OLT, hv1, nod(OLEN, ha, N));
|
||||||
@ -169,7 +169,7 @@ walkrange(Node *n)
|
|||||||
|
|
||||||
case TCHAN:
|
case TCHAN:
|
||||||
hv1 = nod(OXXX, N, n);
|
hv1 = nod(OXXX, N, n);
|
||||||
tempname(hv1, v1->type);
|
tempname(hv1, t->type);
|
||||||
|
|
||||||
n->ntest = nod(ONOT, nod(OCLOSED, ha, N), N);
|
n->ntest = nod(ONOT, nod(OCLOSED, ha, N), N);
|
||||||
n->ntest->ninit = list1(nod(OAS, hv1, nod(ORECV, ha, N)));
|
n->ntest->ninit = list1(nod(OAS, hv1, nod(ORECV, ha, N)));
|
||||||
|
@ -953,6 +953,7 @@ basicnames[] =
|
|||||||
[TSTRING] = "string",
|
[TSTRING] = "string",
|
||||||
[TNIL] = "nil",
|
[TNIL] = "nil",
|
||||||
[TIDEAL] = "ideal",
|
[TIDEAL] = "ideal",
|
||||||
|
[TBLANK] = "blank",
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -1421,6 +1422,19 @@ isslice(Type *t)
|
|||||||
return t != T && t->etype == TARRAY && t->bound < 0;
|
return t != T && t->etype == TARRAY && t->bound < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
isblank(Node *n)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if(n == N || n->sym == S)
|
||||||
|
return 0;
|
||||||
|
p = n->sym->name;
|
||||||
|
if(p == nil)
|
||||||
|
return 0;
|
||||||
|
return p[0] == '_' && p[1] == '\0';
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
isselect(Node *n)
|
isselect(Node *n)
|
||||||
{
|
{
|
||||||
|
@ -61,7 +61,10 @@ typecheck(Node **np, int top)
|
|||||||
n = *np;
|
n = *np;
|
||||||
if(n == N)
|
if(n == N)
|
||||||
return N;
|
return N;
|
||||||
if(n->typecheck == 1 && n->op != ONAME) // XXX for test/func4.go
|
|
||||||
|
// Skip typecheck if already done.
|
||||||
|
// But re-typecheck ONAME node in case context has changed.
|
||||||
|
if(n->typecheck == 1 && n->op != ONAME)
|
||||||
return n;
|
return n;
|
||||||
if(n->typecheck == 2)
|
if(n->typecheck == 2)
|
||||||
fatal("typecheck loop");
|
fatal("typecheck loop");
|
||||||
@ -85,8 +88,10 @@ reswitch:
|
|||||||
*/
|
*/
|
||||||
case OLITERAL:
|
case OLITERAL:
|
||||||
ok |= Erv;
|
ok |= Erv;
|
||||||
if(n->iota && !(top & Eiota))
|
if(n->iota && !(top & Eiota)) {
|
||||||
yyerror("use of iota not in constant initializer");
|
yyerror("use of iota not in constant initializer");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
if(n->val.ctype == CTSTR)
|
if(n->val.ctype == CTSTR)
|
||||||
n->type = idealstring;
|
n->type = idealstring;
|
||||||
goto ret;
|
goto ret;
|
||||||
@ -100,6 +105,10 @@ reswitch:
|
|||||||
ok |= Ecall;
|
ok |= Ecall;
|
||||||
goto ret;
|
goto ret;
|
||||||
}
|
}
|
||||||
|
if(isblank(n) && !(top & Easgn)) {
|
||||||
|
yyerror("cannot use _ as value");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
ok |= Erv;
|
ok |= Erv;
|
||||||
goto ret;
|
goto ret;
|
||||||
|
|
||||||
@ -581,7 +590,7 @@ reswitch:
|
|||||||
}
|
}
|
||||||
yyerror("cannot slice %#N (type %T)", l, t);
|
yyerror("cannot slice %#N (type %T)", l, t);
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call and call like
|
* call and call like
|
||||||
*/
|
*/
|
||||||
@ -970,6 +979,7 @@ ret:
|
|||||||
case TFORW:
|
case TFORW:
|
||||||
case TIDEAL:
|
case TIDEAL:
|
||||||
case TNIL:
|
case TNIL:
|
||||||
|
case TBLANK:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
checkwidth(t);
|
checkwidth(t);
|
||||||
@ -1165,6 +1175,11 @@ checkconv(Type *nt, Type *t, int explicit, int *op, int *et)
|
|||||||
*/
|
*/
|
||||||
if(nt == T)
|
if(nt == T)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if(t->etype == TBLANK) {
|
||||||
|
*op = OCONVNOP;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if(eqtype(t, nt)) {
|
if(eqtype(t, nt)) {
|
||||||
exportassignok(t);
|
exportassignok(t);
|
||||||
@ -1804,7 +1819,7 @@ typecheckas(Node *n)
|
|||||||
// will not look at defn, so it is okay (and desirable,
|
// will not look at defn, so it is okay (and desirable,
|
||||||
// so that the conversion below happens).
|
// so that the conversion below happens).
|
||||||
if(n->left->defn != n || n->left->ntype)
|
if(n->left->defn != n || n->left->ntype)
|
||||||
typecheck(&n->left, Erv);
|
typecheck(&n->left, Erv | Easgn);
|
||||||
|
|
||||||
checkassign(n->left);
|
checkassign(n->left);
|
||||||
typecheck(&n->right, Erv);
|
typecheck(&n->right, Erv);
|
||||||
@ -1820,7 +1835,7 @@ typecheckas(Node *n)
|
|||||||
// just to get it over with. see dance above.
|
// just to get it over with. see dance above.
|
||||||
n->typecheck = 1;
|
n->typecheck = 1;
|
||||||
if(n->left->typecheck == 0)
|
if(n->left->typecheck == 0)
|
||||||
typecheck(&n->left, Erv);
|
typecheck(&n->left, Erv | Easgn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1835,7 +1850,7 @@ typecheckas2(Node *n)
|
|||||||
for(ll=n->list; ll; ll=ll->next) {
|
for(ll=n->list; ll; ll=ll->next) {
|
||||||
// delicate little dance.
|
// delicate little dance.
|
||||||
if(ll->n->defn != n || ll->n->ntype)
|
if(ll->n->defn != n || ll->n->ntype)
|
||||||
typecheck(&ll->n, Erv);
|
typecheck(&ll->n, Erv | Easgn);
|
||||||
}
|
}
|
||||||
cl = count(n->list);
|
cl = count(n->list);
|
||||||
cr = count(n->rlist);
|
cr = count(n->rlist);
|
||||||
@ -1946,7 +1961,7 @@ typecheckfunc(Node *n)
|
|||||||
{
|
{
|
||||||
Type *t, *rcvr;
|
Type *t, *rcvr;
|
||||||
|
|
||||||
typecheck(&n->nname, Erv);
|
typecheck(&n->nname, Erv | Easgn);
|
||||||
if((t = n->nname->type) == T)
|
if((t = n->nname->type) == T)
|
||||||
return;
|
return;
|
||||||
n->type = t;
|
n->type = t;
|
||||||
|
@ -1103,7 +1103,7 @@ ascompatee(int op, NodeList *nl, NodeList *nr, NodeList **init)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* n is an lv and t is the type of an rv
|
* l is an lv and rt is the type of an rv
|
||||||
* return 1 if this implies a function call
|
* return 1 if this implies a function call
|
||||||
* evaluating the lv or a function call
|
* evaluating the lv or a function call
|
||||||
* in the conversion of the types
|
* in the conversion of the types
|
||||||
@ -1141,6 +1141,10 @@ ascompatet(int op, NodeList *nl, Type **nr, int fp, NodeList **init)
|
|||||||
if(r == T)
|
if(r == T)
|
||||||
break;
|
break;
|
||||||
l = ll->n;
|
l = ll->n;
|
||||||
|
if(isblank(l)) {
|
||||||
|
r = structnext(&saver);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// any lv that causes a fn call must be
|
// any lv that causes a fn call must be
|
||||||
// deferred until all the return arguments
|
// deferred until all the return arguments
|
||||||
|
90
test/blank.go
Normal file
90
test/blank.go
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
// $G $D/$F.go && $L $F.$A && ./$A.out
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
var call string
|
||||||
|
|
||||||
|
type T struct {
|
||||||
|
_, _, _ int;
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
c0 = iota;
|
||||||
|
_;
|
||||||
|
_;
|
||||||
|
_;
|
||||||
|
c4;
|
||||||
|
)
|
||||||
|
|
||||||
|
var ints = []string {
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"3"
|
||||||
|
}
|
||||||
|
|
||||||
|
func f() (int, int) {
|
||||||
|
call += "f";
|
||||||
|
return 1,2
|
||||||
|
}
|
||||||
|
|
||||||
|
func g() (float, float) {
|
||||||
|
call += "g";
|
||||||
|
return 3,4
|
||||||
|
}
|
||||||
|
|
||||||
|
func h(_ int, _ float) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func i() int {
|
||||||
|
call += "i";
|
||||||
|
return 23;
|
||||||
|
}
|
||||||
|
|
||||||
|
func main()
|
||||||
|
{
|
||||||
|
_, _ = f();
|
||||||
|
a, _ := f();
|
||||||
|
if a != 1 {panic(a)}
|
||||||
|
b, _ := g();
|
||||||
|
if b != 3 {panic(b)}
|
||||||
|
_, a = f();
|
||||||
|
if a != 2 {panic(a)}
|
||||||
|
_, b = g();
|
||||||
|
if b != 4 {panic(b)}
|
||||||
|
_ = i();
|
||||||
|
if call != "ffgfgi" {panic(call)}
|
||||||
|
if c4 != 4 {panic(c4)}
|
||||||
|
|
||||||
|
out := "";
|
||||||
|
for _, s := range ints {
|
||||||
|
out += s;
|
||||||
|
}
|
||||||
|
if out != "123" {panic(out)}
|
||||||
|
|
||||||
|
sum := 0;
|
||||||
|
for s, _ := range ints {
|
||||||
|
sum += s;
|
||||||
|
}
|
||||||
|
if sum != 3 {panic(sum)}
|
||||||
|
|
||||||
|
h(a,b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// useless but legal
|
||||||
|
var _ int = 1;
|
||||||
|
var _ = 2;
|
||||||
|
var _, _ = 3, 4;
|
||||||
|
const _ = 3;
|
||||||
|
const _, _ = 4, 5;
|
||||||
|
type _ int;
|
||||||
|
func _() {
|
||||||
|
panic("oops")
|
||||||
|
}
|
||||||
|
|
||||||
|
func ff() {
|
||||||
|
var _ int = 1;
|
||||||
|
}
|
12
test/blank1.go
Normal file
12
test/blank1.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// 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 _ // ERROR "invalid package name _"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
_(); // ERROR "cannot use _ as value"
|
||||||
|
x := _+1; // ERROR "cannot use _ as value"
|
||||||
|
}
|
@ -16,7 +16,7 @@ func f0() string {
|
|||||||
|
|
||||||
func f1() string {
|
func f1() string {
|
||||||
const f = 3.141592;
|
const f = 3.141592;
|
||||||
_ := float64(float32(f)); // appears to change the precision of f
|
x := float64(float32(f)); // appears to change the precision of f
|
||||||
return fmt.Sprintf("%v", float64(f));
|
return fmt.Sprintf("%v", float64(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user