mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 04:55:31 +00:00
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>
This commit is contained in:
parent
23ec3c104a
commit
d53eb6fa11
@ -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…
Reference in New Issue
Block a user