diff options
author | Russ Cox <rsc@golang.org> | 2009-05-07 10:29:35 -0700 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2009-05-07 10:29:35 -0700 |
commit | adb56306f4105a783f702639754e7b2b41cdbf22 (patch) | |
tree | 1aba55c652508383c1eb7589c533aafac87c3824 /src | |
parent | dc9dfef6774c63d00608773d2cfd611e0124ea33 (diff) | |
download | golang-adb56306f4105a783f702639754e7b2b41cdbf22.tar.gz |
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
Diffstat (limited to 'src')
-rw-r--r-- | src/cmd/gc/const.c | 1 | ||||
-rw-r--r-- | src/cmd/gc/walk.c | 66 |
2 files changed, 61 insertions, 6 deletions
diff --git a/src/cmd/gc/const.c b/src/cmd/gc/const.c index 08826aaf0..d38bf79d6 100644 --- a/src/cmd/gc/const.c +++ b/src/cmd/gc/const.c @@ -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; } diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index 554451258..64d2ae65d 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -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); } @@ -1868,6 +1872,52 @@ mkdotargs(Node *r, Node *rr, Iter *saver, Node *nn, Type *l, int fp) } /* + * 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 * return expr-list @@ -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); |