Initial commit: Go 1.23 release state
This commit is contained in:
74
test/interface/assertinline.go
Normal file
74
test/interface/assertinline.go
Normal file
@@ -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
|
||||
}
|
||||
74
test/interface/bigdata.go
Normal file
74
test/interface/bigdata.go
Normal file
@@ -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")
|
||||
}
|
||||
}
|
||||
146
test/interface/convert.go
Normal file
146
test/interface/convert.go
Normal file
@@ -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)
|
||||
}
|
||||
24
test/interface/convert1.go
Normal file
24
test/interface/convert1.go
Normal file
@@ -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
|
||||
}
|
||||
24
test/interface/convert2.go
Normal file
24
test/interface/convert2.go
Normal file
@@ -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
|
||||
}
|
||||
61
test/interface/embed.go
Normal file
61
test/interface/embed.go
Normal file
@@ -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)
|
||||
}
|
||||
}
|
||||
28
test/interface/embed1.dir/embed0.go
Normal file
28
test/interface/embed1.dir/embed0.go
Normal file
@@ -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
|
||||
}
|
||||
43
test/interface/embed1.dir/embed1.go
Normal file
43
test/interface/embed1.dir/embed1.go
Normal file
@@ -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
|
||||
}
|
||||
9
test/interface/embed1.go
Normal file
9
test/interface/embed1.go
Normal file
@@ -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
|
||||
75
test/interface/embed2.go
Normal file
75
test/interface/embed2.go
Normal file
@@ -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)
|
||||
}
|
||||
}
|
||||
21
test/interface/embed3.dir/embed0.go
Normal file
21
test/interface/embed3.dir/embed0.go
Normal file
@@ -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) {}
|
||||
78
test/interface/embed3.dir/embed1.go
Normal file
78
test/interface/embed3.dir/embed1.go
Normal file
@@ -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()
|
||||
}
|
||||
7
test/interface/embed3.go
Normal file
7
test/interface/embed3.go
Normal file
@@ -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
|
||||
106
test/interface/explicit.go
Normal file
106
test/interface/explicit.go
Normal file
@@ -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 method M"
|
||||
t = i // ERROR "incompatible|assignment$"
|
||||
|
||||
i = i2 // ok
|
||||
i2 = i // ERROR "incompatible|missing method N"
|
||||
|
||||
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 method M"
|
||||
|
||||
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{}
|
||||
39
test/interface/fail.go
Normal file
39
test/interface/fail.go
Normal file
@@ -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()
|
||||
}
|
||||
97
test/interface/fake.go
Normal file
97
test/interface/fake.go
Normal file
@@ -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()
|
||||
*/
|
||||
40
test/interface/noeq.go
Normal file
40
test/interface/noeq.go
Normal file
@@ -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()
|
||||
}
|
||||
37
test/interface/pointer.go
Normal file
37
test/interface/pointer.go
Normal file
@@ -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 _ Inst = AddInst(new(Start)) // ERROR "pointer to interface|incompatible type"
|
||||
print("return from addinst\n")
|
||||
var _ *Inst = new(Start) // ERROR "pointer to interface|incompatible type"
|
||||
}
|
||||
18
test/interface/private.dir/private1.go
Normal file
18
test/interface/private.dir/private1.go
Normal file
@@ -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)
|
||||
|
||||
33
test/interface/private.dir/prog.go
Normal file
33
test/interface/private.dir/prog.go
Normal file
@@ -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"
|
||||
}
|
||||
10
test/interface/private.go
Normal file
10
test/interface/private.go
Normal file
@@ -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
|
||||
121
test/interface/receiver.go
Normal file
121
test/interface/receiver.go
Normal file
@@ -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")
|
||||
}
|
||||
}
|
||||
59
test/interface/receiver1.go
Normal file
59
test/interface/receiver1.go
Normal file
@@ -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
|
||||
}
|
||||
21
test/interface/recursive.go
Normal file
21
test/interface/recursive.go
Normal file
@@ -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 }
|
||||
15
test/interface/recursive1.dir/recursive1.go
Normal file
15
test/interface/recursive1.dir/recursive1.go
Normal file
@@ -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
|
||||
}
|
||||
20
test/interface/recursive1.dir/recursive2.go
Normal file
20
test/interface/recursive1.dir/recursive2.go
Normal file
@@ -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
|
||||
}
|
||||
9
test/interface/recursive1.go
Normal file
9
test/interface/recursive1.go
Normal file
@@ -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
|
||||
38
test/interface/returntype.go
Normal file
38
test/interface/returntype.go
Normal file
@@ -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()
|
||||
}
|
||||
156
test/interface/struct.go
Normal file
156
test/interface/struct.go
Normal file
@@ -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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user