diff options
-rw-r--r-- | src/cmd/gc/const.c | 1 | ||||
-rw-r--r-- | src/cmd/gc/walk.c | 66 | ||||
-rw-r--r-- | 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 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); diff --git a/test/golden.out b/test/golden.out index 1998061ff..9ccb8ce67 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 |