aboutsummaryrefslogtreecommitdiff
path: root/src/reflect
diff options
context:
space:
mode:
authorAlexander Klauer <Alexander.Klauer@googlemail.com>2020-06-29 16:02:07 +0000
committerEmmanuel Odeke <emm.odeke@gmail.com>2020-08-14 22:58:36 +0000
commit407bf0ca67200463cdd451937623078e0240335e (patch)
tree689bdd791549777cabb431eb27d52fc3848e9fe1 /src/reflect
parent32a84c99e136ed5af0686dbedd31fd7dff40fb38 (diff)
downloadgo-407bf0ca67200463cdd451937623078e0240335e.tar.gz
go-407bf0ca67200463cdd451937623078e0240335e.zip
reflect: add parentheses to properly bind <- in ChanOf’s string
Adds parentheses so as to properly bind <- to the right most channel. This meant that previously given: ChanOf(<-chan T) it would mistakenly try to look up the type as chan <-chan T instead of chan (<-chan T) Fixes #39897 Change-Id: I8564916055f5fadde3382e41fe8820a1071e5f13 GitHub-Last-Rev: f8f2abe8d4c9e3d1414c89cadca8a16ce5cdeab9 GitHub-Pull-Request: golang/go#39898 Reviewed-on: https://go-review.googlesource.com/c/go/+/240280 Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com> Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/reflect')
-rw-r--r--src/reflect/all_test.go16
-rw-r--r--src/reflect/type.go12
2 files changed, 26 insertions, 2 deletions
diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go
index 63f6a92157..6b31568bb9 100644
--- a/src/reflect/all_test.go
+++ b/src/reflect/all_test.go
@@ -74,6 +74,10 @@ var typeTests = []pair{
{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
@@ -5491,6 +5495,18 @@ func TestChanOf(t *testing.T) {
// 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) {
diff --git a/src/reflect/type.go b/src/reflect/type.go
index 38b1283d42..44c96fea82 100644
--- a/src/reflect/type.go
+++ b/src/reflect/type.go
@@ -1789,7 +1789,6 @@ func ChanOf(dir ChanDir, t Type) Type {
}
// Look in known types.
- // TODO: Precedence when constructing string.
var s string
switch dir {
default:
@@ -1799,7 +1798,16 @@ func ChanOf(dir ChanDir, t Type) Type {
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))