]> Cypherpunks.ru repositories - gostls13.git/commitdiff
go/types, types2: more concise error messages for cycle errors
authorRobert Griesemer <gri@golang.org>
Wed, 28 Sep 2022 23:44:53 +0000 (16:44 -0700)
committerGopher Robot <gobot@golang.org>
Thu, 29 Sep 2022 14:21:33 +0000 (14:21 +0000)
If a cycle has length 1, don't enumerate the single cycle entry;
instead just mention "refers to itself". For instance, for an
invalid recursive type T we now report:

invalid recursive type: T refers to itself

instead of:

invalid recursive type T
T refers to
T

Adjust tests to check for the different error messages.

Change-Id: I5bd46f62fac0cf167f0d0c9a55f952981d294ff4
Reviewed-on: https://go-review.googlesource.com/c/go/+/436295
Run-TryBot: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Robert Griesemer <gri@google.com>

19 files changed:
src/cmd/compile/internal/types2/decl.go
src/cmd/compile/internal/types2/initorder.go
src/go/types/decl.go
src/go/types/initorder.go
src/internal/types/testdata/check/cycles0.go
src/internal/types/testdata/check/cycles5.go
src/internal/types/testdata/check/init0.go
src/internal/types/testdata/fixedbugs/issue48819.go
test/fixedbugs/bug195.go
test/fixedbugs/issue23823.go
test/fixedbugs/issue44266.go
test/fixedbugs/issue48301.go
test/fixedbugs/issue7525.go
test/fixedbugs/issue7525b.go
test/fixedbugs/issue7525c.go
test/fixedbugs/issue7525d.go
test/fixedbugs/issue7525e.go
test/fixedbugs/issue8507.go
test/typeparam/issue46461.go

