in codegen/type_converter.go [1257:1290]
func isRecursiveStruct(spec compile.TypeSpec, seenSoFar map[string]bool) bool {
switch t := spec.(type) {
case *compile.StructSpec:
// detected cycle; second time seeing this type
if _, found := seenSoFar[t.Name]; found {
return true
}
// mark this type as seen
seenSoFar[t.Name] = true
// search all fields of this struct
for _, field := range t.Fields {
if isRecursiveStruct(field.Type, seenSoFar) {
return true
}
}
// unmark
delete(seenSoFar, t.Name)
// for lists and maps, check element/key types the same way
case *compile.MapSpec:
if isRecursiveStruct(t.KeySpec, seenSoFar) || isRecursiveStruct(t.ValueSpec, seenSoFar) {
return true
}
case *compile.ListSpec:
if isRecursiveStruct(t.ValueSpec, seenSoFar) {
return true
}
}
return false
}