{struct{ x ([]int8) }{}, "[]int8"},
{struct{ x (map[string]int32) }{}, "map[string]int32"},
{struct{ x (chan<- string) }{}, "chan<- string"},
+ {struct{ x (chan<- chan string) }{}, "chan<- chan string"},
+ {struct{ x (chan<- <-chan string) }{}, "chan<- <-chan string"},
+ {struct{ x (<-chan <-chan string) }{}, "<-chan <-chan string"},
+ {struct{ x (chan (<-chan string)) }{}, "chan (<-chan string)"},
{struct {
x struct {
c chan *int32
// check that type already in binary is found
type T1 int
checkSameType(t, ChanOf(BothDir, TypeOf(T1(1))), (chan T1)(nil))
+
+ // Check arrow token association in undefined chan types.
+ var left chan<- chan T
+ var right chan (<-chan T)
+ tLeft := ChanOf(SendDir, ChanOf(BothDir, TypeOf(T(""))))
+ tRight := ChanOf(BothDir, ChanOf(RecvDir, TypeOf(T(""))))
+ if tLeft != TypeOf(left) {
+ t.Errorf("chan<-chan: have %s, want %T", tLeft, left)
+ }
+ if tRight != TypeOf(right) {
+ t.Errorf("chan<-chan: have %s, want %T", tRight, right)
+ }
}
func TestChanOfDir(t *testing.T) {
}
// Look in known types.
- // TODO: Precedence when constructing string.
var s string
switch dir {
default:
case RecvDir:
s = "<-chan " + typ.String()
case BothDir:
- s = "chan " + typ.String()
+ typeStr := typ.String()
+ if typeStr[0] == '<' {
+ // typ is recv chan, need parentheses as "<-" associates with leftmost
+ // chan possible, see:
+ // * https://golang.org/ref/spec#Channel_types
+ // * https://github.com/golang/go/issues/39897
+ s = "chan (" + typeStr + ")"
+ } else {
+ s = "chan " + typeStr
+ }
}
for _, tt := range typesByString(s) {
ch := (*chanType)(unsafe.Pointer(tt))