1// run 2 3// Copyright 2020 The Go Authors. All rights reserved. 4// Use of this source code is governed by a BSD-style 5// license that can be found in the LICENSE file. 6 7// Check to make sure that we compare fields in order. See issue 8606. 8 9package main 10 11import "fmt" 12 13func main() { 14 type A [2]interface{} 15 type A2 [6]interface{} 16 type S struct{ x, y interface{} } 17 type S2 struct{ x, y, z, a, b, c interface{} } 18 type T1 struct { 19 i interface{} 20 a int64 21 j interface{} 22 } 23 type T2 struct { 24 i interface{} 25 a, b, c int64 26 j interface{} 27 } 28 type T3 struct { 29 i interface{} 30 s string 31 j interface{} 32 } 33 type S3 struct { 34 f any 35 i int 36 } 37 type S4 struct { 38 a [1000]byte 39 b any 40 } 41 b := []byte{1} 42 s1 := S3{func() {}, 0} 43 s2 := S3{func() {}, 1} 44 45 for _, test := range []struct { 46 panic bool 47 a, b interface{} 48 }{ 49 {false, A{1, b}, A{2, b}}, 50 {true, A{b, 1}, A{b, 2}}, 51 {false, A{1, b}, A{"2", b}}, 52 {true, A{b, 1}, A{b, "2"}}, 53 54 {false, A2{1, b}, A2{2, b}}, 55 {true, A2{b, 1}, A2{b, 2}}, 56 {false, A2{1, b}, A2{"2", b}}, 57 {true, A2{b, 1}, A2{b, "2"}}, 58 59 {false, S{1, b}, S{2, b}}, 60 {true, S{b, 1}, S{b, 2}}, 61 {false, S{1, b}, S{"2", b}}, 62 {true, S{b, 1}, S{b, "2"}}, 63 64 {false, S2{x: 1, y: b}, S2{x: 2, y: b}}, 65 {true, S2{x: b, y: 1}, S2{x: b, y: 2}}, 66 {false, S2{x: 1, y: b}, S2{x: "2", y: b}}, 67 {true, S2{x: b, y: 1}, S2{x: b, y: "2"}}, 68 69 {true, T1{i: b, a: 1}, T1{i: b, a: 2}}, 70 {false, T1{a: 1, j: b}, T1{a: 2, j: b}}, 71 {true, T2{i: b, a: 1}, T2{i: b, a: 2}}, 72 {false, T2{a: 1, j: b}, T2{a: 2, j: b}}, 73 {true, T3{i: b, s: "foo"}, T3{i: b, s: "bar"}}, 74 {false, T3{s: "foo", j: b}, T3{s: "bar", j: b}}, 75 {true, T3{i: b, s: "fooz"}, T3{i: b, s: "bar"}}, 76 {false, T3{s: "fooz", j: b}, T3{s: "bar", j: b}}, 77 {true, A{s1, s2}, A{s2, s1}}, 78 {true, s1, s2}, 79 {false, S4{[1000]byte{0}, func() {}}, S4{[1000]byte{1}, func() {}}}, 80 } { 81 f := func() { 82 defer func() { 83 if recover() != nil { 84 panic(fmt.Sprintf("comparing %#v and %#v panicked", test.a, test.b)) 85 } 86 }() 87 if test.a == test.b { 88 panic(fmt.Sprintf("values %#v and %#v should not be equal", test.a, test.b)) 89 } 90 } 91 if test.panic { 92 shouldPanic(fmt.Sprintf("comparing %#v and %#v did not panic", test.a, test.b), f) 93 } else { 94 f() // should not panic 95 } 96 } 97} 98 99func shouldPanic(name string, f func()) { 100 defer func() { 101 if recover() == nil { 102 panic(name) 103 } 104 }() 105 f() 106} 107