Skip to content

Commit d10b819

Browse files
findleyrdmitshur
authored andcommitted
[release-branch.go1.18] go/printer: don't print unnecesary commas for func type param lists
Type parameter lists are not ambiguous for function declarations in the way that they are ambiguous for type declarations. Avoid printing an extra comma to disambiguate. Fixes #51548 Change-Id: I8ca2b21e271982013653b9e220f92ee74f577ba2 Reviewed-on: https://go-review.googlesource.com/c/go/+/390914 Trust: Robert Findley <[email protected]> Run-TryBot: Robert Findley <[email protected]> Reviewed-by: Robert Griesemer <[email protected]> TryBot-Result: Gopher Robot <[email protected]> (cherry picked from commit 0add064) Reviewed-on: https://go-review.googlesource.com/c/go/+/390957 Trust: Dmitri Shuralyov <[email protected]> Run-TryBot: Dmitri Shuralyov <[email protected]> Reviewed-by: Robert Findley <[email protected]>
1 parent bf366ef commit d10b819

File tree

3 files changed

+67
-8
lines changed

3 files changed

+67
-8
lines changed

src/go/printer/nodes.go

+16-8
Original file line numberDiff line numberDiff line change
@@ -319,9 +319,17 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
319319
}
320320
}
321321

322-
func (p *printer) parameters(fields *ast.FieldList, isTypeParam bool) {
322+
type paramMode int
323+
324+
const (
325+
funcParam paramMode = iota
326+
funcTParam
327+
typeTParam
328+
)
329+
330+
func (p *printer) parameters(fields *ast.FieldList, mode paramMode) {
323331
openTok, closeTok := token.LPAREN, token.RPAREN
324-
if isTypeParam {
332+
if mode != funcParam {
325333
openTok, closeTok = token.LBRACK, token.RBRACK
326334
}
327335
p.print(fields.Opening, openTok)
@@ -373,7 +381,7 @@ func (p *printer) parameters(fields *ast.FieldList, isTypeParam bool) {
373381
if closing := p.lineFor(fields.Closing); 0 < prevLine && prevLine < closing {
374382
p.print(token.COMMA)
375383
p.linebreak(closing, 0, ignore, true)
376-
} else if isTypeParam && fields.NumFields() == 1 {
384+
} else if mode == typeTParam && fields.NumFields() == 1 {
377385
// Otherwise, if we are in a type parameter list that could be confused
378386
// with the constant array length expression [P*C], print a comma so that
379387
// parsing is unambiguous.
@@ -411,10 +419,10 @@ func isTypeLit(x ast.Expr) bool {
411419

412420
func (p *printer) signature(sig *ast.FuncType) {
413421
if sig.TypeParams != nil {
414-
p.parameters(sig.TypeParams, true)
422+
p.parameters(sig.TypeParams, funcTParam)
415423
}
416424
if sig.Params != nil {
417-
p.parameters(sig.Params, false)
425+
p.parameters(sig.Params, funcParam)
418426
} else {
419427
p.print(token.LPAREN, token.RPAREN)
420428
}
@@ -428,7 +436,7 @@ func (p *printer) signature(sig *ast.FuncType) {
428436
p.expr(stripParensAlways(res.List[0].Type))
429437
return
430438
}
431-
p.parameters(res, false)
439+
p.parameters(res, funcParam)
432440
}
433441
}
434442

@@ -1639,7 +1647,7 @@ func (p *printer) spec(spec ast.Spec, n int, doIndent bool) {
16391647
p.setComment(s.Doc)
16401648
p.expr(s.Name)
16411649
if s.TypeParams != nil {
1642-
p.parameters(s.TypeParams, true)
1650+
p.parameters(s.TypeParams, typeTParam)
16431651
}
16441652
if n == 1 {
16451653
p.print(blank)
@@ -1829,7 +1837,7 @@ func (p *printer) funcDecl(d *ast.FuncDecl) {
18291837
// FUNC is emitted).
18301838
startCol := p.out.Column - len("func ")
18311839
if d.Recv != nil {
1832-
p.parameters(d.Recv, false) // method: print receiver
1840+
p.parameters(d.Recv, funcParam) // method: print receiver
18331841
p.print(blank)
18341842
}
18351843
p.expr(d.Name)

src/go/printer/testdata/generics.golden

+26
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,29 @@ type _ [P*T - T]struct{}
6464
type _[
6565
P *T,
6666
] struct{}
67+
68+
// equivalent test cases for potentially ambiguous type parameter lists, except
69+
// for function declarations there is no ambiguity (issue #51548)
70+
func _[P *T]() {}
71+
func _[P *T, _ any]() {}
72+
func _[P *T]() {}
73+
func _[P *T, _ any]() {}
74+
func _[P T]() {}
75+
func _[P T, _ any]() {}
76+
77+
func _[P *struct{}]() {}
78+
func _[P *struct{}]() {}
79+
func _[P []int]() {}
80+
81+
func _[P T]() {}
82+
func _[P T]() {}
83+
func _[P **T]() {}
84+
func _[P *T]() {}
85+
func _[P *T]() {}
86+
func _[P **T]() {}
87+
func _[P *T]() {}
88+
89+
func _[
90+
P *T,
91+
]() {
92+
}

src/go/printer/testdata/generics.input

+25
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,28 @@ type _ [P * T - T]struct{}
6161
type _[
6262
P *T,
6363
] struct{}
64+
65+
// equivalent test cases for potentially ambiguous type parameter lists, except
66+
// for function declarations there is no ambiguity (issue #51548)
67+
func _[P *T,]() {}
68+
func _[P *T, _ any]() {}
69+
func _[P (*T),]() {}
70+
func _[P (*T), _ any]() {}
71+
func _[P (T),]() {}
72+
func _[P (T), _ any]() {}
73+
74+
func _[P *struct{}] () {}
75+
func _[P (*struct{})] () {}
76+
func _[P ([]int)] () {}
77+
78+
func _ [P(T)]() {}
79+
func _ [P((T))]() {}
80+
func _ [P * *T]() {}
81+
func _ [P * T]() {}
82+
func _ [P(*T)]() {}
83+
func _ [P(**T)]() {}
84+
func _ [P * T]() {}
85+
86+
func _[
87+
P *T,
88+
]() {}

0 commit comments

Comments
 (0)