util/deephash: simplify typeIsRecursive (#5385)

Any type that is memory hashable must not be recursive since
there are definitely no pointers involved to make a cycle.

Signed-off-by: Joe Tsai <joetsai@digital-static.net>
pull/5386/head
Joe Tsai 2 years ago committed by GitHub
parent 23ec3c104a
commit d53eb6fa11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -648,31 +648,7 @@ func typeIsRecursive(t reflect.Type) bool {
var visitType func(t reflect.Type) (isRecursiveSoFar bool) var visitType func(t reflect.Type) (isRecursiveSoFar bool)
visitType = func(t reflect.Type) (isRecursiveSoFar bool) { visitType = func(t reflect.Type) (isRecursiveSoFar bool) {
switch t.Kind() { // Check whether we have seen this type before.
case reflect.Bool,
reflect.Int,
reflect.Int8,
reflect.Int16,
reflect.Int32,
reflect.Int64,
reflect.Uint,
reflect.Uint8,
reflect.Uint16,
reflect.Uint32,
reflect.Uint64,
reflect.Uintptr,
reflect.Float32,
reflect.Float64,
reflect.Complex64,
reflect.Complex128,
reflect.String,
reflect.UnsafePointer,
reflect.Func:
return false
}
if t.Size() == 0 {
return false
}
if inStack[t] { if inStack[t] {
return true return true
} }
@ -681,9 +657,18 @@ func typeIsRecursive(t reflect.Type) bool {
delete(inStack, t) delete(inStack, t)
}() }()
// Any type that is memory hashable must not be recursive since
// cycles can only occur if pointers are involved.
if canMemHash(t) {
return false
}
// Recursively check types that may contain pointers.
switch t.Kind() { switch t.Kind() {
default: default:
panic("unhandled kind " + t.Kind().String()) panic("unhandled kind " + t.Kind().String())
case reflect.String, reflect.UnsafePointer, reflect.Func:
return false
case reflect.Interface: case reflect.Interface:
// Assume the worst for now. TODO(bradfitz): in some cases // Assume the worst for now. TODO(bradfitz): in some cases
// we should be able to prove that it's not recursive. Not worth // we should be able to prove that it's not recursive. Not worth
@ -692,12 +677,7 @@ func typeIsRecursive(t reflect.Type) bool {
case reflect.Array, reflect.Chan, reflect.Pointer, reflect.Slice: case reflect.Array, reflect.Chan, reflect.Pointer, reflect.Slice:
return visitType(t.Elem()) return visitType(t.Elem())
case reflect.Map: case reflect.Map:
if visitType(t.Key()) { return visitType(t.Key()) || visitType(t.Elem())
return true
}
if visitType(t.Elem()) {
return true
}
case reflect.Struct: case reflect.Struct:
if t.String() == "intern.Value" { if t.String() == "intern.Value" {
// Otherwise its interface{} makes this return true. // Otherwise its interface{} makes this return true.
@ -710,7 +690,6 @@ func typeIsRecursive(t reflect.Type) bool {
} }
return false return false
} }
return false
} }
return visitType(t) return visitType(t)
} }

Loading…
Cancel
Save