}
}
-func (p *printer) parameters(fields *ast.FieldList, isTypeParam bool) {
+type paramMode int
+
+const (
+ funcParam paramMode = iota
+ funcTParam
+ typeTParam
+)
+
+func (p *printer) parameters(fields *ast.FieldList, mode paramMode) {
openTok, closeTok := token.LPAREN, token.RPAREN
- if isTypeParam {
+ if mode != funcParam {
openTok, closeTok = token.LBRACK, token.RBRACK
}
p.print(fields.Opening, openTok)
if closing := p.lineFor(fields.Closing); 0 < prevLine && prevLine < closing {
p.print(token.COMMA)
p.linebreak(closing, 0, ignore, true)
- } else if isTypeParam && fields.NumFields() == 1 {
+ } else if mode == typeTParam && fields.NumFields() == 1 {
// Otherwise, if we are in a type parameter list that could be confused
// with the constant array length expression [P*C], print a comma so that
// parsing is unambiguous.
func (p *printer) signature(sig *ast.FuncType) {
if sig.TypeParams != nil {
- p.parameters(sig.TypeParams, true)
+ p.parameters(sig.TypeParams, funcTParam)
}
if sig.Params != nil {
- p.parameters(sig.Params, false)
+ p.parameters(sig.Params, funcParam)
} else {
p.print(token.LPAREN, token.RPAREN)
}
p.expr(stripParensAlways(res.List[0].Type))
return
}
- p.parameters(res, false)
+ p.parameters(res, funcParam)
}
}
p.setComment(s.Doc)
p.expr(s.Name)
if s.TypeParams != nil {
- p.parameters(s.TypeParams, true)
+ p.parameters(s.TypeParams, typeTParam)
}
if n == 1 {
p.print(blank)
// FUNC is emitted).
startCol := p.out.Column - len("func ")
if d.Recv != nil {
- p.parameters(d.Recv, false) // method: print receiver
+ p.parameters(d.Recv, funcParam) // method: print receiver
p.print(blank)
}
p.expr(d.Name)
type _[
P *T,
] struct{}
+
+// equivalent test cases for potentially ambiguous type parameter lists, except
+// for function declarations there is no ambiguity (issue #51548)
+func _[P *T]() {}
+func _[P *T, _ any]() {}
+func _[P *T]() {}
+func _[P *T, _ any]() {}
+func _[P T]() {}
+func _[P T, _ any]() {}
+
+func _[P *struct{}]() {}
+func _[P *struct{}]() {}
+func _[P []int]() {}
+
+func _[P T]() {}
+func _[P T]() {}
+func _[P **T]() {}
+func _[P *T]() {}
+func _[P *T]() {}
+func _[P **T]() {}
+func _[P *T]() {}
+
+func _[
+ P *T,
+]() {
+}
type _[
P *T,
] struct{}
+
+// equivalent test cases for potentially ambiguous type parameter lists, except
+// for function declarations there is no ambiguity (issue #51548)
+func _[P *T,]() {}
+func _[P *T, _ any]() {}
+func _[P (*T),]() {}
+func _[P (*T), _ any]() {}
+func _[P (T),]() {}
+func _[P (T), _ any]() {}
+
+func _[P *struct{}] () {}
+func _[P (*struct{})] () {}
+func _[P ([]int)] () {}
+
+func _ [P(T)]() {}
+func _ [P((T))]() {}
+func _ [P * *T]() {}
+func _ [P * T]() {}
+func _ [P(*T)]() {}
+func _ [P(**T)]() {}
+func _ [P * T]() {}
+
+func _[
+ P *T,
+]() {}