mirror of
https://github.com/golang/go
synced 2024-11-21 13:24:40 -07:00
gc: clearer error for struct == struct
cmp6.go:48: invalid operation: t3 == t3 (operator == not defined on struct) Fixes #1438. R=ken2 CC=golang-dev https://golang.org/cl/4003045
This commit is contained in:
parent
9e441e5215
commit
7e84666df1
@ -56,6 +56,34 @@ typechecklist(NodeList *l, int top)
|
||||
typecheck(&l->n, top);
|
||||
}
|
||||
|
||||
static char* typekind[] = {
|
||||
[TINT] = "int",
|
||||
[TUINT] = "uint",
|
||||
[TINT8] = "int8",
|
||||
[TUINT8] = "uint8",
|
||||
[TINT16] = "int16",
|
||||
[TUINT16] = "uint16",
|
||||
[TINT32] = "int32",
|
||||
[TUINT32] = "uint32",
|
||||
[TINT64] = "int64",
|
||||
[TUINT64] = "uint64",
|
||||
[TUINTPTR] = "uintptr",
|
||||
[TCOMPLEX64] = "complex64",
|
||||
[TCOMPLEX128] = "complex128",
|
||||
[TFLOAT32] = "float32",
|
||||
[TFLOAT64] = "float64",
|
||||
[TBOOL] = "bool",
|
||||
[TSTRING] = "string",
|
||||
[TPTR32] = "pointer",
|
||||
[TPTR64] = "pointer",
|
||||
[TSTRUCT] = "struct",
|
||||
[TINTER] = "interface",
|
||||
[TCHAN] = "chan",
|
||||
[TMAP] = "map",
|
||||
[TARRAY] = "array",
|
||||
[TFUNC] = "func",
|
||||
};
|
||||
|
||||
/*
|
||||
* type check node *np.
|
||||
* replaces *np with a new pointer in some cases.
|
||||
@ -372,21 +400,25 @@ reswitch:
|
||||
et = t->etype;
|
||||
}
|
||||
if(t->etype != TIDEAL && !eqtype(l->type, r->type)) {
|
||||
badbinary:
|
||||
defaultlit2(&l, &r, 1);
|
||||
yyerror("invalid operation: %#N (type %T %#O %T)", n, l->type, op, r->type);
|
||||
yyerror("invalid operation: %#N (mismatched types %T and %T)", n, l->type, r->type);
|
||||
goto error;
|
||||
}
|
||||
if(!okfor[op][et]) {
|
||||
notokfor:
|
||||
yyerror("invalid operation: %#N (operator %#O not defined on %s)", n, op, typekind[et]);
|
||||
goto error;
|
||||
}
|
||||
if(!okfor[op][et])
|
||||
goto badbinary;
|
||||
// okfor allows any array == array;
|
||||
// restrict to slice == nil and nil == slice.
|
||||
if(l->type->etype == TARRAY && !isslice(l->type))
|
||||
goto badbinary;
|
||||
goto notokfor;
|
||||
if(r->type->etype == TARRAY && !isslice(r->type))
|
||||
goto badbinary;
|
||||
if(isslice(l->type) && !isnil(l) && !isnil(r))
|
||||
goto badbinary;
|
||||
goto notokfor;
|
||||
if(isslice(l->type) && !isnil(l) && !isnil(r)) {
|
||||
yyerror("invalid operation: %#N (slice can only be compared to nil)", n);
|
||||
goto error;
|
||||
}
|
||||
t = l->type;
|
||||
if(iscmp[n->op]) {
|
||||
evconst(n);
|
||||
|
@ -11,6 +11,10 @@ func use(bool) {}
|
||||
type T1 *int
|
||||
type T2 *int
|
||||
|
||||
type T3 struct {}
|
||||
|
||||
var t3 T3
|
||||
|
||||
func main() {
|
||||
// Arguments to comparison must be
|
||||
// assignable one to the other (or vice versa)
|
||||
@ -39,4 +43,7 @@ func main() {
|
||||
use(p2 == p2)
|
||||
use(p3 == p1)
|
||||
use(p3 == p2)
|
||||
|
||||
// Comparison of structs should have a good message
|
||||
use(t3 == t3) // ERROR "struct"
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user