1 // This interpreter test is designed to run very quickly yet provide
2 // some coverage of a broad selection of constructs.
4 // Validate this file with 'go run' after editing.
5 // TODO(adonovan): break this into small files organized by theme.
16 // Call of variadic function with (implicit) empty slice.
17 if x := fmt.Sprint(); x != "" {
22 type empty interface{}
28 type T struct{ z int }
30 func (t T) f() int { return t.z }
32 func use(interface{}) {}
36 // Test initialization, including init blocks containing 'return'.
37 // Assertion is in main.
55 return fib(x-1) + fib(x-2)
58 func fibgen(ch chan int) {
59 for x := 0; x < 10; x++ {
65 // Goroutines and channels.
71 fibs = append(fibs, v)
76 if x := fmt.Sprint(fibs); x != "[0 1 1 2 3 5 8 13 21 34]" {
87 s1 := []string{"foo", "bar"}
88 s2 := s1 // creates an alias
90 if x := fmt.Sprint(s1, s2); x != "[wiz bar] [wiz bar]" {
94 pa1 := &[2]string{"foo", "bar"}
95 pa2 := pa1 // creates an alias
97 if x := fmt.Sprint(*pa1, *pa2); x != "[wiz bar] [wiz bar]" {
101 a1 := [2]string{"foo", "bar"}
102 a2 := a1 // creates a copy
104 if x := fmt.Sprint(a1, a2); x != "[foo bar] [wiz bar]" {
108 t1 := S{"foo", "bar"}
111 if x := fmt.Sprint(t1, t2); x != "{foo bar} {wiz bar}" {
119 if counter != 2*3*5 {
123 // Test builtins (e.g. complex) preserve named argument types.
126 n = complex(1.0, 2.0)
127 if n != complex(1.0, 2.0) {
130 if x := reflect.TypeOf(n).String(); x != "main.N" {
133 if real(n) != 1.0 || imag(n) != 2.0 {
138 ch := make(chan int, 1)
143 panic("couldn't send")
146 panic("couldn't receive")
148 // A "receive" select-case that doesn't declare its vars. (regression test)
152 case anint, ok = <-ch:
159 // Anon structs with methods.
160 anon := struct{ T }{T: T{z: 1}}
161 if x := anon.f(); x != 1 {
165 if x := i.f(); x != 1 {
168 // NB. precise output of reflect.Type.String is undefined.
169 if x := reflect.TypeOf(i).String(); x != "struct { main.T }" && x != "struct{main.T}" {
174 const message = "Hello, World!"
175 if fmt.Sprint("Hello", ", ", "World", "!") != message {
183 var e empty = S{f: 42}
184 switch v := e.(type) {
190 panic(reflect.TypeOf(v))
192 if i, ok := e.(I); ok {
221 // string -> []rune conversion.
224 // Calls of form x.f().
228 S2{f: func() int { return 1 }}.f() // field is a func value
229 T{}.f() // method call
230 i.f() // interface method invocation
233 }(T{})).f() // anon interface method invocation
236 if v, ok := map[string]string{}["foo5"]; v != "" || ok {
240 // Regression test: implicit address-taken struct literal
241 // inside literal map element.
242 _ = map[int]*struct{}{0: {}}
252 var i interface{} = b || b // result preserves types of operands
255 i = false && b // result preserves type of "typed" operand
258 i = b || true // result preserves type of "typed" operand
264 var b mybool = x == y // x==y is an untyped bool
271 f := func(a int) int {
275 if x := f(1); x != 5 { // 1+4 == 5
279 if x := f(2); x != 7 { // 2+5 == 7
282 if b := f(1) < 16 || f(2) < 17; !b {
290 var u uint64 = 1 << 32
291 if x := i << uint32(u); x != 1 {
294 if x := i << uint64(u); x != 0 {
299 // Implicit conversion of delete() key operand.
302 m := make(map[I]bool)
315 // An I->I conversion always succeeds.
319 panic("I->I conversion failed")
323 // An I->I type-assert fails iff the value is nil.
326 r := fmt.Sprint(recover())
327 // Exact error varies by toolchain.
328 if r != "runtime error: interface conversion: interface is nil, not main.I" &&
329 r != "interface conversion: interface is nil, not main.I" {
330 panic("I->I type assertion succeeded for nil value")
337 //////////////////////////////////////////////////////////////////////
338 // Variadic bridge methods and interface thunks.
344 func (VT) f(x int, y ...string) {
349 if len(y) != 2 || y[0] != "foo" || y[1] != "bar" {
359 f(x int, y ...string)
363 foobar := []string{"foo", "bar"}
368 panic("s.f not called twice")
372 fn(s, 1, "foo", "bar")
375 panic("I.f not called twice")
379 // Multiple labels on same statement.
380 func multipleLabels() {
386 trace = append(trace, i)
397 if x := fmt.Sprint(trace); x != "[0 1 2]" {
407 // Struct equivalence ignores blank fields.
408 type s struct{ x, _, z int }
417 // A slice var can be compared to const []T nil.
418 var i interface{} = []string{"foo"}
419 var j interface{} = []string(nil)
420 if i.([]string) == nil {
421 panic("expected i non-nil")
423 if j.([]string) != nil {
424 panic("expected j nil")
426 // But two slices cannot be compared, even if one is nil.
428 r := fmt.Sprint(recover())
429 if !(strings.Contains(r, "compar") && strings.Contains(r, "[]string")) {
430 panic("want panic from slice comparison, got " + r)
433 _ = i == j // interface comparison recurses on types
437 // Regression test for SSA renaming bug.
442 ints = append(ints, x)
444 if fmt.Sprint(ints) != "[1 1 1]" {
449 // Regression test for issue 6949:
450 // []byte("foo") is not a constant since it allocates memory.
453 for i, b := range "ABC" {
458 if r != "AbcaBcabC" {
463 // Test of 3-operand x[lo:hi:max] slice.
465 s := []int{0, 1, 2, 3}
466 lenCapLoHi := func(x []int) [4]int { return [4]int{len(x), cap(x), x[0], x[len(x)-1]} }
467 if got := lenCapLoHi(s[1:3]); got != [4]int{2, 3, 1, 2} {
470 if got := lenCapLoHi(s[1:3:3]); got != [4]int{2, 2, 1, 2} {
475 max = 2 // max is non-constant, even in SSA form
477 if got := lenCapLoHi(s[1:2:max]); got != [4]int{1, 1, 1, 1} {
482 var one = 1 // not a constant
486 check := func(s []string, wantLen, wantCap int) {
487 if len(s) != wantLen {
490 if cap(s) != wantCap {
495 check(make([]string, 10), 10, 10) // new([10]string)[:10]
496 check(make([]string, one), 1, 1) // make([]string, one, one)
497 check(make([]string, 0, 10), 0, 10) // new([10]string)[:0]
498 check(make([]string, 0, one), 0, 1) // make([]string, 0, one)
499 check(make([]string, one, 10), 1, 10) // new([10]string)[:one]
500 check(make([]string, one, one), 1, 1) // make([]string, one, one)
503 // Test that a nice error is issued by indirection wrappers.
509 r := fmt.Sprint(recover())
510 // Exact error varies by toolchain:
511 if r != "runtime error: value method (main.T).f called using nil *main.T pointer" &&
512 r != "value method (main.T).f called using nil *main.T pointer" {
513 panic("want panic from call with nil receiver, got " + r)
520 // Regression test for a subtle bug in which copying values would causes
521 // subcomponents of aggregate variables to change address, breaking
524 type T struct{ f int }
533 panic("unstable address")