From b5e212ffddff2f9b5a6d3779d4f6bd35fd2d2b02 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Thu, 7 May 2009 10:29:35 -0700 Subject: [PATCH] 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 --- src/cmd/gc/const.c | 1 - src/cmd/gc/walk.c | 66 ++++++++++++++++++++++++++++++++++++++++++---- test/golden.out | 5 ++++ 3 files changed, 66 insertions(+), 6 deletions(-) diff --git a/src/cmd/gc/const.c b/src/cmd/gc/const.c index 08826aaf0b..d38bf79d6b 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 554451258e..64d2ae65d0 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); } @@ -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); diff --git a/test/golden.out b/test/golden.out index 1998061ffb..9ccb8ce678 100644 --- a/test/golden.out +++ b/test/golden.out @@ -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 -- 2.48.1