1 // Copyright 2022 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
9 // validType verifies that the given type does not "expand" infinitely
10 // producing a cycle in the type graph. Cycles are detected by marking
12 // (Cycles involving alias types, as in "type A = [10]A" are detected
13 // earlier, via the objDecl cycle detection mechanism.)
14 func (check *Checker) validType(typ Type, path []Object) typeInfo {
16 unknown typeInfo = iota
22 switch t := typ.(type) {
24 return check.validType(t.elem, path)
27 for _, f := range t.fields {
28 if check.validType(f.typ, path) == invalid {
34 for _, t := range t.terms {
35 if check.validType(t.typ, path) == invalid {
41 for _, etyp := range t.embeddeds {
42 if check.validType(etyp, path) == invalid {
48 // If t is parameterized, we should be considering the instantiated (expanded)
49 // form of t, but in general we can't with this algorithm: if t is an invalid
50 // type it may be so because it infinitely expands through a type parameter.
51 // Instantiating such a type would lead to an infinite sequence of instantiations.
52 // In general, we need "type flow analysis" to recognize those cases.
53 // Example: type A[T any] struct{ x A[*T] } (issue #48951)
54 // In this algorithm we always only consider the original, uninstantiated type.
55 // This won't recognize some invalid cases with parameterized types, but it
59 // don't touch the type if it is from a different package or the Universe scope
60 // (doing so would lead to a race condition - was issue #35049)
61 if t.obj.pkg != check.pkg {
65 // don't report a 2nd error if we already know the type is invalid
66 // (e.g., if a cycle was detected earlier, via under).
67 if t.underlying == Typ[Invalid] {
75 t.info = check.validType(t.fromRHS, append(path, t.obj)) // only types of current package added to path
78 for i, tn := range path {
79 if t.obj.pkg != check.pkg {
80 panic("type cycle via package-external type")
83 check.cycleError(path[i:])
85 t.underlying = Typ[Invalid]
89 panic("cycle start not found")