mirror of
https://github.com/golang/go
synced 2024-11-17 13:54:46 -07:00
reflect: panic when Value.Equal using two non-comparable values
Assuming the two values are valid and non-comparable, Equal should panic. x := reflect.ValueOf([]int{1, 2, 3}) x.Equal(x) // can not report false, should panic Assuming one of them is non-comparable and the other is invalid, it should always report false. x := reflect.ValueOf([]int{1, 2, 3}) y := reflect.ValueOf(nil) x.Equal(y) // should report false For #46746. Change-Id: Ifecd77ca0b3de3019fae2be39048f9277831676c Reviewed-on: https://go-review.googlesource.com/c/go/+/440037 Reviewed-by: Ian Lance Taylor <iant@google.com> Reviewed-by: David Chase <drchase@google.com> Run-TryBot: Ian Lance Taylor <iant@google.com> Auto-Submit: Ian Lance Taylor <iant@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
9abcc487f8
commit
7ffc1e47b4
@ -8244,16 +8244,6 @@ var valueEqualTests = []ValueEqualTest{
|
||||
true,
|
||||
true, false,
|
||||
},
|
||||
{
|
||||
&equalSlice, []int{1},
|
||||
false,
|
||||
true, false,
|
||||
},
|
||||
{
|
||||
map[int]int{}, map[int]int{},
|
||||
false,
|
||||
false, false,
|
||||
},
|
||||
{
|
||||
(chan int)(nil), nil,
|
||||
false,
|
||||
@ -8289,11 +8279,6 @@ var valueEqualTests = []ValueEqualTest{
|
||||
true,
|
||||
false, false,
|
||||
},
|
||||
{
|
||||
&mapInterface, &mapInterface,
|
||||
false,
|
||||
true, true,
|
||||
},
|
||||
}
|
||||
|
||||
func TestValue_Equal(t *testing.T) {
|
||||
@ -8324,6 +8309,41 @@ func TestValue_Equal(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestValue_EqualNonComparable(t *testing.T) {
|
||||
var invalid = Value{} // ValueOf(nil)
|
||||
var values = []Value{
|
||||
// Value of slice is non-comparable.
|
||||
ValueOf([]int(nil)),
|
||||
ValueOf(([]int{})),
|
||||
|
||||
// Value of map is non-comparable.
|
||||
ValueOf(map[int]int(nil)),
|
||||
ValueOf((map[int]int{})),
|
||||
|
||||
// Value of func is non-comparable.
|
||||
ValueOf(((func())(nil))),
|
||||
ValueOf(func() {}),
|
||||
|
||||
// Value of struct is non-comparable because of non-comparable elements.
|
||||
ValueOf((NonComparableStruct{})),
|
||||
|
||||
// Value of array is non-comparable because of non-comparable elements.
|
||||
ValueOf([0]map[int]int{}),
|
||||
ValueOf([0]func(){}),
|
||||
ValueOf(([1]struct{ I interface{} }{{[]int{}}})),
|
||||
ValueOf(([1]interface{}{[1]interface{}{map[int]int{}}})),
|
||||
}
|
||||
for _, value := range values {
|
||||
// Panic when reflect.Value.Equal using two valid non-comparable values.
|
||||
shouldPanic("reflect.Value.Equal using two non-comparable values", func() { value.Equal(value) })
|
||||
|
||||
// If one is non-comparable and the other is invalid, the expected result is always false.
|
||||
if r := value.Equal(invalid); r != false {
|
||||
t.Errorf("%s == invalid got %t, want false", value.Type(), r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitFuncTypes(t *testing.T) {
|
||||
n := 100
|
||||
var wg sync.WaitGroup
|
||||
|
@ -3320,7 +3320,8 @@ func (v Value) Comparable() bool {
|
||||
}
|
||||
|
||||
// Equal reports true if v is equal to u.
|
||||
// For valid values, if either v or u is non-comparable, Equal returns false.
|
||||
// For valid values, if one of them is non-comparable, and the other is comparable,
|
||||
// Equal reports false; if v and u are both non-comparable, Equal will panic.
|
||||
func (v Value) Equal(u Value) bool {
|
||||
if !v.IsValid() || !u.IsValid() {
|
||||
return v.IsValid() == u.IsValid()
|
||||
@ -3334,7 +3335,7 @@ func (v Value) Equal(u Value) bool {
|
||||
return v.Elem().Equal(u.Elem())
|
||||
}
|
||||
|
||||
return false
|
||||
panic("reflect.Value.Equal using two non-comparable values")
|
||||
}
|
||||
|
||||
// convertOp returns the function to convert a value of type src
|
||||
|
Loading…
Reference in New Issue
Block a user