diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:18:25 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:18:25 +0000 |
commit | 109be507377fe7f6e8819ac94041d3fdcdf6fd2f (patch) | |
tree | 2806a689f8fab4a2ec9fc949830ef270a91d667d /test/interface | |
parent | Initial commit. (diff) | |
download | golang-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 'test/interface')
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) + } +} |