6g: error messages

replace "shape error across CALL" with more information.

x.go:7: not enough arguments to CALL
	a int, b int
	int
x.go:10: assignment count mismatch: 3 = 2
x.go:12: too many arguments to RETURN
	[no arguments expected]
	int, int, int

also leave type alone after conversion failure,
for later errors:

bug049.go:6: cannot convert nil constant to string
bug049.go:6: illegal types for operand: EQ
	string
	nil		# this used to be blank

R=ken
OCL=28405
CL=28407
This commit is contained in:
Russ Cox 2009-05-07 10:29:35 -07:00
parent 5a67ea3883
commit b5e212ffdd
3 changed files with 66 additions and 6 deletions

View file

@ -156,7 +156,6 @@ bad:
if(n->type->etype == TIDEAL)
defaultlit(n, T);
yyerror("cannot convert %T constant to %T", n->type, t);
n->type = T;
n->diag = 1;
return;
}

View file

@ -454,7 +454,8 @@ loop:
if(cr == 1) {
// a,b,... = fn()
walktype(r, Erv);
convlit(r, types[TFUNC]);
if(r->type == T || r->type->etype != TSTRUCT)
break;
l = ascompatet(n->op, &n->left, &r->type, 0);
if(l != N)
indir(n, list(r, reorder2(l)));
@ -1697,6 +1698,7 @@ ascompatee(int op, Node **nl, Node **nr)
loop:
if(l == N || r == N) {
// cannot happen: caller checked that lists had same length
if(l != r)
yyerror("error in shape across %O", op);
return rev(nn);
@ -1738,7 +1740,9 @@ ascompatet(int op, Node **nl, Type **nr, int fp)
loop:
if(l == N || r == T) {
if(l != N || r != T)
yyerror("error in shape across %O", op);
yyerror("assignment count mismatch: %d = %d",
listcount(*nl), structcount(*nr));
return rev(nn);
}
@ -1867,6 +1871,52 @@ mkdotargs(Node *r, Node *rr, Iter *saver, Node *nn, Type *l, int fp)
return nn;
}
/*
* helpers for shape errors
*/
static void
dumptypes(Type **nl, char *what)
{
int first;
Type *l;
Iter savel;
l = structfirst(&savel, nl);
print("\t");
first = 1;
for(l = structfirst(&savel, nl); l != T; l = structnext(&savel)) {
if(first)
first = 0;
else
print(", ");
print("%T", l);
}
if(first)
print("[no arguments %s]", what);
print("\n");
}
static void
dumpnodetypes(Node **nr, char *what)
{
int first;
Node *r;
Iter saver;
print("\t");
first = 1;
for(r = listfirst(&saver, nr); r != N; r = listnext(&saver)) {
if(first)
first = 0;
else
print(", ");
print("%T", r->type);
}
if(first)
print("[no arguments %s]", what);
print("\n");
}
/*
* check assign expression list to
* a type list. called in
@ -1891,7 +1941,7 @@ ascompatte(int op, Type **nl, Node **nr, int fp)
&& structnext(&peekl) != T
&& listnext(&peekr) == N
&& eqtypenoname(r->type, *nl)) {
// clumsy check for differently aligned structs.
// TODO(rsc): clumsy check for differently aligned structs.
// need to handle eventually, but this keeps us
// from inserting bugs
if(r->type->width != (*nl)->width) {
@ -1931,8 +1981,14 @@ loop:
}
if(l == T || r == N) {
if(l != T || r != N)
yyerror("error in shape across %O", op);
if(l != T || r != N) {
if(l != T)
yyerror("not enough arguments to %O", op);
else
yyerror("too many arguments to %O", op);
dumptypes(nl, "expected");
dumpnodetypes(nr, "given");
}
return rev(nn);
}
convlit(r, l->type);

View file

@ -136,6 +136,9 @@ fixedbugs/bug041.go:5: export of incomplete type t
=========== fixedbugs/bug049.go
fixedbugs/bug049.go:6: cannot convert nil constant to string
fixedbugs/bug049.go:6: illegal types for operand: EQ
string
nil
=========== fixedbugs/bug050.go
fixedbugs/bug050.go:3: package statement must be first
@ -148,6 +151,7 @@ fixedbugs/bug051.go:10: expression must be a constant
fixedbugs/bug062.go:6: cannot convert nil constant to string
fixedbugs/bug062.go:6: illegal types for operand: AS
string
nil
=========== fixedbugs/bug067.go
ok
@ -224,6 +228,7 @@ fixedbugs/bug122.go:6: too many arguments to make array
fixedbugs/bug131.go:7: cannot convert uint64 constant to int64
fixedbugs/bug131.go:7: illegal types for operand: AS
int64
uint64
=========== fixedbugs/bug133.go
fixedbugs/bug133.dir/bug2.go:11: undefined DOT i on bug0.T