]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: replace "typechecking loop" by nicer errors in some cases.
authorRémy Oudompheng <oudomphe@phare.normalesup.org>
Sun, 7 Oct 2012 15:35:21 +0000 (17:35 +0200)
committerRémy Oudompheng <oudomphe@phare.normalesup.org>
Sun, 7 Oct 2012 15:35:21 +0000 (17:35 +0200)
For issue 3757:
BEFORE:  test/fixedbugs/bug463.go:12: typechecking loop involving a
             test/fixedbugs/bug463.go:12 a
             test/fixedbugs/bug463.go:12 <node DCLCONST>
AFTER:   test/fixedbugs/bug463.go:12: constant definition loop
             test/fixedbugs/bug463.go:12: a uses a

For issue 3937:
BEFORE: test/fixedbugs/bug464.go:12: typechecking loop involving foo
            test/fixedbugs/bug464.go:12 <T>
            test/fixedbugs/bug464.go:12 foo
            test/fixedbugs/bug464.go:12 <node DCLFUNC>
AFTER:  test/fixedbugs/bug464.go:12: foo is not a type

Fixes #3757.
Fixes #3937.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/6614058

src/cmd/gc/typecheck.c
test/fixedbugs/bug463.go [new file with mode: 0644]
test/fixedbugs/bug464.go [new file with mode: 0644]

index e84b45f3893a53b1bc0d71a91920b7679cd4c563..ebc43e759834455a1b01221501b03aebc5e875ab 100644 (file)
@@ -105,6 +105,27 @@ typekind(Type *t)
        return buf;
 }
 
+/*
+ * sprint_depchain prints a dependency chain
+ * of nodes into fmt.
+ * It is used by typecheck in the case of OLITERAL nodes
+ * to print constant definition loops.
+ */
+static void
+sprint_depchain(Fmt *fmt, NodeList *stack, Node *cur, Node *first)
+{
+       NodeList *l;
+
+       for(l = stack; l; l=l->next) {
+               if(l->n->op == cur->op) {
+                       if(l->n != first)
+                               sprint_depchain(fmt, l->next, l->n, first);
+                       fmtprint(fmt, "\n\t%L: %N uses %N", l->n->lineno, l->n, cur);
+                       return;
+               }
+       }
+}
+
 /*
  * type check node *np.
  * replaces *np with a new pointer in some cases.
@@ -155,6 +176,24 @@ typecheck(Node **np, int top)
        }
 
        if(n->typecheck == 2) {
+               // Typechecking loop. Trying printing a meaningful message,
+               // otherwise a stack trace of typechecking.
+               switch(n->op) {
+               case ONAME:
+                       // We can already diagnose variables used as types.
+                       if((top & (Erv|Etype)) == Etype)
+                               yyerror("%N is not a type", n);
+                       break;
+               case OLITERAL:
+                       if((top & (Erv|Etype)) == Etype) {
+                               yyerror("%N is not a type", n);
+                               break;
+                       }
+                       fmtstrinit(&fmt);
+                       sprint_depchain(&fmt, tcstack, n, n);
+                       yyerrorl(n->lineno, "constant definition loop%s", fmtstrflush(&fmt));
+                       break;
+               }
                if(nsavederrors+nerrors == 0) {
                        fmtstrinit(&fmt);
                        for(l=tcstack; l; l=l->next)
@@ -165,7 +204,7 @@ typecheck(Node **np, int top)
                return n;
        }
        n->typecheck = 2;
-       
+
        if(tcfree != nil) {
                l = tcfree;
                tcfree = l->next;
diff --git a/test/fixedbugs/bug463.go b/test/fixedbugs/bug463.go
new file mode 100644 (file)
index 0000000..3e7a184
--- /dev/null
@@ -0,0 +1,22 @@
+// errorcheck
+
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 3757: unhelpful typechecking loop message
+// for constants that refer to themselves.
+
+package main
+
+const a = a // ERROR "refers to itself|definition loop"
+
+const (
+       X    = A
+       A    = B // ERROR "refers to itself|definition loop"
+       B    = D
+       C, D = 1, A
+)
+
+func main() {
+}
diff --git a/test/fixedbugs/bug464.go b/test/fixedbugs/bug464.go
new file mode 100644 (file)
index 0000000..5821939
--- /dev/null
@@ -0,0 +1,12 @@
+// errorcheck
+
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 3937: unhelpful typechecking loop message
+// for identifiers wrongly used as types.
+
+package main
+
+func foo(x foo) {} // ERROR "expected type|not a type"