index ebce3ee2e250125826bee6d037fdd30271449db3..ec9f15466490e5392e4f72ca31eaec0213578092 100644 (file)
@@ -308,7 +308,7 @@ func (check *Checker) cycleError(cycle []Object) {
        // name returns the (possibly qualified) object name.
        // This is needed because with generic types, cycles
        // may refer to imported types. See issue #50788.
-       // TODO(gri) Thus functionality is used elsewhere. Factor it out.
+       // TODO(gri) This functionality is used elsewhere. Factor it out.
        name := func(obj Object) string {
                var buf bytes.Buffer
                writePackage(&buf, obj.Pkg(), check.qualifier)
@@ -327,6 +327,17 @@ func (check *Checker) cycleError(cycle []Object) {
        if tname != nil && tname.IsAlias() {
                check.validAlias(tname, Typ[Invalid])
        }
+
+       // report a more concise error for self references
+       if len(cycle) == 1 {
+               if tname != nil {
+                       check.errorf(obj, _InvalidDeclCycle, "invalid recursive type: %s refers to itself", objName)
+               } else {
+                       check.errorf(obj, _InvalidDeclCycle, "invalid cycle in declaration: %s refers to itself", objName)
+               }
+               return
+       }
+
        var err error_
        err.code = _InvalidDeclCycle
        if tname != nil {
index af43f53c1699a0e66b9a6c7a300af4485ce67176..62184ea8709e9e2d955d13c8dcbc2ad2ace2b7cc 100644 (file)
@@ -152,6 +152,13 @@ func findPath(objMap map[Object]*declInfo, from, to Object, seen map[Object]bool
 // reportCycle reports an error for the given cycle.
 func (check *Checker) reportCycle(cycle []Object) {
        obj := cycle[0]
+
+       // report a more concise error for self references
+       if len(cycle) == 1 {
+               check.errorf(obj, _InvalidInitCycle, "initialization cycle: %s refers to itself", obj.Name())
+               return
+       }
+
        var err error_
        err.code = _InvalidInitCycle
        err.errorf(obj, "initialization cycle for %s", obj.Name())
index 87d4f3fdf4381fa7bd3866ce94803ab302a76ec9..628c7bb5d97723c28ad0020291d314cfac2eed58 100644 (file)
@@ -325,6 +325,17 @@ func (check *Checker) cycleError(cycle []Object) {
        if tname != nil && tname.IsAlias() {
                check.validAlias(tname, Typ[Invalid])
        }
+
+       // report a more concise error for self references
+       if len(cycle) == 1 {
+               if tname != nil {
+                       check.errorf(obj, _InvalidDeclCycle, "invalid recursive type: %s refers to itself", objName)
+               } else {
+                       check.errorf(obj, _InvalidDeclCycle, "invalid cycle in declaration: %s refers to itself", objName)
+               }
+               return
+       }
+
        if tname != nil {
                check.errorf(obj, _InvalidDeclCycle, "invalid recursive type %s", objName)
        } else {
index 1118b58f7bac2c7e7ba1fdc61143b8ea19c98e1d..e9570ad55c13b5f2b33d046ae4e37082f59409bd 100644 (file)
@@ -152,6 +152,13 @@ func findPath(objMap map[Object]*declInfo, from, to Object, seen map[Object]bool
 // reportCycle reports an error for the given cycle.
 func (check *Checker) reportCycle(cycle []Object) {
        obj := cycle[0]
+
+       // report a more concise error for self references
+       if len(cycle) == 1 {
+               check.errorf(obj, _InvalidInitCycle, "initialization cycle: %s refers to itself", obj.Name())
+               return
+       }
+
        check.errorf(obj, _InvalidInitCycle, "initialization cycle for %s", obj.Name())
        // subtle loop: print cycle[i] for i = 0, n-1, n-2, ... 1 for len(cycle) = n
        for i := len(cycle) - 1; i >= 0; i-- {
index e5368d13c9847205028ea7f5942f296ce200ec3a..d4e7e60f832ac08e7971ffffe66e99922fdba8c7 100644 (file)
@@ -8,7 +8,7 @@ import "unsafe"
 
 type (
        T0 int
-       T1 /* ERROR invalid recursive type */ T1
+       T1 /* ERROR invalid recursive type: T1 refers to itself */ T1
        T2 *T2
 
        T3 /* ERROR invalid recursive type */ T4
@@ -34,8 +34,8 @@ type (
        L0 []L0
 
        // structs
-       S0 /* ERROR invalid recursive type */ struct{ _ S0 }
-       S1 /* ERROR invalid recursive type */ struct{ S1 }
+       S0 /* ERROR invalid recursive type: S0 refers to itself */ struct{ _ S0 }
+       S1 /* ERROR invalid recursive type: S1 refers to itself */ struct{ S1 }
        S2 struct{ _ *S2 }
        S3 struct{ *S3 }
 
@@ -53,7 +53,7 @@ type (
        F2 func(F2) F2
 
        // interfaces
-       I0 /* ERROR invalid recursive type */ interface{ I0 }
+       I0 /* ERROR invalid recursive type: I0 refers to itself */ interface{ I0 }
 
        I1 /* ERROR invalid recursive type */ interface{ I2 }
        I2 interface{ I3 }
@@ -83,7 +83,7 @@ type (
 
 func _() {
        type (
-               t1 /* ERROR invalid recursive type */ t1
+               t1 /* ERROR invalid recursive type: t1 refers to itself */ t1
                t2 *t2
 
                t3 t4 /* ERROR undefined */
@@ -91,15 +91,15 @@ func _() {
                t5 t3
 
                // arrays
-               a0 /* ERROR invalid recursive type */ [10]a0
+               a0 /* ERROR invalid recursive type: a0 refers to itself */ [10]a0
                a1 [10]*a1
 
                // slices
                l0 []l0
 
                // structs
-               s0 /* ERROR invalid recursive type */ struct{ _ s0 }
-               s1 /* ERROR invalid recursive type */ struct{ s1 }
+               s0 /* ERROR invalid recursive type: s0 refers to itself */ struct{ _ s0 }
+               s1 /* ERROR invalid recursive type: s1 refers to itself */ struct{ s1 }
                s2 struct{ _ *s2 }
                s3 struct{ *s3 }
 
@@ -112,7 +112,7 @@ func _() {
                f2 func(f2) f2
 
                // interfaces
-               i0 /* ERROR invalid recursive type */ interface{ i0 }
+               i0 /* ERROR invalid recursive type: i0 refers to itself */ interface{ i0 }
 
                // maps
                m0 map[m0 /* ERROR invalid map key */ ]m0
@@ -135,17 +135,17 @@ type S struct {
 
 type (
        P1 *T9
-       T9 /* ERROR invalid recursive type */ T9
+       T9 /* ERROR invalid recursive type: T9 refers to itself */ T9
 
-       T10 /* ERROR invalid recursive type */ T10
+       T10 /* ERROR invalid recursive type: T10 refers to itself */ T10
        P2 *T10
 )
 
 func (T11) m() {}
 
-type T11 /* ERROR invalid recursive type */ struct{ T11 }
+type T11 /* ERROR invalid recursive type: T11 refers to itself */ struct{ T11 }
 
-type T12 /* ERROR invalid recursive type */ struct{ T12 }
+type T12 /* ERROR invalid recursive type: T12 refers to itself */ struct{ T12 }
 
 func (*T12) m() {}
 
index 68aa913682dd2d29e559cb22ab073f5eea3e81bb..5e0d1913d9baa42bafec150df10f77694ac66d46 100644 (file)
@@ -159,7 +159,7 @@ var a12 = makeArray()
 func makeArray() (res T12) { return }
 
 // issue #20770
-var r /* ERROR cycle */ = newReader()
+var r /* ERROR invalid cycle in declaration of r */ = newReader()
 func newReader() r
 
 // variations of the theme of #8699 and #20770
@@ -170,7 +170,7 @@ func f() [len(arr)]int
 func ff(ff /* ERROR not a type */ )
 func gg((gg /* ERROR not a type */ ))
 
-type T13 /* ERROR invalid recursive type */ [len(b13)]int
+type T13 /* ERROR invalid recursive type T13 */ [len(b13)]int
 var b13 T13
 
 func g1() [unsafe.Sizeof(g1)]int
@@ -190,7 +190,7 @@ var c14 /* ERROR cycle */ T14
 type T14 [uintptr(unsafe.Sizeof(&c14))]byte
 
 // issue #34333
-type T15 /* ERROR invalid recursive type */ struct {
+type T15 /* ERROR invalid recursive type T15 */ struct {
        f func() T16
        b T16
 }
index 6e8746afb64197af29c089f8f9a368ca1a7b0186..5159a176d74813e7dfe32be26a9a274c3b89582b 100644 (file)
@@ -8,50 +8,50 @@ package init0
 
 // initialization cycles (we don't know the types)
 const (
-       s0 /* ERROR initialization cycle */ = s0
+       s0 /* ERROR initialization cycle: s0 refers to itself */ = s0
 
-       x0 /* ERROR initialization cycle */ = y0
+       x0 /* ERROR initialization cycle for x0 */ = y0
        y0 = x0
 
        a0 = b0
-       b0 /* ERROR initialization cycle */ = c0
+       b0 /* ERROR initialization cycle for b0 */ = c0
        c0 = d0
        d0 = b0
 )
 
 var (
-       s1 /* ERROR initialization cycle */ = s1
+       s1 /* ERROR initialization cycle: s1 refers to itself */ = s1
 
-       x1 /* ERROR initialization cycle */ = y1
+       x1 /* ERROR initialization cycle for x1 */ = y1
        y1 = x1
 
        a1 = b1
-       b1 /* ERROR initialization cycle */ = c1
+       b1 /* ERROR initialization cycle for b1 */ = c1
        c1 = d1
        d1 = b1
 )
 
 // initialization cycles (we know the types)
 const (
-       s2 /* ERROR initialization cycle */ int = s2
+       s2 /* ERROR initialization cycle: s2 refers to itself */ int = s2
 
-       x2 /* ERROR initialization cycle */ int = y2
+       x2 /* ERROR initialization cycle for x2 */ int = y2
        y2 = x2
 
        a2 = b2
-       b2 /* ERROR initialization cycle */ int = c2
+       b2 /* ERROR initialization cycle for b2 */ int = c2
        c2 = d2
        d2 = b2
 )
 
 var (
-       s3 /* ERROR initialization cycle */ int = s3
+       s3 /* ERROR initialization cycle: s3 refers to itself */ int = s3
 
-       x3 /* ERROR initialization cycle */ int = y3
+       x3 /* ERROR initialization cycle for x3 */ int = y3
        y3 = x3
 
        a3 = b3
-       b3 /* ERROR initialization cycle */ int = c3
+       b3 /* ERROR initialization cycle for b3 */ int = c3
        c3 = d3
        d3 = b3
 )
@@ -62,12 +62,12 @@ type S1 struct {
        f int
 }
 const cx3 S1 /* ERROR invalid constant type */ = S1{cx3.f}
-var vx3 /* ERROR initialization cycle */ S1 = S1{vx3.f}
+var vx3 /* ERROR initialization cycle: vx3 refers to itself */ S1 = S1{vx3.f}
 
 // cycles via functions
 
 var x4 = x5
-var x5 /* ERROR initialization cycle */ = f1()
+var x5 /* ERROR initialization cycle for x5 */ = f1()
 func f1() int { return x5*10 }
 
 var x6, x7 /* ERROR initialization cycle */ = f2()
@@ -77,9 +77,9 @@ func f3() int { return x8 }
 
 // cycles via function literals
 
-var x9 /* ERROR initialization cycle */ = func() int { return x9 }()
+var x9 /* ERROR initialization cycle: x9 refers to itself */ = func() int { return x9 }()
 
-var x10 /* ERROR initialization cycle */ = f4()
+var x10 /* ERROR initialization cycle for x10 */ = f4()
 
 func f4() int {
        _ = func() {
@@ -94,7 +94,7 @@ type T1 struct{}
 
 func (T1) m() bool { _ = x11; return false }
 
-var x11 /* ERROR initialization cycle */ = T1.m(T1{})
+var x11 /* ERROR initialization cycle for x11 */ = T1.m(T1{})
 
 // cycles via method values
 
@@ -103,4 +103,4 @@ type T2 struct{}
 func (T2) m() bool { _ = x12; return false }
 
 var t1 T2
-var x12 /* ERROR initialization cycle */ = t1.m
+var x12 /* ERROR initialization cycle for x12 */ = t1.m
index 95e40ea009f5cbe3b5b23d00752511fcad111502..5d618036874e0c576b57f09500a565329e3a337c 100644 (file)
@@ -6,7 +6,7 @@ package p
 
 import "unsafe"
 
-type T /* ERROR invalid recursive type T */ struct {
+type T /* ERROR invalid recursive type: T refers to itself */ struct {
        T
 }
 
index 4a3bf0db81d84094664dff9bd53d2ca6dd641d55..769ed050b3704cf4b1af54bc77512fac4dd7478c 100644 (file)
@@ -14,7 +14,7 @@ type I3 interface{ int } // ERROR "interface"
 type S struct { // GC_ERROR "invalid recursive type"
        x interface{ S } // GCCGO_ERROR "interface"
 }
-type I4 interface { // GC_ERROR "invalid recursive type I4\n\tLINE:.* I4 refers to\n\tLINE:.* I4$"
+type I4 interface { // GC_ERROR "invalid recursive type: I4 refers to itself"
        I4 // GCCGO_ERROR "interface"
 }
 
index c53415f7b9146547ae50ea8a5e755d87b6cea7a5..0d51f81098ce316d16e9bf16bf5dc7ad36fdac53 100644 (file)
@@ -11,6 +11,6 @@ type I1 = interface {
 }
 
 // BAD: type loop should mention I1; see also #41669
-type I2 interface { // GC_ERROR "invalid recursive type I2\n\tLINE: I2 refers to\n\tLINE: I2$|invalid recursive type I2"
+type I2 interface { // GC_ERROR "invalid recursive type: I2 refers to itself"
        I1 // GCCGO_ERROR "invalid recursive interface"
 }
index c683e56075d8190e23f11d89fafeda08233f5906..f3c1984b6fafafd66a813aceb3e9cc7a787a8ebe 100644 (file)
@@ -16,7 +16,7 @@ type T2 struct {
        io.SectionReader
 }
 
-type T3 struct { // ERROR "invalid recursive type T3"
+type T3 struct { // ERROR "invalid recursive type: T3 refers to itself"
        T1
        T2
        parent T3
index 94c9a5b6f9e2832e47678a5e58d6412177230dfd..8b6321d19aa73c6082354b36339f047d094d5a3c 100644 (file)
@@ -9,5 +9,5 @@
 package p
 
 func _() {
-       type T = T // ERROR "T uses T|invalid recursive type T"
+       type T = T // ERROR "invalid recursive type: T refers to itself"
 }
index 05e26d19153f1ffd3b867c4dbb17a0cb2c577d32..1a81200f13b7ec152c1f5b000a5d6674de956e39 100644 (file)
@@ -10,6 +10,6 @@ package main
 
 import "unsafe"
 
-var x struct { // GC_ERROR "initialization cycle for x"
+var x struct { // GC_ERROR "initialization cycle: x refers to itself"
        a [unsafe.Sizeof(x.a)]int // GCCGO_ERROR "array bound|typechecking loop|invalid expression"
 }
index b72d12fbb7a04fb96961c2cb84360c62646c8f40..2b903ae91305c9d9840043a59bc56e3c96bc1ee3 100644 (file)
@@ -8,6 +8,6 @@
 
 package main
 
-var y struct { // GC_ERROR "initialization cycle for y"
+var y struct { // GC_ERROR "initialization cycle: y refers to itself"
        d [len(y.d)]int // GCCGO_ERROR "array bound|typechecking loop|invalid array"
 }
index 8d51154a35aa08a492249b8815324d5899b0ab61..b94d596044ea6da7a4a2d194059e6c28b1d41f9f 100644 (file)
@@ -8,6 +8,6 @@
 
 package main
 
-var z struct { // GC_ERROR "initialization cycle for z"
+var z struct { // GC_ERROR "initialization cycle: z refers to itself"
        e [cap(z.e)]int // GCCGO_ERROR "array bound|typechecking loop|invalid array"
 }
index cedb9f7b314f1084d7424aaaa1edfec746748fc1..dc83dbcb46b2a00e5d4e441e3c1815593cb38c83 100644 (file)
@@ -10,6 +10,6 @@ package main
 
 import "unsafe"
 
-var x struct { // GC_ERROR "initialization cycle for x"
+var x struct { // GC_ERROR "initialization cycle: x refers to itself"
        b [unsafe.Offsetof(x.b)]int // GCCGO_ERROR "array bound|typechecking loop|invalid array"
 }
index 574639752164886843e438a58ce53b70b2c5d378..d4f17314db8576a0440dd92fb32604288f921ac5 100644 (file)
@@ -10,6 +10,6 @@ package main
 
 import "unsafe"
 
-var x struct { // GC_ERROR "initialization cycle for x"
+var x struct { // GC_ERROR "initialization cycle: x refers to itself"
        c [unsafe.Alignof(x.c)]int // GCCGO_ERROR "array bound|typechecking loop|invalid array"
 }
index 392ecf406350a7abe01425c4ec3541ad82b0e011..6b513baf27dbb74389fef068db63c0c346f60b32 100644 (file)
@@ -9,7 +9,7 @@
 
 package p
 
-type T struct{ T } // ERROR "invalid recursive type .*T"
+type T struct{ T } // ERROR "invalid recursive type.*T"
 
 func f() {
        println(T{} == T{})
index 4d4d4400c2333c58c9dfa004cc63c872e17fed03..363a87cfe08f10ed145120369ab0a01fc7f13fee 100644 (file)
@@ -6,7 +6,7 @@
 
 package p
 
-type T[U interface{ M() T[U] }] int // ERROR "invalid recursive type T"
+type T[U interface{ M() T[U] }] int // ERROR "invalid recursive type: T refers to itself"
 
 type X int