Skip to content

Comparing reflect types behaves not as expected #80

@posener

Description

@posener

When comparing two equal types, the response is false, for example, the following code print false:

t1 := reflect.TypeOf(1)
t2 := reflect.TypeOf(2)
fmt.Println(cmp.Equal(t1, t2, deepAllowUnexported(t1)))

See full code

Just to clarify, if the diff is being printed, this is the reason that those two types are not the same:

{*reflect.rtype}.alg.hash:
	-: (func(unsafe.Pointer, uintptr) uintptr)(0x451530)
	+: (func(unsafe.Pointer, uintptr) uintptr)(0x451530)
{*reflect.rtype}.alg.equal:
	-: (func(unsafe.Pointer, unsafe.Pointer) bool)(0x401a50)
	+: (func(unsafe.Pointer, unsafe.Pointer) bool)(0x401a50)

This is being solved in the standard refelect.DeepEqual when comparing two pointers.

If the compareAny will do the same trick, the above code will print true as expected. It also does not break any of the tests:

diff --git a/cmp/compare.go b/cmp/compare.go
index 1260603..8fbbaa9 100644
--- a/cmp/compare.go
+++ b/cmp/compare.go
@@ -239,6 +239,12 @@ func (s *state) compareAny(vx, vy reflect.Value) {
                        s.report(vx.IsNil() && vy.IsNil(), vx, vy)
                        return
                }
+
+               if vx.Pointer() == vy.Pointer() {
+                       s.report(true, vx, vy)
+                       return
+               }
+

I am not sure why this comparison is not done in the go-cmp implementation, I can't see any harm in doing it, it can also saves running time.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions