diff --git a/src/pkg/reflect/deepequal.go b/src/pkg/reflect/deepequal.go index 915afed4cd..cc6ce05616 100644 --- a/src/pkg/reflect/deepequal.go +++ b/src/pkg/reflect/deepequal.go @@ -9,18 +9,17 @@ package reflect // During deepValueEqual, must keep track of checks that are // in progress. The comparison algorithm assumes that all // checks in progress are true when it reencounters them. -// Visited are stored in a map indexed by 17 * a1 + a2; +// Visited comparisons are stored in a map indexed by visit. type visit struct { - a1 uintptr - a2 uintptr - typ Type - next *visit + a1 uintptr + a2 uintptr + typ Type } // Tests for deep equality using reflected types. The map argument tracks // comparisons that have already been seen, which allows short circuiting on // recursive types. -func deepValueEqual(v1, v2 Value, visited map[uintptr]*visit, depth int) (b bool) { +func deepValueEqual(v1, v2 Value, visited map[visit]bool, depth int) bool { if !v1.IsValid() || !v2.IsValid() { return v1.IsValid() == v2.IsValid() } @@ -44,17 +43,14 @@ func deepValueEqual(v1, v2 Value, visited map[uintptr]*visit, depth int) (b bool } // ... or already seen - h := 17*addr1 + addr2 - seen := visited[h] typ := v1.Type() - for p := seen; p != nil; p = p.next { - if p.a1 == addr1 && p.a2 == addr2 && p.typ == typ { - return true - } + v := visit{addr1, addr2, typ} + if visited[v] { + return true } // Remember for later. - visited[h] = &visit{addr1, addr2, typ, seen} + visited[v] = true } switch v1.Kind() { @@ -135,5 +131,5 @@ func DeepEqual(a1, a2 interface{}) bool { if v1.Type() != v2.Type() { return false } - return deepValueEqual(v1, v2, make(map[uintptr]*visit), 0) + return deepValueEqual(v1, v2, make(map[visit]bool), 0) }