Commit 3a1c226a authored by Rob Pike's avatar Rob Pike

reflect.DeepEqual: don't panic comparing functions

Functions are equal iff they are both nil.

Fixes #3122.

R=golang-dev, dsymonds, rsc
CC=golang-dev
https://golang.org/cl/5693057
parent eb37b5b7
...@@ -629,6 +629,13 @@ type DeepEqualTest struct { ...@@ -629,6 +629,13 @@ type DeepEqualTest struct {
eq bool eq bool
} }
// Simple functions for DeepEqual tests.
var (
fn1 func() // nil.
fn2 func() // nil.
fn3 = func() { fn1() } // Not nil.
)
var deepEqualTests = []DeepEqualTest{ var deepEqualTests = []DeepEqualTest{
// Equalities // Equalities
{1, 1, true}, {1, 1, true},
...@@ -641,6 +648,7 @@ var deepEqualTests = []DeepEqualTest{ ...@@ -641,6 +648,7 @@ var deepEqualTests = []DeepEqualTest{
{Basic{1, 0.5}, Basic{1, 0.5}, true}, {Basic{1, 0.5}, Basic{1, 0.5}, true},
{error(nil), error(nil), true}, {error(nil), error(nil), true},
{map[int]string{1: "one", 2: "two"}, map[int]string{2: "two", 1: "one"}, true}, {map[int]string{1: "one", 2: "two"}, map[int]string{2: "two", 1: "one"}, true},
{fn1, fn2, true},
// Inequalities // Inequalities
{1, 2, false}, {1, 2, false},
...@@ -658,6 +666,8 @@ var deepEqualTests = []DeepEqualTest{ ...@@ -658,6 +666,8 @@ var deepEqualTests = []DeepEqualTest{
{map[int]string{2: "two", 1: "one"}, map[int]string{1: "one"}, false}, {map[int]string{2: "two", 1: "one"}, map[int]string{1: "one"}, false},
{nil, 1, false}, {nil, 1, false},
{1, nil, false}, {1, nil, false},
{fn1, fn3, false},
{fn3, fn3, false},
// Nil vs empty: not the same. // Nil vs empty: not the same.
{[]int{}, []int(nil), false}, {[]int{}, []int(nil), false},
......
...@@ -108,6 +108,12 @@ func deepValueEqual(v1, v2 Value, visited map[uintptr]*visit, depth int) (b bool ...@@ -108,6 +108,12 @@ func deepValueEqual(v1, v2 Value, visited map[uintptr]*visit, depth int) (b bool
} }
} }
return true return true
case Func:
if v1.IsNil() && v2.IsNil() {
return true
}
// Can't do better than this:
return false
default: default:
// Normal equality suffices // Normal equality suffices
return valueInterface(v1, false) == valueInterface(v2, false) return valueInterface(v1, false) == valueInterface(v2, false)
...@@ -117,8 +123,8 @@ func deepValueEqual(v1, v2 Value, visited map[uintptr]*visit, depth int) (b bool ...@@ -117,8 +123,8 @@ func deepValueEqual(v1, v2 Value, visited map[uintptr]*visit, depth int) (b bool
} }
// DeepEqual tests for deep equality. It uses normal == equality where possible // DeepEqual tests for deep equality. It uses normal == equality where possible
// but will scan members of arrays, slices, and fields of structs. It correctly // but will scan members of arrays, slices, maps, and fields of structs. It correctly
// handles recursive types. // handles recursive types. Functions are equal only if they are both nil.
func DeepEqual(a1, a2 interface{}) bool { func DeepEqual(a1, a2 interface{}) bool {
if a1 == nil || a2 == nil { if a1 == nil || a2 == nil {
return a1 == a2 return a1 == a2
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment