summaryrefslogtreecommitdiffstats
path: root/test/interface
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 13:18:25 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 13:18:25 +0000
commit109be507377fe7f6e8819ac94041d3fdcdf6fd2f (patch)
tree2806a689f8fab4a2ec9fc949830ef270a91d667d /test/interface
parentInitial commit. (diff)
downloadgolang-1.19-109be507377fe7f6e8819ac94041d3fdcdf6fd2f.tar.xz
golang-1.19-109be507377fe7f6e8819ac94041d3fdcdf6fd2f.zip
Adding upstream version 1.19.8.upstream/1.19.8upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--test/interface/assertinline.go74
-rw-r--r--test/interface/bigdata.go74
-rw-r--r--test/interface/convert.go146
-rw-r--r--test/interface/convert1.go24
-rw-r--r--test/interface/convert2.go24
-rw-r--r--test/interface/embed.go61
-rw-r--r--test/interface/embed1.dir/embed0.go28
-rw-r--r--test/interface/embed1.dir/embed1.go43
-rw-r--r--test/interface/embed1.go9
-rw-r--r--test/interface/embed2.go75
-rw-r--r--test/interface/embed3.dir/embed0.go21
-rw-r--r--test/interface/embed3.dir/embed1.go78
-rw-r--r--test/interface/embed3.go7
-rw-r--r--test/interface/explicit.go106
-rw-r--r--test/interface/fail.go39
-rw-r--r--test/interface/fake.go97
-rw-r--r--test/interface/noeq.go40
-rw-r--r--test/interface/pointer.go37
-rw-r--r--test/interface/private.dir/private1.go18
-rw-r--r--test/interface/private.dir/prog.go33
-rw-r--r--test/interface/private.go10
-rw-r--r--test/interface/receiver.go121
-rw-r--r--test/interface/receiver1.go59
-rw-r--r--test/interface/recursive.go21
-rw-r--r--test/interface/recursive1.dir/recursive1.go15
-rw-r--r--test/interface/recursive1.dir/recursive2.go20
-rw-r--r--test/interface/recursive1.go9
-rw-r--r--test/interface/returntype.go38
-rw-r--r--test/interface/struct.go156
29 files changed, 1483 insertions, 0 deletions
diff --git a/test/interface/assertinline.go b/test/interface/assertinline.go
new file mode 100644
index 0000000..324316b
--- /dev/null
+++ b/test/interface/assertinline.go
@@ -0,0 +1,74 @@
+// errorcheck -0 -d=typeassert
+
+// Copyright 2015 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.
+
+package p
+
+func assertptr(x interface{}) *int {
+ return x.(*int) // ERROR "type assertion inlined"
+}
+
+func assertptr2(x interface{}) (*int, bool) {
+ z, ok := x.(*int) // ERROR "type assertion inlined"
+ return z, ok
+}
+
+func assertfunc(x interface{}) func() {
+ return x.(func()) // ERROR "type assertion inlined"
+}
+
+func assertfunc2(x interface{}) (func(), bool) {
+ z, ok := x.(func()) // ERROR "type assertion inlined"
+ return z, ok
+}
+
+func assertstruct(x interface{}) struct{ *int } {
+ return x.(struct{ *int }) // ERROR "type assertion inlined"
+}
+
+func assertstruct2(x interface{}) (struct{ *int }, bool) {
+ z, ok := x.(struct{ *int }) // ERROR "type assertion inlined"
+ return z, ok
+}
+
+func assertbig(x interface{}) complex128 {
+ return x.(complex128) // ERROR "type assertion inlined"
+}
+
+func assertbig2(x interface{}) (complex128, bool) {
+ z, ok := x.(complex128) // ERROR "type assertion inlined"
+ return z, ok
+}
+
+func assertbig2ok(x interface{}) (complex128, bool) {
+ _, ok := x.(complex128) // ERROR "type assertion inlined"
+ return 0, ok
+}
+
+func assertslice(x interface{}) []int {
+ return x.([]int) // ERROR "type assertion inlined"
+}
+
+func assertslice2(x interface{}) ([]int, bool) {
+ z, ok := x.([]int) // ERROR "type assertion inlined"
+ return z, ok
+}
+
+func assertslice2ok(x interface{}) ([]int, bool) {
+ _, ok := x.([]int) // ERROR "type assertion inlined"
+ return nil, ok
+}
+
+type I interface {
+ foo()
+}
+
+func assertInter(x interface{}) I {
+ return x.(I) // ERROR "type assertion not inlined"
+}
+func assertInter2(x interface{}) (I, bool) {
+ z, ok := x.(I) // ERROR "type assertion not inlined"
+ return z, ok
+}
diff --git a/test/interface/bigdata.go b/test/interface/bigdata.go
new file mode 100644
index 0000000..0f2e9a9
--- /dev/null
+++ b/test/interface/bigdata.go
@@ -0,0 +1,74 @@
+// 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 big vs. small, pointer vs. value interface methods.
+
+package main
+
+type I interface { M() int64 }
+
+type BigPtr struct { a, b, c, d int64 }
+func (z *BigPtr) M() int64 { return z.a+z.b+z.c+z.d }
+
+type SmallPtr struct { a int32 }
+func (z *SmallPtr) M() int64 { return int64(z.a) }
+
+type IntPtr int32
+func (z *IntPtr) M() int64 { return int64(*z) }
+
+var bad bool
+
+func test(name string, i I) {
+ m := i.M()
+ if m != 12345 {
+ println(name, m)
+ bad = true
+ }
+}
+
+func ptrs() {
+ var bigptr BigPtr = BigPtr{ 10000, 2000, 300, 45 }
+ var smallptr SmallPtr = SmallPtr{ 12345 }
+ var intptr IntPtr = 12345
+
+// test("bigptr", bigptr)
+ test("&bigptr", &bigptr)
+// test("smallptr", smallptr)
+ test("&smallptr", &smallptr)
+// test("intptr", intptr)
+ test("&intptr", &intptr)
+}
+
+type Big struct { a, b, c, d int64 }
+func (z Big) M() int64 { return z.a+z.b+z.c+z.d }
+
+type Small struct { a int32 }
+func (z Small) M() int64 { return int64(z.a) }
+
+type Int int32
+func (z Int) M() int64 { return int64(z) }
+
+func nonptrs() {
+ var big Big = Big{ 10000, 2000, 300, 45 }
+ var small Small = Small{ 12345 }
+ var int Int = 12345
+
+ test("big", big)
+ test("&big", &big)
+ test("small", small)
+ test("&small", &small)
+ test("int", int)
+ test("&int", &int)
+}
+
+func main() {
+ ptrs()
+ nonptrs()
+
+ if bad {
+ println("BUG: interface4")
+ }
+}
diff --git a/test/interface/convert.go b/test/interface/convert.go
new file mode 100644
index 0000000..eb6fd1d
--- /dev/null
+++ b/test/interface/convert.go
@@ -0,0 +1,146 @@
+// 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 all the different interface conversion runtime functions.
+
+package main
+
+type Stringer interface {
+ String() string
+}
+type StringLengther interface {
+ String() string
+ Length() int
+}
+type Empty interface{}
+
+type T string
+
+func (t T) String() string {
+ return string(t)
+}
+func (t T) Length() int {
+ return len(t)
+}
+
+type U string
+
+func (u U) String() string {
+ return string(u)
+}
+
+var t = T("hello")
+var u = U("goodbye")
+var e Empty
+var s Stringer = t
+var sl StringLengther = t
+var i int
+var ok bool
+
+func hello(s string) {
+ if s != "hello" {
+ println("not hello: ", s)
+ panic("fail")
+ }
+}
+
+func five(i int) {
+ if i != 5 {
+ println("not 5: ", i)
+ panic("fail")
+ }
+}
+
+func true(ok bool) {
+ if !ok {
+ panic("not true")
+ }
+}
+
+func false(ok bool) {
+ if ok {
+ panic("not false")
+ }
+}
+
+func main() {
+ // T2I
+ s = t
+ hello(s.String())
+
+ // I2T
+ t = s.(T)
+ hello(t.String())
+
+ // T2E
+ e = t
+
+ // E2T
+ t = e.(T)
+ hello(t.String())
+
+ // T2I again
+ sl = t
+ hello(sl.String())
+ five(sl.Length())
+
+ // I2I static
+ s = sl
+ hello(s.String())
+
+ // I2I dynamic
+ sl = s.(StringLengther)
+ hello(sl.String())
+ five(sl.Length())
+
+ // I2E (and E2T)
+ e = s
+ hello(e.(T).String())
+
+ // E2I
+ s = e.(Stringer)
+ hello(s.String())
+
+ // I2T2 true
+ t, ok = s.(T)
+ true(ok)
+ hello(t.String())
+
+ // I2T2 false
+ _, ok = s.(U)
+ false(ok)
+
+ // I2I2 true
+ sl, ok = s.(StringLengther)
+ true(ok)
+ hello(sl.String())
+ five(sl.Length())
+
+ // I2I2 false (and T2I)
+ s = u
+ sl, ok = s.(StringLengther)
+ false(ok)
+
+ // E2T2 true
+ t, ok = e.(T)
+ true(ok)
+ hello(t.String())
+
+ // E2T2 false
+ i, ok = e.(int)
+ false(ok)
+
+ // E2I2 true
+ sl, ok = e.(StringLengther)
+ true(ok)
+ hello(sl.String())
+ five(sl.Length())
+
+ // E2I2 false (and T2E)
+ e = u
+ sl, ok = e.(StringLengther)
+ false(ok)
+}
diff --git a/test/interface/convert1.go b/test/interface/convert1.go
new file mode 100644
index 0000000..4a3ec8a
--- /dev/null
+++ b/test/interface/convert1.go
@@ -0,0 +1,24 @@
+// 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 static interface conversion of interface value nil.
+
+package main
+
+type R interface { R() }
+type RW interface { R(); W() }
+
+var e interface {}
+var r R
+var rw RW
+
+func main() {
+ r = r
+ r = rw
+ e = r
+ e = rw
+ rw = rw
+}
diff --git a/test/interface/convert2.go b/test/interface/convert2.go
new file mode 100644
index 0000000..4a3ec8a
--- /dev/null
+++ b/test/interface/convert2.go
@@ -0,0 +1,24 @@
+// 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 static interface conversion of interface value nil.
+
+package main
+
+type R interface { R() }
+type RW interface { R(); W() }
+
+var e interface {}
+var r R
+var rw RW
+
+func main() {
+ r = r
+ r = rw
+ e = r
+ e = rw
+ rw = rw
+}
diff --git a/test/interface/embed.go b/test/interface/embed.go
new file mode 100644
index 0000000..5c52ac0
--- /dev/null
+++ b/test/interface/embed.go
@@ -0,0 +1,61 @@
+// 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 methods derived from embedded interface values.
+
+package main
+
+import "os"
+
+const Value = 1e12
+
+type Inter interface { M() int64 }
+
+type T int64
+func (t T) M() int64 { return int64(t) }
+var t = T(Value)
+var pt = &t
+var ti Inter = t
+
+type S struct { Inter }
+var s = S{ ti }
+var ps = &s
+
+var i Inter
+
+var ok = true
+
+func check(s string, v int64) {
+ if v != Value {
+ println(s, v)
+ ok = false
+ }
+}
+
+func main() {
+ check("t.M()", t.M())
+ check("pt.M()", pt.M())
+ check("ti.M()", ti.M())
+ check("s.M()", s.M())
+ check("ps.M()", ps.M())
+
+ i = t
+ check("i = t; i.M()", i.M())
+
+ i = pt
+ check("i = pt; i.M()", i.M())
+
+ i = s
+ check("i = s; i.M()", i.M())
+
+ i = ps
+ check("i = ps; i.M()", i.M())
+
+ if !ok {
+ println("BUG: interface10")
+ os.Exit(1)
+ }
+}
diff --git a/test/interface/embed1.dir/embed0.go b/test/interface/embed1.dir/embed0.go
new file mode 100644
index 0000000..4aed391
--- /dev/null
+++ b/test/interface/embed1.dir/embed0.go
@@ -0,0 +1,28 @@
+// 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 that embedded interface types can have local methods.
+
+package p
+
+type T int
+
+func (t T) m() {}
+
+type I interface{ m() }
+type J interface{ I }
+
+func main() {
+ var i I
+ var j J
+ var t T
+ i = t
+ j = t
+ _ = i
+ _ = j
+ i = j
+ _ = i
+ j = i
+ _ = j
+}
diff --git a/test/interface/embed1.dir/embed1.go b/test/interface/embed1.dir/embed1.go
new file mode 100644
index 0000000..7dfb1db
--- /dev/null
+++ b/test/interface/embed1.dir/embed1.go
@@ -0,0 +1,43 @@
+// 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 that embedded interface types can have local methods.
+
+package main
+
+import "./embed0"
+
+type T int
+func (t T) m() {}
+
+type I interface { m() }
+type J interface { I }
+
+type PI interface { p.I }
+type PJ interface { p.J }
+
+func main() {
+ var i I
+ var j J
+ var t T
+ i = t
+ j = t
+ _ = i
+ _ = j
+ i = j
+ _ = i
+ j = i
+ _ = j
+ var pi PI
+ var pj PJ
+ var pt p.T
+ pi = pt
+ pj = pt
+ _ = pi
+ _ = pj
+ pi = pj
+ _ = pi
+ pj = pi
+ _ = pj
+}
diff --git a/test/interface/embed1.go b/test/interface/embed1.go
new file mode 100644
index 0000000..784b82b
--- /dev/null
+++ b/test/interface/embed1.go
@@ -0,0 +1,9 @@
+// rundir
+
+// 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 that embedded interface types can have local methods.
+
+package ignored
diff --git a/test/interface/embed2.go b/test/interface/embed2.go
new file mode 100644
index 0000000..97a2d96
--- /dev/null
+++ b/test/interface/embed2.go
@@ -0,0 +1,75 @@
+// errorcheck
+
+// 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 methods derived from embedded interface and *interface values.
+
+package main
+
+import "os"
+
+const Value = 1e12
+
+type Inter interface {
+ M() int64
+}
+
+type T int64
+
+func (t T) M() int64 { return int64(t) }
+
+var t = T(Value)
+var pt = &t
+var ti Inter = t
+var pti = &ti
+
+type S struct{ Inter }
+
+var s = S{ti}
+var ps = &s
+
+type SP struct{ *Inter } // ERROR "interface"
+
+var i Inter
+var pi = &i
+
+var ok = true
+
+func check(s string, v int64) {
+ if v != Value {
+ println(s, v)
+ ok = false
+ }
+}
+
+func main() {
+ check("t.M()", t.M())
+ check("pt.M()", pt.M())
+ check("ti.M()", ti.M())
+ check("pti.M()", pti.M()) // ERROR "pointer to interface, not interface|no field or method M"
+ check("s.M()", s.M())
+ check("ps.M()", ps.M())
+
+ i = t
+ check("i = t; i.M()", i.M())
+ check("i = t; pi.M()", pi.M()) // ERROR "pointer to interface, not interface|no field or method M"
+
+ i = pt
+ check("i = pt; i.M()", i.M())
+ check("i = pt; pi.M()", pi.M()) // ERROR "pointer to interface, not interface|no field or method M"
+
+ i = s
+ check("i = s; i.M()", i.M())
+ check("i = s; pi.M()", pi.M()) // ERROR "pointer to interface, not interface|no field or method M"
+
+ i = ps
+ check("i = ps; i.M()", i.M())
+ check("i = ps; pi.M()", pi.M()) // ERROR "pointer to interface, not interface|no field or method M"
+
+ if !ok {
+ println("BUG: interface10")
+ os.Exit(1)
+ }
+}
diff --git a/test/interface/embed3.dir/embed0.go b/test/interface/embed3.dir/embed0.go
new file mode 100644
index 0000000..614609e
--- /dev/null
+++ b/test/interface/embed3.dir/embed0.go
@@ -0,0 +1,21 @@
+// Copyright 2019 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.
+
+package p
+
+type I1 interface {
+ Foo(int)
+}
+
+type I2 interface {
+ foo(int)
+}
+
+type M1 int
+
+func (M1) foo() {}
+
+type M2 int
+
+func (M2) foo(int) {}
diff --git a/test/interface/embed3.dir/embed1.go b/test/interface/embed3.dir/embed1.go
new file mode 100644
index 0000000..d042482
--- /dev/null
+++ b/test/interface/embed3.dir/embed1.go
@@ -0,0 +1,78 @@
+// Copyright 2019 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.
+
+package main
+
+import "./embed0"
+
+type X1 struct{}
+
+func (X1) Foo() {}
+
+type X2 struct{}
+
+func (X2) foo() {}
+
+type X3 struct{}
+
+func (X3) foo(int) {}
+
+type X4 struct{ p.M1 }
+
+type X5 struct{ p.M1 }
+
+func (X5) foo(int) {}
+
+type X6 struct{ p.M2 }
+
+type X7 struct{ p.M2 }
+
+func (X7) foo() {}
+
+type X8 struct{ p.M2 }
+
+func (X8) foo(int) {}
+
+func main() {
+ var i1 interface{} = X1{}
+ check(func() { _ = i1.(p.I1) }, "interface conversion: main.X1 is not p.I1: missing method Foo")
+
+ var i2 interface{} = X2{}
+ check(func() { _ = i2.(p.I2) }, "interface conversion: main.X2 is not p.I2: missing method foo")
+
+ var i3 interface{} = X3{}
+ check(func() { _ = i3.(p.I2) }, "interface conversion: main.X3 is not p.I2: missing method foo")
+
+ var i4 interface{} = X4{}
+ check(func() { _ = i4.(p.I2) }, "interface conversion: main.X4 is not p.I2: missing method foo")
+
+ var i5 interface{} = X5{}
+ check(func() { _ = i5.(p.I2) }, "interface conversion: main.X5 is not p.I2: missing method foo")
+
+ var i6 interface{} = X6{}
+ check(func() { _ = i6.(p.I2) }, "")
+
+ var i7 interface{} = X7{}
+ check(func() { _ = i7.(p.I2) }, "")
+
+ var i8 interface{} = X8{}
+ check(func() { _ = i8.(p.I2) }, "")
+}
+
+func check(f func(), msg string) {
+ defer func() {
+ v := recover()
+ if v == nil {
+ if msg == "" {
+ return
+ }
+ panic("did not panic")
+ }
+ got := v.(error).Error()
+ if msg != got {
+ panic("want '" + msg + "', got '" + got + "'")
+ }
+ }()
+ f()
+}
diff --git a/test/interface/embed3.go b/test/interface/embed3.go
new file mode 100644
index 0000000..af6f134
--- /dev/null
+++ b/test/interface/embed3.go
@@ -0,0 +1,7 @@
+// rundir
+
+// Copyright 2019 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.
+
+package ignored
diff --git a/test/interface/explicit.go b/test/interface/explicit.go
new file mode 100644
index 0000000..e18d684
--- /dev/null
+++ b/test/interface/explicit.go
@@ -0,0 +1,106 @@
+// errorcheck
+
+// 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.
+
+// Verify compiler messages about erroneous static interface conversions.
+// Does not compile.
+
+package main
+
+type T struct {
+ a int
+}
+
+var t *T
+
+type X int
+
+func (x *X) M() {}
+
+type I interface {
+ M()
+}
+
+var i I
+
+type I2 interface {
+ M()
+ N()
+}
+
+var i2 I2
+
+type E interface{}
+
+var e E
+
+func main() {
+ e = t // ok
+ t = e // ERROR "need explicit|need type assertion"
+
+ // neither of these can work,
+ // because i has an extra method
+ // that t does not, so i cannot contain a t.
+ i = t // ERROR "incompatible|missing M method"
+ t = i // ERROR "incompatible|assignment$"
+
+ i = i2 // ok
+ i2 = i // ERROR "incompatible|missing N method"
+
+ i = I(i2) // ok
+ i2 = I2(i) // ERROR "invalid|missing N method|cannot convert"
+
+ e = E(t) // ok
+ t = T(e) // ERROR "need explicit|need type assertion|incompatible|cannot convert"
+
+ // cannot type-assert non-interfaces
+ f := 2.0
+ _ = f.(int) // ERROR "non-interface type|only valid for interface types|not an interface"
+
+}
+
+type M interface {
+ M()
+}
+
+var m M
+
+var _ = m.(int) // ERROR "impossible type assertion"
+
+type Int int
+
+func (Int) M(float64) {}
+
+var _ = m.(Int) // ERROR "impossible type assertion"
+
+var _ = m.(X) // ERROR "pointer receiver"
+
+var ii int
+var jj Int
+
+var m1 M = ii // ERROR "incompatible|missing"
+var m2 M = jj // ERROR "incompatible|wrong type for M method"
+
+var m3 = M(ii) // ERROR "invalid|missing|cannot convert"
+var m4 = M(jj) // ERROR "invalid|wrong type for M method|cannot convert"
+
+type B1 interface {
+ _() // ERROR "methods must have a unique non-blank name"
+}
+
+type B2 interface {
+ M()
+ _() // ERROR "methods must have a unique non-blank name"
+}
+
+type T2 struct{}
+
+func (t *T2) M() {}
+func (t *T2) _() {}
+
+// Already reported about the invalid blank interface method above;
+// no need to report about not implementing it.
+var b1 B1 = &T2{}
+var b2 B2 = &T2{}
diff --git a/test/interface/fail.go b/test/interface/fail.go
new file mode 100644
index 0000000..d40a151
--- /dev/null
+++ b/test/interface/fail.go
@@ -0,0 +1,39 @@
+// 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 that interface conversion fails when method is missing.
+
+package main
+
+type I interface {
+ Foo()
+}
+
+func main() {
+ shouldPanic(p1)
+}
+
+func p1() {
+ var s *S
+ var i I
+ var e interface{}
+ e = s
+ i = e.(I)
+ _ = i
+}
+
+type S struct{}
+
+func (s *S) _() {}
+
+func shouldPanic(f func()) {
+ defer func() {
+ if recover() == nil {
+ panic("function should panic")
+ }
+ }()
+ f()
+}
diff --git a/test/interface/fake.go b/test/interface/fake.go
new file mode 100644
index 0000000..861a640
--- /dev/null
+++ b/test/interface/fake.go
@@ -0,0 +1,97 @@
+// 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 interface comparisons using types hidden
+// inside reflected-on structs.
+
+package main
+
+import "reflect"
+
+type T struct {
+ F float32
+ G float32
+
+ S string
+ T string
+
+ U uint32
+ V uint32
+
+ W uint32
+ X uint32
+
+ Y uint32
+ Z uint32
+}
+
+func add(s, t string) string {
+ return s + t
+}
+
+func assert(b bool) {
+ if !b {
+ panic("assert")
+ }
+}
+
+func main() {
+ var x T
+ x.F = 1.0
+ x.G = x.F
+ x.S = add("abc", "def")
+ x.T = add("abc", "def")
+ x.U = 1
+ x.V = 2
+ x.W = 1 << 28
+ x.X = 2 << 28
+ x.Y = 0x12345678
+ x.Z = x.Y
+
+ // check mem and string
+ v := reflect.ValueOf(x)
+ i := v.Field(0)
+ j := v.Field(1)
+ assert(i.Interface() == j.Interface())
+
+ s := v.Field(2)
+ t := v.Field(3)
+ assert(s.Interface() == t.Interface())
+
+ // make sure different values are different.
+ // make sure whole word is being compared,
+ // not just a single byte.
+ i = v.Field(4)
+ j = v.Field(5)
+ assert(i.Interface() != j.Interface())
+
+ i = v.Field(6)
+ j = v.Field(7)
+ assert(i.Interface() != j.Interface())
+
+ i = v.Field(8)
+ j = v.Field(9)
+ assert(i.Interface() == j.Interface())
+}
+
+/*
+comparing uncomparable type float32
+throw: interface compare
+
+panic PC=0x28ceb8 [1]
+throw+0x41 /Users/rsc/goX/src/runtime/runtime.c:54
+ throw(0x3014a, 0x0)
+ifaceeq+0x15c /Users/rsc/goX/src/runtime/iface.c:501
+ ifaceeq(0x2aa7c0, 0x0, 0x0, 0x0, 0x2aa7c0, ...)
+sys·ifaceeq+0x48 /Users/rsc/goX/src/runtime/iface.c:527
+ sys·ifaceeq(0x2aa7c0, 0x0, 0x0, 0x0, 0x2aa7c0, ...)
+main·main+0x190 /Users/rsc/goX/src/cmd/gc/x.go:10
+ main·main()
+mainstart+0xf /Users/rsc/goX/src/runtime/amd64/asm.s:53
+ mainstart()
+sys·Goexit /Users/rsc/goX/src/runtime/proc.c:124
+ sys·Goexit()
+*/
diff --git a/test/interface/noeq.go b/test/interface/noeq.go
new file mode 100644
index 0000000..bb36893
--- /dev/null
+++ b/test/interface/noeq.go
@@ -0,0 +1,40 @@
+// run
+
+// Copyright 2011 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 run-time error detection for interface values containing types
+// that cannot be compared for equality.
+
+package main
+
+func main() {
+ cmp(1)
+
+ var (
+ m map[int]int
+ s struct{ x []int }
+ f func()
+ )
+ noCmp(m)
+ noCmp(s)
+ noCmp(f)
+}
+
+func cmp(x interface{}) bool {
+ return x == x
+}
+
+func noCmp(x interface{}) {
+ shouldPanic(func() { cmp(x) })
+}
+
+func shouldPanic(f func()) {
+ defer func() {
+ if recover() == nil {
+ panic("function should panic")
+ }
+ }()
+ f()
+}
diff --git a/test/interface/pointer.go b/test/interface/pointer.go
new file mode 100644
index 0000000..a71b3f4
--- /dev/null
+++ b/test/interface/pointer.go
@@ -0,0 +1,37 @@
+// errorcheck
+
+// 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 that interface{M()} = *interface{M()} produces a compiler error.
+// Does not compile.
+
+package main
+
+type Inst interface {
+ Next() *Inst
+}
+
+type Regexp struct {
+ code []Inst
+ start Inst
+}
+
+type Start struct {
+ foo *Inst
+}
+
+func (start *Start) Next() *Inst { return nil }
+
+func AddInst(Inst) *Inst {
+ print("ok in addinst\n")
+ return nil
+}
+
+func main() {
+ print("call addinst\n")
+ var x Inst = AddInst(new(Start)) // ERROR "pointer to interface|incompatible type"
+ print("return from addinst\n")
+ var y *Inst = new(Start) // ERROR "pointer to interface|incompatible type"
+}
diff --git a/test/interface/private.dir/private1.go b/test/interface/private.dir/private1.go
new file mode 100644
index 0000000..75eee51
--- /dev/null
+++ b/test/interface/private.dir/private1.go
@@ -0,0 +1,18 @@
+// Copyright 2011 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.
+
+// Imported by private.go, which should not be able to see the private method.
+
+package p
+
+type Exported interface {
+ private()
+}
+
+type Implementation struct{}
+
+func (p *Implementation) private() {}
+
+var X = new(Implementation)
+
diff --git a/test/interface/private.dir/prog.go b/test/interface/private.dir/prog.go
new file mode 100644
index 0000000..abea7d6
--- /dev/null
+++ b/test/interface/private.dir/prog.go
@@ -0,0 +1,33 @@
+// Copyright 2011 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 that unexported methods are not visible outside the package.
+// Does not compile.
+
+package main
+
+import "./private1"
+
+type Exported interface {
+ private()
+}
+
+type Implementation struct{}
+
+func (p *Implementation) private() {}
+
+func main() {
+ var x Exported
+ x = new(Implementation)
+ x.private()
+
+ var px p.Exported
+ px = p.X
+
+ px.private() // ERROR "private"
+
+ px = new(Implementation) // ERROR "private"
+
+ x = px // ERROR "private"
+}
diff --git a/test/interface/private.go b/test/interface/private.go
new file mode 100644
index 0000000..a0da249
--- /dev/null
+++ b/test/interface/private.go
@@ -0,0 +1,10 @@
+// errorcheckdir
+
+// Copyright 2011 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 that unexported methods are not visible outside the package.
+// Does not compile.
+
+package ignored
diff --git a/test/interface/receiver.go b/test/interface/receiver.go
new file mode 100644
index 0000000..4511ab3
--- /dev/null
+++ b/test/interface/receiver.go
@@ -0,0 +1,121 @@
+// 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 Implicit methods for embedded types and
+// mixed pointer and non-pointer receivers.
+
+package main
+
+type T int
+
+var nv, np int
+
+func (t T) V() {
+ if t != 42 {
+ panic(t)
+ }
+ nv++
+}
+
+func (t *T) P() {
+ if *t != 42 {
+ println(t, *t)
+ panic("fail")
+ }
+ np++
+}
+
+type V interface {
+ V()
+}
+type P interface {
+ P()
+ V()
+}
+
+type S struct {
+ T
+}
+
+type SP struct {
+ *T
+}
+
+func main() {
+ var t T
+ var v V
+ var p P
+
+ t = 42
+
+ t.P()
+ t.V()
+
+ v = t
+ v.V()
+
+ p = &t
+ p.P()
+ p.V()
+
+ v = &t
+ v.V()
+
+ // p = t // ERROR
+ var i interface{} = t
+ if _, ok := i.(P); ok {
+ println("dynamic i.(P) succeeded incorrectly")
+ panic("fail")
+ }
+
+ // println("--struct--");
+ var s S
+ s.T = 42
+ s.P()
+ s.V()
+
+ v = s
+ s.V()
+
+ p = &s
+ p.P()
+ p.V()
+
+ v = &s
+ v.V()
+
+ // p = s // ERROR
+ var j interface{} = s
+ if _, ok := j.(P); ok {
+ println("dynamic j.(P) succeeded incorrectly")
+ panic("fail")
+ }
+
+ // println("--struct pointer--");
+ var sp SP
+ sp.T = &t
+ sp.P()
+ sp.V()
+
+ v = sp
+ sp.V()
+
+ p = &sp
+ p.P()
+ p.V()
+
+ v = &sp
+ v.V()
+
+ p = sp // not error
+ p.P()
+ p.V()
+
+ if nv != 13 || np != 7 {
+ println("bad count", nv, np)
+ panic("fail")
+ }
+}
diff --git a/test/interface/receiver1.go b/test/interface/receiver1.go
new file mode 100644
index 0000000..a0a8753
--- /dev/null
+++ b/test/interface/receiver1.go
@@ -0,0 +1,59 @@
+// errorcheck
+
+// 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.
+
+// Verify compiler complains about missing implicit methods.
+// Does not compile.
+
+package main
+
+type T int
+
+func (t T) V()
+func (t *T) P()
+
+type V interface {
+ V()
+}
+type P interface {
+ P()
+ V()
+}
+
+type S struct {
+ T
+}
+type SP struct {
+ *T
+}
+
+func main() {
+ var t T
+ var v V
+ var p P
+ var s S
+ var sp SP
+
+ v = t
+ p = t // ERROR "does not implement|requires a pointer|cannot use"
+ _, _ = v, p
+ v = &t
+ p = &t
+ _, _ = v, p
+
+ v = s
+ p = s // ERROR "does not implement|requires a pointer|cannot use"
+ _, _ = v, p
+ v = &s
+ p = &s
+ _, _ = v, p
+
+ v = sp
+ p = sp // no error!
+ _, _ = v, p
+ v = &sp
+ p = &sp
+ _, _ = v, p
+}
diff --git a/test/interface/recursive.go b/test/interface/recursive.go
new file mode 100644
index 0000000..fcc8833
--- /dev/null
+++ b/test/interface/recursive.go
@@ -0,0 +1,21 @@
+// compile
+
+// 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.
+
+// Check mutually recursive interfaces
+
+package recursive
+
+type I1 interface {
+ foo() I2
+}
+
+type I2 interface {
+ bar() I1
+}
+
+type T int
+func (t T) foo() I2 { return t }
+func (t T) bar() I1 { return t }
diff --git a/test/interface/recursive1.dir/recursive1.go b/test/interface/recursive1.dir/recursive1.go
new file mode 100644
index 0000000..8498cb5
--- /dev/null
+++ b/test/interface/recursive1.dir/recursive1.go
@@ -0,0 +1,15 @@
+// Copyright 2012 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.
+
+// Mutually recursive type definitions imported and used by recursive1.go.
+
+package p
+
+type I1 interface {
+ F() I2
+}
+
+type I2 interface {
+ I1
+}
diff --git a/test/interface/recursive1.dir/recursive2.go b/test/interface/recursive1.dir/recursive2.go
new file mode 100644
index 0000000..29385df
--- /dev/null
+++ b/test/interface/recursive1.dir/recursive2.go
@@ -0,0 +1,20 @@
+// Copyright 2012 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 that the mutually recursive types in recursive1.go made it
+// intact and with the same meaning, by assigning to or using them.
+
+package main
+
+import "./recursive1"
+
+func main() {
+ var i1 p.I1
+ var i2 p.I2
+ i1 = i2
+ i2 = i1
+ i1 = i2.F()
+ i2 = i1.F()
+ _, _ = i1, i2
+}
diff --git a/test/interface/recursive1.go b/test/interface/recursive1.go
new file mode 100644
index 0000000..ea2f4eb
--- /dev/null
+++ b/test/interface/recursive1.go
@@ -0,0 +1,9 @@
+// compiledir
+
+// Copyright 2012 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.
+
+// Mutually recursive type definitions imported and used by recursive1.go.
+
+package ignored
diff --git a/test/interface/returntype.go b/test/interface/returntype.go
new file mode 100644
index 0000000..4d86f39
--- /dev/null
+++ b/test/interface/returntype.go
@@ -0,0 +1,38 @@
+// 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 interface methods with different return types are distinct.
+
+package main
+
+type S struct { a int }
+type T struct { b string }
+
+func (s *S) Name() int8 { return 1 }
+func (t *T) Name() int64 { return 64 }
+
+type I1 interface { Name() int8 }
+type I2 interface { Name() int64 }
+
+func main() {
+ shouldPanic(p1)
+}
+
+func p1() {
+ var i1 I1
+ var s *S
+ i1 = s
+ print(i1.(I2).Name())
+}
+
+func shouldPanic(f func()) {
+ defer func() {
+ if recover() == nil {
+ panic("function should panic")
+ }
+ }()
+ f()
+}
diff --git a/test/interface/struct.go b/test/interface/struct.go
new file mode 100644
index 0000000..f60819c
--- /dev/null
+++ b/test/interface/struct.go
@@ -0,0 +1,156 @@
+// 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 interface values containing structures.
+
+package main
+
+import "os"
+
+var fail int
+
+func check(b bool, msg string) {
+ if (!b) {
+ println("failure in", msg)
+ fail++
+ }
+}
+
+type I1 interface { Get() int; Put(int) }
+
+type S1 struct { i int }
+func (p S1) Get() int { return p.i }
+func (p S1) Put(i int) { p.i = i }
+
+func f1() {
+ s := S1{1}
+ var i I1 = s
+ i.Put(2)
+ check(i.Get() == 1, "f1 i")
+ check(s.i == 1, "f1 s")
+}
+
+func f2() {
+ s := S1{1}
+ var i I1 = &s
+ i.Put(2)
+ check(i.Get() == 1, "f2 i")
+ check(s.i == 1, "f2 s")
+}
+
+func f3() {
+ s := &S1{1}
+ var i I1 = s
+ i.Put(2)
+ check(i.Get() == 1, "f3 i")
+ check(s.i == 1, "f3 s")
+}
+
+type S2 struct { i int }
+func (p *S2) Get() int { return p.i }
+func (p *S2) Put(i int) { p.i = i }
+
+// Disallowed by restriction of values going to pointer receivers
+// func f4() {
+// s := S2{1}
+// var i I1 = s
+// i.Put(2)
+// check(i.Get() == 2, "f4 i")
+// check(s.i == 1, "f4 s")
+// }
+
+func f5() {
+ s := S2{1}
+ var i I1 = &s
+ i.Put(2)
+ check(i.Get() == 2, "f5 i")
+ check(s.i == 2, "f5 s")
+}
+
+func f6() {
+ s := &S2{1}
+ var i I1 = s
+ i.Put(2)
+ check(i.Get() == 2, "f6 i")
+ check(s.i == 2, "f6 s")
+}
+
+type I2 interface { Get() int64; Put(int64) }
+
+type S3 struct { i, j, k, l int64 }
+func (p S3) Get() int64 { return p.l }
+func (p S3) Put(i int64) { p.l = i }
+
+func f7() {
+ s := S3{1, 2, 3, 4}
+ var i I2 = s
+ i.Put(5)
+ check(i.Get() == 4, "f7 i")
+ check(s.l == 4, "f7 s")
+}
+
+func f8() {
+ s := S3{1, 2, 3, 4}
+ var i I2 = &s
+ i.Put(5)
+ check(i.Get() == 4, "f8 i")
+ check(s.l == 4, "f8 s")
+}
+
+func f9() {
+ s := &S3{1, 2, 3, 4}
+ var i I2 = s
+ i.Put(5)
+ check(i.Get() == 4, "f9 i")
+ check(s.l == 4, "f9 s")
+}
+
+type S4 struct { i, j, k, l int64 }
+func (p *S4) Get() int64 { return p.l }
+func (p *S4) Put(i int64) { p.l = i }
+
+// Disallowed by restriction of values going to pointer receivers
+// func f10() {
+// s := S4{1, 2, 3, 4}
+// var i I2 = s
+// i.Put(5)
+// check(i.Get() == 5, "f10 i")
+// check(s.l == 4, "f10 s")
+// }
+
+func f11() {
+ s := S4{1, 2, 3, 4}
+ var i I2 = &s
+ i.Put(5)
+ check(i.Get() == 5, "f11 i")
+ check(s.l == 5, "f11 s")
+}
+
+func f12() {
+ s := &S4{1, 2, 3, 4}
+ var i I2 = s
+ i.Put(5)
+ check(i.Get() == 5, "f12 i")
+ check(s.l == 5, "f12 s")
+}
+
+func main() {
+ f1()
+ f2()
+ f3()
+// f4()
+ f5()
+ f6()
+ f7()
+ f8()
+ f9()
+// f10()
+ f11()
+ f12()
+ if fail > 0 {
+ os.Exit(1)
+ }
+}