func checkNoCycles()

in pkg/cloud/api/check.go [75:101]


func checkNoCycles(p Path, t reflect.Type, seen []string) error {
	switch t.Kind() {
	case reflect.Slice:
		return checkNoCycles(p.Index(0), t.Elem(), seen)
	case reflect.Pointer:
		return checkNoCycles(p.Pointer(), t.Elem(), seen)
	case reflect.Map:
		// Use "x" as the placeholder for the map key in the Path for debugging
		// output purposes.
		return checkNoCycles(p.MapIndex("x"), t.Elem(), seen)
	case reflect.Struct:
		typeName := fmt.Sprintf("%s/%s", t.PkgPath(), t.Name())
		for _, seenTypeName := range seen {
			if typeName == seenTypeName {
				return fmt.Errorf("recursive type found at %s: %s", p, typeName)
			}
		}
		// Add this struct type to the list of types seen on this path.
		seen = append(seen, fmt.Sprintf("%s/%s", t.PkgPath(), t.Name()))
		for i := 0; i < t.NumField(); i++ {
			if err := checkNoCycles(p.Field(t.Field(i).Name), t.Field(i).Type, seen); err != nil {
				return err
			}
		}
	}
	return nil
}