summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cmd/gc/const.c1
-rw-r--r--src/cmd/gc/walk.c66
-rw-r--r--test/golden.out5
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