Home | History | Annotate | Download | only in fixedbugs
      1 // run
      2 
      3 // Copyright 2016 The Go Authors. All rights reserved.
      4 // Use of this source code is governed by a BSD-style
      5 // license that can be found in the LICENSE file.
      6 
      7 package main
      8 
      9 import (
     10 	"fmt"
     11 	"io"
     12 	"os"
     13 	"reflect"
     14 	"unsafe"
     15 )
     16 
     17 type RWS struct{}
     18 
     19 func (x *RWS) Read(p []byte) (n int, err error)                   { return }
     20 func (x *RWS) Write(p []byte) (n int, err error)                  { return }
     21 func (x *RWS) Seek(offset int64, whence int) (n int64, err error) { return }
     22 func (x *RWS) String() string                                     { return "rws" }
     23 
     24 func makeRWS() io.ReadWriteSeeker { return &RWS{} }
     25 func makeStringer() fmt.Stringer  { return &RWS{} }
     26 
     27 // Test correct construction of static empty interface values
     28 var efaces = [...]struct {
     29 	x interface{}
     30 	s string
     31 }{
     32 	{nil, "<nil> <nil>"},
     33 	{1, "int 1"},
     34 	{int(1), "int 1"},
     35 	{Int(int(2)), "main.Int Int=2"},
     36 	{int(Int(3)), "int 3"},
     37 	{[1]int{2}, "[1]int [2]"},
     38 	{io.Reader(io.ReadWriter(io.ReadWriteSeeker(nil))), "<nil> <nil>"},
     39 	{io.Reader(io.ReadWriter(io.ReadWriteSeeker(&RWS{}))), "*main.RWS rws"},
     40 	{makeRWS(), "*main.RWS rws"},
     41 	{map[string]string{"here": "there"}, "map[string]string map[here:there]"},
     42 	{chan bool(nil), "chan bool <nil>"},
     43 	{unsafe.Pointer(uintptr(0)), "unsafe.Pointer <nil>"},
     44 	{(*byte)(nil), "*uint8 <nil>"},
     45 	{io.Writer((*os.File)(nil)), "*os.File <nil>"},
     46 	{(interface{})(io.Writer((*os.File)(nil))), "*os.File <nil>"},
     47 	{fmt.Stringer(Strunger(((*Int)(nil)))), "*main.Int <nil>"},
     48 }
     49 
     50 type Int int
     51 
     52 func (i Int) String() string { return fmt.Sprintf("Int=%d", i) }
     53 func (i Int) Strung()        {}
     54 
     55 type Strunger interface {
     56 	fmt.Stringer
     57 	Strung()
     58 }
     59 
     60 // Test correct construction of static non-empty interface values
     61 var ifaces = [...]struct {
     62 	x fmt.Stringer
     63 	s string
     64 }{
     65 	{nil, "<nil> <nil> %!s(<nil>)"},
     66 	{Int(3), "main.Int 3 Int=3"},
     67 	{Int(int(Int(4))), "main.Int 4 Int=4"},
     68 	{Strunger(Int(5)), "main.Int 5 Int=5"},
     69 	{makeStringer(), "*main.RWS &main.RWS{} rws"},
     70 	{fmt.Stringer(nil), "<nil> <nil> %!s(<nil>)"},
     71 	{(*RWS)(nil), "*main.RWS (*main.RWS)(nil) rws"},
     72 }
     73 
     74 // Test correct handling of direct interface values
     75 var (
     76 	one  int         = 1
     77 	iptr interface{} = &one
     78 	clos int
     79 	f    interface{} = func() { clos++ }
     80 	deep interface{} = [1]struct{ a *[2]byte }{{a: &[2]byte{'z', 'w'}}}
     81 	ch   interface{} = make(chan bool, 1)
     82 )
     83 
     84 func main() {
     85 	var fail bool
     86 	for i, test := range efaces {
     87 		s := fmt.Sprintf("%[1]T %[1]v", test.x)
     88 		if s != test.s {
     89 			fmt.Printf("eface(%d)=%q want %q\n", i, s, test.s)
     90 			fail = true
     91 		}
     92 	}
     93 
     94 	for i, test := range ifaces {
     95 		s := fmt.Sprintf("%[1]T %#[1]v %[1]s", test.x)
     96 		if s != test.s {
     97 			fmt.Printf("iface(%d)=%q want %q\n", i, s, test.s)
     98 			fail = true
     99 		}
    100 	}
    101 
    102 	if got := *(iptr.(*int)); got != 1 {
    103 		fmt.Printf("bad int ptr %d\n", got)
    104 		fail = true
    105 	}
    106 
    107 	f.(func())()
    108 	f.(func())()
    109 	f.(func())()
    110 	if clos != 3 {
    111 		fmt.Printf("bad closure exec %d\n", clos)
    112 		fail = true
    113 	}
    114 
    115 	if !reflect.DeepEqual(*(deep.([1]struct{ a *[2]byte })[0].a), [2]byte{'z', 'w'}) {
    116 		fmt.Printf("bad deep directiface\n")
    117 		fail = true
    118 	}
    119 
    120 	cc := ch.(chan bool)
    121 	cc <- true
    122 	if got := <-cc; !got {
    123 		fmt.Printf("bad chan\n")
    124 		fail = true
    125 	}
    126 
    127 	if fail {
    128 		fmt.Println("BUG")
    129 		os.Exit(1)
    130 	}
    131 }
    132