mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 17:30:00 +00:00
Merge pull request #49747 from nikhita/conversion-gen-recursive-types
Automatic merge from submit-queue (batch tested with PRs 49651, 49707, 49662, 47019, 49747) conversion-gen: support recursive types Currently, conversion-gen goes into an infinite recursion for recursive types. This fixes it to support recursive types. Needed for #47263. **Release note**: ```release-note NONE ``` /cc @sttts
This commit is contained in:
commit
088c198224
@ -329,6 +329,12 @@ func (e equalMemoryTypes) Skip(a, b *types.Type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e equalMemoryTypes) Equal(a, b *types.Type) bool {
|
func (e equalMemoryTypes) Equal(a, b *types.Type) bool {
|
||||||
|
// alreadyVisitedTypes holds all the types that have already been checked in the structural type recursion.
|
||||||
|
alreadyVisitedTypes := make(map[*types.Type]bool)
|
||||||
|
return e.cachingEqual(a, b, alreadyVisitedTypes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e equalMemoryTypes) cachingEqual(a, b *types.Type, alreadyVisitedTypes map[*types.Type]bool) bool {
|
||||||
if a == b {
|
if a == b {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -338,18 +344,24 @@ func (e equalMemoryTypes) Equal(a, b *types.Type) bool {
|
|||||||
if equal, ok := e[conversionPair{b, a}]; ok {
|
if equal, ok := e[conversionPair{b, a}]; ok {
|
||||||
return equal
|
return equal
|
||||||
}
|
}
|
||||||
result := e.equal(a, b)
|
result := e.equal(a, b, alreadyVisitedTypes)
|
||||||
e[conversionPair{a, b}] = result
|
e[conversionPair{a, b}] = result
|
||||||
e[conversionPair{b, a}] = result
|
e[conversionPair{b, a}] = result
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e equalMemoryTypes) equal(a, b *types.Type) bool {
|
func (e equalMemoryTypes) equal(a, b *types.Type, alreadyVisitedTypes map[*types.Type]bool) bool {
|
||||||
in, out := unwrapAlias(a), unwrapAlias(b)
|
in, out := unwrapAlias(a), unwrapAlias(b)
|
||||||
switch {
|
switch {
|
||||||
case in == out:
|
case in == out:
|
||||||
return true
|
return true
|
||||||
case in.Kind == out.Kind:
|
case in.Kind == out.Kind:
|
||||||
|
// if the type exists already, return early to avoid recursion
|
||||||
|
if alreadyVisitedTypes[in] {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
alreadyVisitedTypes[in] = true
|
||||||
|
|
||||||
switch in.Kind {
|
switch in.Kind {
|
||||||
case types.Struct:
|
case types.Struct:
|
||||||
if len(in.Members) != len(out.Members) {
|
if len(in.Members) != len(out.Members) {
|
||||||
@ -357,17 +369,17 @@ func (e equalMemoryTypes) equal(a, b *types.Type) bool {
|
|||||||
}
|
}
|
||||||
for i, inMember := range in.Members {
|
for i, inMember := range in.Members {
|
||||||
outMember := out.Members[i]
|
outMember := out.Members[i]
|
||||||
if !e.Equal(inMember.Type, outMember.Type) {
|
if !e.cachingEqual(inMember.Type, outMember.Type, alreadyVisitedTypes) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
case types.Pointer:
|
case types.Pointer:
|
||||||
return e.Equal(in.Elem, out.Elem)
|
return e.cachingEqual(in.Elem, out.Elem, alreadyVisitedTypes)
|
||||||
case types.Map:
|
case types.Map:
|
||||||
return e.Equal(in.Key, out.Key) && e.Equal(in.Elem, out.Elem)
|
return e.cachingEqual(in.Key, out.Key, alreadyVisitedTypes) && e.cachingEqual(in.Elem, out.Elem, alreadyVisitedTypes)
|
||||||
case types.Slice:
|
case types.Slice:
|
||||||
return e.Equal(in.Elem, out.Elem)
|
return e.cachingEqual(in.Elem, out.Elem, alreadyVisitedTypes)
|
||||||
case types.Interface:
|
case types.Interface:
|
||||||
// TODO: determine whether the interfaces are actually equivalent - for now, they must have the
|
// TODO: determine whether the interfaces are actually equivalent - for now, they must have the
|
||||||
// same type.
|
// same type.
|
||||||
|
Loading…
Reference in New Issue
Block a user