|
|
@ -12,8 +12,17 @@ import (
|
|
|
|
|
|
|
|
|
|
|
|
"tailscale.com/tailcfg"
|
|
|
|
"tailscale.com/tailcfg"
|
|
|
|
"tailscale.com/types/structs"
|
|
|
|
"tailscale.com/types/structs"
|
|
|
|
|
|
|
|
"tailscale.com/util/hashx"
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type implsSelfHasher struct {
|
|
|
|
|
|
|
|
emit uint64
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (s *implsSelfHasher) Hash(h *hashx.Block512) {
|
|
|
|
|
|
|
|
h.HashUint64(s.emit)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestTypeIsMemHashable(t *testing.T) {
|
|
|
|
func TestTypeIsMemHashable(t *testing.T) {
|
|
|
|
tests := []struct {
|
|
|
|
tests := []struct {
|
|
|
|
val any
|
|
|
|
val any
|
|
|
@ -67,6 +76,7 @@ func TestTypeIsMemHashable(t *testing.T) {
|
|
|
|
false},
|
|
|
|
false},
|
|
|
|
{[0]chan bool{}, true},
|
|
|
|
{[0]chan bool{}, true},
|
|
|
|
{struct{ f [0]func() }{}, true},
|
|
|
|
{struct{ f [0]func() }{}, true},
|
|
|
|
|
|
|
|
{&implsSelfHasher{}, false},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
|
|
for _, tt := range tests {
|
|
|
|
got := typeIsMemHashable(reflect.TypeOf(tt.val))
|
|
|
|
got := typeIsMemHashable(reflect.TypeOf(tt.val))
|
|
|
@ -102,6 +112,7 @@ func TestTypeIsRecursive(t *testing.T) {
|
|
|
|
{val: unsafe.Pointer(nil), want: false},
|
|
|
|
{val: unsafe.Pointer(nil), want: false},
|
|
|
|
{val: make(RecursiveChan), want: true},
|
|
|
|
{val: make(RecursiveChan), want: true},
|
|
|
|
{val: make(chan int), want: false},
|
|
|
|
{val: make(chan int), want: false},
|
|
|
|
|
|
|
|
{val: (*implsSelfHasher)(nil), want: false},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
|
|
for _, tt := range tests {
|
|
|
|
got := typeIsRecursive(reflect.TypeOf(tt.val))
|
|
|
|
got := typeIsRecursive(reflect.TypeOf(tt.val))
|
|
|
|