// 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)
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 {
// 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())
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 {
// 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-- {
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
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 }
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 }
func _() {
type (
- t1 /* ERROR invalid recursive type */ t1
+ t1 /* ERROR invalid recursive type: t1 refers to itself */ t1
t2 *t2
t3 t4 /* ERROR undefined */
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 }
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
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() {}
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
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
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
}
// 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
)
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()
// 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() {
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
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
import "unsafe"
-type T /* ERROR invalid recursive type T */ struct {
+type T /* ERROR invalid recursive type: T refers to itself */ struct {
T
}
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"
}
}
// 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"
}
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
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"
}
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"
}
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"
}
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"
}
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"
}
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"
}
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{})
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