mirror of
https://github.com/golang/go
synced 2024-11-02 05:32:33 +00:00
8628688304
Change-Id: Ifb8e4e13c7778a7c0113190051415e096f5db94f Reviewed-on: https://go-review.googlesource.com/11390 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Andrew Gerrand <adg@golang.org>
488 lines
7.6 KiB
Go
488 lines
7.6 KiB
Go
// run
|
|
|
|
// Copyright 2009 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// Test equality and inequality operations.
|
|
|
|
package main
|
|
|
|
import (
|
|
"os"
|
|
"unsafe"
|
|
)
|
|
|
|
var global bool
|
|
|
|
func use(b bool) { global = b }
|
|
|
|
func stringptr(s string) uintptr { return *(*uintptr)(unsafe.Pointer(&s)) }
|
|
|
|
func isfalse(b bool) {
|
|
if b {
|
|
// stack will explain where
|
|
panic("wanted false, got true")
|
|
}
|
|
}
|
|
|
|
func istrue(b bool) {
|
|
if !b {
|
|
// stack will explain where
|
|
panic("wanted true, got false")
|
|
}
|
|
}
|
|
|
|
type T *int
|
|
|
|
type X int
|
|
|
|
func (X) x() {}
|
|
|
|
func main() {
|
|
var a []int
|
|
var b map[string]int
|
|
|
|
var c string = "hello"
|
|
var d string = "hel" // try to get different pointer
|
|
d = d + "lo"
|
|
|
|
// go.tools/ssa/interp can't handle unsafe.Pointer.
|
|
if os.Getenv("GOSSAINTERP") == "" {
|
|
if stringptr(c) == stringptr(d) {
|
|
panic("compiler too smart -- got same string")
|
|
}
|
|
}
|
|
|
|
var e = make(chan int)
|
|
|
|
var ia interface{} = a
|
|
var ib interface{} = b
|
|
var ic interface{} = c
|
|
var id interface{} = d
|
|
var ie interface{} = e
|
|
|
|
// these comparisons are okay because
|
|
// string compare is okay and the others
|
|
// are comparisons where the types differ.
|
|
isfalse(ia == ib)
|
|
isfalse(ia == ic)
|
|
isfalse(ia == id)
|
|
isfalse(ib == ic)
|
|
isfalse(ib == id)
|
|
istrue(ic == id)
|
|
istrue(ie == ie)
|
|
|
|
istrue(ia != ib)
|
|
istrue(ia != ic)
|
|
istrue(ia != id)
|
|
istrue(ib != ic)
|
|
istrue(ib != id)
|
|
isfalse(ic != id)
|
|
isfalse(ie != ie)
|
|
|
|
// these are not okay, because there is no comparison on slices or maps.
|
|
//isfalse(a == ib)
|
|
//isfalse(a == ic)
|
|
//isfalse(a == id)
|
|
//isfalse(b == ic)
|
|
//isfalse(b == id)
|
|
|
|
istrue(c == id)
|
|
istrue(e == ie)
|
|
|
|
//isfalse(ia == b)
|
|
isfalse(ia == c)
|
|
isfalse(ia == d)
|
|
isfalse(ib == c)
|
|
isfalse(ib == d)
|
|
istrue(ic == d)
|
|
istrue(ie == e)
|
|
|
|
//istrue(a != ib)
|
|
//istrue(a != ic)
|
|
//istrue(a != id)
|
|
//istrue(b != ic)
|
|
//istrue(b != id)
|
|
isfalse(c != id)
|
|
isfalse(e != ie)
|
|
|
|
//istrue(ia != b)
|
|
istrue(ia != c)
|
|
istrue(ia != d)
|
|
istrue(ib != c)
|
|
istrue(ib != d)
|
|
isfalse(ic != d)
|
|
isfalse(ie != e)
|
|
|
|
// gc used to let this go through as true.
|
|
var g uint64 = 123
|
|
var h int64 = 123
|
|
var ig interface{} = g
|
|
var ih interface{} = h
|
|
isfalse(ig == ih)
|
|
istrue(ig != ih)
|
|
|
|
// map of interface should use == on interface values,
|
|
// not memory.
|
|
var m = make(map[interface{}]int)
|
|
m[ic] = 1
|
|
m[id] = 2
|
|
if m[c] != 2 {
|
|
println("m[c] = ", m[c])
|
|
panic("bad m[c]")
|
|
}
|
|
|
|
// interface comparisons (issue 7207)
|
|
{
|
|
type I1 interface {
|
|
x()
|
|
}
|
|
type I2 interface {
|
|
x()
|
|
}
|
|
a1 := I1(X(0))
|
|
b1 := I1(X(1))
|
|
a2 := I2(X(0))
|
|
b2 := I2(X(1))
|
|
a3 := I1(a2)
|
|
a4 := I2(a1)
|
|
var e interface{} = X(0)
|
|
a5 := e.(I1)
|
|
a6 := e.(I2)
|
|
isfalse(a1 == b1)
|
|
isfalse(a1 == b2)
|
|
isfalse(a2 == b1)
|
|
isfalse(a2 == b2)
|
|
istrue(a1 == a2)
|
|
istrue(a1 == a3)
|
|
istrue(a1 == a4)
|
|
istrue(a1 == a5)
|
|
istrue(a1 == a6)
|
|
istrue(a2 == a3)
|
|
istrue(a2 == a4)
|
|
istrue(a2 == a5)
|
|
istrue(a2 == a6)
|
|
istrue(a3 == a4)
|
|
istrue(a3 == a5)
|
|
istrue(a3 == a6)
|
|
istrue(a4 == a5)
|
|
istrue(a4 == a6)
|
|
istrue(a5 == a6)
|
|
}
|
|
|
|
// non-interface comparisons
|
|
{
|
|
c := make(chan int)
|
|
c1 := (<-chan int)(c)
|
|
c2 := (chan<- int)(c)
|
|
istrue(c == c1)
|
|
istrue(c == c2)
|
|
istrue(c1 == c)
|
|
istrue(c2 == c)
|
|
|
|
isfalse(c != c1)
|
|
isfalse(c != c2)
|
|
isfalse(c1 != c)
|
|
isfalse(c2 != c)
|
|
|
|
d := make(chan int)
|
|
isfalse(c == d)
|
|
isfalse(d == c)
|
|
isfalse(d == c1)
|
|
isfalse(d == c2)
|
|
isfalse(c1 == d)
|
|
isfalse(c2 == d)
|
|
|
|
istrue(c != d)
|
|
istrue(d != c)
|
|
istrue(d != c1)
|
|
istrue(d != c2)
|
|
istrue(c1 != d)
|
|
istrue(c2 != d)
|
|
}
|
|
|
|
// named types vs not
|
|
{
|
|
var x = new(int)
|
|
var y T
|
|
var z T = x
|
|
|
|
isfalse(x == y)
|
|
istrue(x == z)
|
|
isfalse(y == z)
|
|
|
|
isfalse(y == x)
|
|
istrue(z == x)
|
|
isfalse(z == y)
|
|
|
|
istrue(x != y)
|
|
isfalse(x != z)
|
|
istrue(y != z)
|
|
|
|
istrue(y != x)
|
|
isfalse(z != x)
|
|
istrue(z != y)
|
|
}
|
|
|
|
// structs
|
|
{
|
|
var x = struct {
|
|
x int
|
|
y string
|
|
}{1, "hi"}
|
|
var y = struct {
|
|
x int
|
|
y string
|
|
}{2, "bye"}
|
|
var z = struct {
|
|
x int
|
|
y string
|
|
}{1, "hi"}
|
|
|
|
isfalse(x == y)
|
|
isfalse(y == x)
|
|
isfalse(y == z)
|
|
isfalse(z == y)
|
|
istrue(x == z)
|
|
istrue(z == x)
|
|
|
|
istrue(x != y)
|
|
istrue(y != x)
|
|
istrue(y != z)
|
|
istrue(z != y)
|
|
isfalse(x != z)
|
|
isfalse(z != x)
|
|
|
|
var m = make(map[struct {
|
|
x int
|
|
y string
|
|
}]int)
|
|
m[x] = 10
|
|
m[y] = 20
|
|
m[z] = 30
|
|
istrue(m[x] == 30)
|
|
istrue(m[y] == 20)
|
|
istrue(m[z] == 30)
|
|
istrue(m[x] != 10)
|
|
isfalse(m[x] != 30)
|
|
isfalse(m[y] != 20)
|
|
isfalse(m[z] != 30)
|
|
isfalse(m[x] == 10)
|
|
|
|
var m1 = make(map[struct {
|
|
x int
|
|
y string
|
|
}]struct {
|
|
x int
|
|
y string
|
|
})
|
|
m1[x] = x
|
|
m1[y] = y
|
|
m1[z] = z
|
|
istrue(m1[x] == z)
|
|
istrue(m1[y] == y)
|
|
istrue(m1[z] == z)
|
|
istrue(m1[x] == x)
|
|
isfalse(m1[x] != z)
|
|
isfalse(m1[y] != y)
|
|
isfalse(m1[z] != z)
|
|
isfalse(m1[x] != x)
|
|
|
|
var ix, iy, iz interface{} = x, y, z
|
|
|
|
isfalse(ix == iy)
|
|
isfalse(iy == ix)
|
|
isfalse(iy == iz)
|
|
isfalse(iz == iy)
|
|
istrue(ix == iz)
|
|
istrue(iz == ix)
|
|
|
|
isfalse(x == iy)
|
|
isfalse(y == ix)
|
|
isfalse(y == iz)
|
|
isfalse(z == iy)
|
|
istrue(x == iz)
|
|
istrue(z == ix)
|
|
|
|
isfalse(ix == y)
|
|
isfalse(iy == x)
|
|
isfalse(iy == z)
|
|
isfalse(iz == y)
|
|
istrue(ix == z)
|
|
istrue(iz == x)
|
|
|
|
istrue(ix != iy)
|
|
istrue(iy != ix)
|
|
istrue(iy != iz)
|
|
istrue(iz != iy)
|
|
isfalse(ix != iz)
|
|
isfalse(iz != ix)
|
|
|
|
istrue(x != iy)
|
|
istrue(y != ix)
|
|
istrue(y != iz)
|
|
istrue(z != iy)
|
|
isfalse(x != iz)
|
|
isfalse(z != ix)
|
|
|
|
istrue(ix != y)
|
|
istrue(iy != x)
|
|
istrue(iy != z)
|
|
istrue(iz != y)
|
|
isfalse(ix != z)
|
|
isfalse(iz != x)
|
|
}
|
|
|
|
// structs with _ fields
|
|
{
|
|
var x = struct {
|
|
x int
|
|
_ string
|
|
y float64
|
|
_ float64
|
|
z int
|
|
}{
|
|
x: 1, y: 2, z: 3,
|
|
}
|
|
var ix interface{} = x
|
|
|
|
istrue(x == x)
|
|
istrue(x == ix)
|
|
istrue(ix == x)
|
|
istrue(ix == ix)
|
|
}
|
|
|
|
// arrays
|
|
{
|
|
var x = [2]string{"1", "hi"}
|
|
var y = [2]string{"2", "bye"}
|
|
var z = [2]string{"1", "hi"}
|
|
|
|
isfalse(x == y)
|
|
isfalse(y == x)
|
|
isfalse(y == z)
|
|
isfalse(z == y)
|
|
istrue(x == z)
|
|
istrue(z == x)
|
|
|
|
istrue(x != y)
|
|
istrue(y != x)
|
|
istrue(y != z)
|
|
istrue(z != y)
|
|
isfalse(x != z)
|
|
isfalse(z != x)
|
|
|
|
var m = make(map[[2]string]int)
|
|
m[x] = 10
|
|
m[y] = 20
|
|
m[z] = 30
|
|
istrue(m[x] == 30)
|
|
istrue(m[y] == 20)
|
|
istrue(m[z] == 30)
|
|
isfalse(m[x] != 30)
|
|
isfalse(m[y] != 20)
|
|
isfalse(m[z] != 30)
|
|
|
|
var ix, iy, iz interface{} = x, y, z
|
|
|
|
isfalse(ix == iy)
|
|
isfalse(iy == ix)
|
|
isfalse(iy == iz)
|
|
isfalse(iz == iy)
|
|
istrue(ix == iz)
|
|
istrue(iz == ix)
|
|
|
|
isfalse(x == iy)
|
|
isfalse(y == ix)
|
|
isfalse(y == iz)
|
|
isfalse(z == iy)
|
|
istrue(x == iz)
|
|
istrue(z == ix)
|
|
|
|
isfalse(ix == y)
|
|
isfalse(iy == x)
|
|
isfalse(iy == z)
|
|
isfalse(iz == y)
|
|
istrue(ix == z)
|
|
istrue(iz == x)
|
|
|
|
istrue(ix != iy)
|
|
istrue(iy != ix)
|
|
istrue(iy != iz)
|
|
istrue(iz != iy)
|
|
isfalse(ix != iz)
|
|
isfalse(iz != ix)
|
|
|
|
istrue(x != iy)
|
|
istrue(y != ix)
|
|
istrue(y != iz)
|
|
istrue(z != iy)
|
|
isfalse(x != iz)
|
|
isfalse(z != ix)
|
|
|
|
istrue(ix != y)
|
|
istrue(iy != x)
|
|
istrue(iy != z)
|
|
istrue(iz != y)
|
|
isfalse(ix != z)
|
|
isfalse(iz != x)
|
|
}
|
|
|
|
// named booleans
|
|
{
|
|
type mybool bool
|
|
var b mybool
|
|
|
|
type T struct{ data [20]byte }
|
|
var x, y T
|
|
b = x == y
|
|
istrue(x == y)
|
|
istrue(bool(b))
|
|
|
|
m := make(map[string][10]interface{})
|
|
b = m["x"] == m["y"]
|
|
istrue(m["x"] == m["y"])
|
|
istrue(bool(b))
|
|
}
|
|
|
|
shouldPanic(p1)
|
|
shouldPanic(p2)
|
|
shouldPanic(p3)
|
|
shouldPanic(p4)
|
|
}
|
|
|
|
func p1() {
|
|
var a []int
|
|
var ia interface{} = a
|
|
use(ia == ia)
|
|
}
|
|
|
|
func p2() {
|
|
var b []int
|
|
var ib interface{} = b
|
|
use(ib == ib)
|
|
}
|
|
|
|
func p3() {
|
|
var a []int
|
|
var ia interface{} = a
|
|
var m = make(map[interface{}]int)
|
|
m[ia] = 1
|
|
}
|
|
|
|
func p4() {
|
|
var b []int
|
|
var ib interface{} = b
|
|
var m = make(map[interface{}]int)
|
|
m[ib] = 1
|
|
}
|
|
|
|
func shouldPanic(f func()) {
|
|
defer func() {
|
|
if recover() == nil {
|
|
panic("function should panic")
|
|
}
|
|
}()
|
|
f()
|
|
}
|