Skip to content

Commit b66fa57

Browse files
committed
reflect.DeepEquals: channels of the same underlying type can be equal.
According to the Go spec, channels are equal if they have been created by the same call to make(). Prior to this change reflect.DeepEqual() would return false when comparing two channels, one of this is a named type (e.g. `type ch chan string`) and was created by type conversion from the other one. After this change, DeepEquals behavior becomes consistent with the == operator. Upstream has a similar bug: golang/go#63886.
1 parent 0769076 commit b66fa57

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

compiler/natives/src/reflect/reflect.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1639,7 +1639,7 @@ func DeepEqual(a1, a2 interface{}) bool {
16391639
if i1 == i2 {
16401640
return true
16411641
}
1642-
if i1 == nil || i2 == nil || i1.Get("constructor") != i2.Get("constructor") {
1642+
if i1 == nil || i2 == nil {
16431643
return false
16441644
}
16451645
return deepValueEqualJs(ValueOf(a1), ValueOf(a2), nil)
@@ -1649,6 +1649,11 @@ func deepValueEqualJs(v1, v2 Value, visited [][2]unsafe.Pointer) bool {
16491649
if !v1.IsValid() || !v2.IsValid() {
16501650
return !v1.IsValid() && !v2.IsValid()
16511651
}
1652+
1653+
if v1.Kind() == Chan && v2.Kind() == Chan {
1654+
return v1.object() == v2.object()
1655+
}
1656+
16521657
if v1.Type() != v2.Type() {
16531658
return false
16541659
}

tests/misc_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,3 +959,31 @@ func TestFileSetSize(t *testing.T) {
959959
t.Errorf("Got: unsafe.Sizeof(token.FileSet{}) %v, Want: %v", n2, n1)
960960
}
961961
}
962+
963+
func TestChanEquality(t *testing.T) {
964+
type ch chan string
965+
966+
ch1 := make(chan string)
967+
ch2 := make(ch)
968+
ch3 := ch(ch1)
969+
970+
t.Run("equal", func(t *testing.T) {
971+
if ch1 != ch3 {
972+
t.Errorf("Got: ch1 != ch3. Want: channels created by the same call to make are equal.")
973+
}
974+
if runtime.Compiler != "gopherjs" {
975+
t.Skip("https://github.com/golang/go/issues/63886")
976+
}
977+
if !reflect.DeepEqual(ch1, ch3) {
978+
t.Errorf("Got: reflect.DeepEqual(ch1, ch3) == false. Want: channels created by the same call to make are equal.")
979+
}
980+
})
981+
t.Run("not equal", func(t *testing.T) {
982+
if ch1 == ch2 {
983+
t.Errorf("Got: ch1 == ch2. Want: channels created by different calls to make are not equal.")
984+
}
985+
if reflect.DeepEqual(ch1, ch2) {
986+
t.Errorf("Got: reflect.DeepEqual(ch1, ch2) == true. Want: channels created by different calls to make are not equal.")
987+
}
988+
})
989+
}

0 commit comments

Comments
 (0)