summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2009-05-07 10:29:35 -0700
committerRuss Cox <rsc@golang.org>2009-05-07 10:29:35 -0700
commitadb56306f4105a783f702639754e7b2b41cdbf22 (patch)
tree1aba55c652508383c1eb7589c533aafac87c3824 /src
parentdc9dfef6774c63d00608773d2cfd611e0124ea33 (diff)
downloadgolang-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.c1
-rw-r--r--src/cmd/gc/walk.c66
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);