From 1065c6f65ad3083976f10f0828633a322f7114b8 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Thu, 4 Oct 2012 21:03:50 -0700 Subject: [PATCH] go/printer: parenthesize literal function types in conversions Also: gofmt -w src misc R=r CC=golang-dev, iant https://golang.org/cl/6591071 --- src/pkg/go/printer/nodes.go | 9 ++++++++- src/pkg/go/printer/testdata/expressions.golden | 15 +++++++++++++++ src/pkg/go/printer/testdata/expressions.input | 15 +++++++++++++++ src/pkg/go/printer/testdata/expressions.raw | 15 +++++++++++++++ src/pkg/reflect/all_test.go | 2 +- 5 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/pkg/go/printer/nodes.go b/src/pkg/go/printer/nodes.go index 01a7473b835..6eee9a9245c 100644 --- a/src/pkg/go/printer/nodes.go +++ b/src/pkg/go/printer/nodes.go @@ -791,7 +791,14 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) { if len(x.Args) > 1 { depth++ } - p.expr1(x.Fun, token.HighestPrec, depth) + if _, ok := x.Fun.(*ast.FuncType); ok { + // conversions to literal function types require parentheses around the type + p.print(token.LPAREN) + p.expr1(x.Fun, token.HighestPrec, depth) + p.print(token.RPAREN) + } else { + p.expr1(x.Fun, token.HighestPrec, depth) + } p.print(x.Lparen, token.LPAREN) if x.Ellipsis.IsValid() { p.exprList(x.Lparen, x.Args, depth, 0, x.Ellipsis) diff --git a/src/pkg/go/printer/testdata/expressions.golden b/src/pkg/go/printer/testdata/expressions.golden index 45fa4d97a4a..4291c557ce2 100644 --- a/src/pkg/go/printer/testdata/expressions.golden +++ b/src/pkg/go/printer/testdata/expressions.golden @@ -647,3 +647,18 @@ func _() { a..., ) } + +// Literal function types in conversions must be parenthesized; +// for now go/parser accepts the unparenthesized form where it +// is non-ambiguous. +func _() { + // these conversions should be rewritten to look + // the same as the parenthesized conversions below + _ = (func())(nil) + _ = (func(x int) float)(nil) + _ = (func() func() func())(nil) + + _ = (func())(nil) + _ = (func(x int) float)(nil) + _ = (func() func() func())(nil) +} diff --git a/src/pkg/go/printer/testdata/expressions.input b/src/pkg/go/printer/testdata/expressions.input index f545c66057c..1ec12a05049 100644 --- a/src/pkg/go/printer/testdata/expressions.input +++ b/src/pkg/go/printer/testdata/expressions.input @@ -676,3 +676,18 @@ func _() { a..., ) } + +// Literal function types in conversions must be parenthesized; +// for now go/parser accepts the unparenthesized form where it +// is non-ambiguous. +func _() { + // these conversions should be rewritten to look + // the same as the parenthesized conversions below + _ = func()()(nil) + _ = func(x int)(float)(nil) + _ = func() func() func()()(nil) + + _ = (func()())(nil) + _ = (func(x int)(float))(nil) + _ = (func() func() func()())(nil) +} diff --git a/src/pkg/go/printer/testdata/expressions.raw b/src/pkg/go/printer/testdata/expressions.raw index 87a4b00836d..062900e0724 100644 --- a/src/pkg/go/printer/testdata/expressions.raw +++ b/src/pkg/go/printer/testdata/expressions.raw @@ -647,3 +647,18 @@ func _() { a..., ) } + +// Literal function types in conversions must be parenthesized; +// for now go/parser accepts the unparenthesized form where it +// is non-ambiguous. +func _() { + // these conversions should be rewritten to look + // the same as the parenthesized conversions below + _ = (func())(nil) + _ = (func(x int) float)(nil) + _ = (func() func() func())(nil) + + _ = (func())(nil) + _ = (func(x int) float)(nil) + _ = (func() func() func())(nil) +} diff --git a/src/pkg/reflect/all_test.go b/src/pkg/reflect/all_test.go index 5dad071b3cc..5ddd6bef18c 100644 --- a/src/pkg/reflect/all_test.go +++ b/src/pkg/reflect/all_test.go @@ -1494,7 +1494,7 @@ func TestMethod(t *testing.T) { } // Curried method of value. - tfunc := TypeOf(func(int) int(nil)) + tfunc := TypeOf((func(int) int)(nil)) v := ValueOf(p).Method(1) if tt := v.Type(); tt != tfunc { t.Errorf("Value Method Type is %s; want %s", tt, tfunc)