aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlan Donovan <adonovan@google.com>2023-10-04 10:26:17 -0400
committerGopher Robot <gobot@golang.org>2023-10-04 16:05:21 +0000
commit0c64ebce7e7007615aba58a19be07372f0febe69 (patch)
tree55d4f41aed339e6687c6dc9df3e6c68cfc88d4e8 /src
parenta9036396080aa414c032550fc258919636295f0f (diff)
downloadgo-0c64ebce7e7007615aba58a19be07372f0febe69.tar.xz
go/printer: parenthesize type in <-((<-chan int)(nil))
When printing synthetic syntax (not created by the parser), the tree for <-((<-chan int)(nil)) without any ParenExpr nodes was misprinted so that it was parsed back as a receive of a receive. This changes emits parens around the channel type. Fixes #63362 Change-Id: I2041ced224f0bca001cee5d37f7a127265d21020 Reviewed-on: https://go-review.googlesource.com/c/go/+/532556 Auto-Submit: Robert Griesemer <gri@google.com> Run-TryBot: Robert Griesemer <gri@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/go/printer/nodes.go21
-rw-r--r--src/go/printer/printer_test.go23
2 files changed, 38 insertions, 6 deletions
diff --git a/src/go/printer/nodes.go b/src/go/printer/nodes.go
index 97c2cab0f8..0a693b6667 100644
--- a/src/go/printer/nodes.go
+++ b/src/go/printer/nodes.go
@@ -974,15 +974,24 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
if len(x.Args) > 1 {
depth++
}
- var wasIndented bool
- if _, ok := x.Fun.(*ast.FuncType); ok {
- // conversions to literal function types require parentheses around the type
+
+ // Conversions to literal function types or <-chan
+ // types require parentheses around the type.
+ paren := false
+ switch t := x.Fun.(type) {
+ case *ast.FuncType:
+ paren = true
+ case *ast.ChanType:
+ paren = t.Dir == ast.RECV
+ }
+ if paren {
p.print(token.LPAREN)
- wasIndented = p.possibleSelectorExpr(x.Fun, token.HighestPrec, depth)
+ }
+ wasIndented := p.possibleSelectorExpr(x.Fun, token.HighestPrec, depth)
+ if paren {
p.print(token.RPAREN)
- } else {
- wasIndented = p.possibleSelectorExpr(x.Fun, token.HighestPrec, depth)
}
+
p.setPos(x.Lparen)
p.print(token.LPAREN)
if x.Ellipsis.IsValid() {
diff --git a/src/go/printer/printer_test.go b/src/go/printer/printer_test.go
index 3a8ce60431..8e78bc640e 100644
--- a/src/go/printer/printer_test.go
+++ b/src/go/printer/printer_test.go
@@ -604,6 +604,29 @@ func f()
}
}
+// TestChanType tests that the tree for <-(<-chan int), without
+// ParenExpr, is correctly formatted with parens.
+// Test case for issue #63362.
+func TestChanType(t *testing.T) {
+ expr := &ast.UnaryExpr{
+ Op: token.ARROW,
+ X: &ast.CallExpr{
+ Fun: &ast.ChanType{
+ Dir: ast.RECV,
+ Value: &ast.Ident{Name: "int"},
+ },
+ Args: []ast.Expr{&ast.Ident{Name: "nil"}},
+ },
+ }
+ var buf bytes.Buffer
+ if err := Fprint(&buf, fset, expr); err != nil {
+ t.Fatal(err)
+ }
+ if got, want := buf.String(), `<-(<-chan int)(nil)`; got != want {
+ t.Fatalf("got:\n%s\nwant:\n%s\n", got, want)
+ }
+}
+
type limitWriter struct {
remaining int
errCount int