}
f.Name = p.name()
- if p.allowGenerics() && p.got(_Lbrack) {
- if p.tok == _Rbrack {
- p.syntaxError("empty type parameter list")
- p.next()
- } else {
- f.TParamList = p.paramList(nil, _Rbrack, true)
- }
- }
- f.Type = p.funcType()
+ f.TParamList, f.Type = p.funcType("")
if p.tok == _Lbrace {
f.Body = p.funcBody()
}
case _Func:
pos := p.pos()
p.next()
- ftyp := p.funcType()
+ _, ftyp := p.funcType("function literal")
if p.tok == _Lbrace {
p.xnest++
case _Func:
// fntype
p.next()
- return p.funcType()
+ _, t := p.funcType("function type")
+ return t
case _Lbrack:
// '[' oexpr ']' ntype
return x
}
-func (p *parser) funcType() *FuncType {
+// If context != "", type parameters are not permitted.
+func (p *parser) funcType(context string) ([]*Field, *FuncType) {
if trace {
defer p.trace("funcType")()
}
typ := new(FuncType)
typ.pos = p.pos()
+
+ var tparamList []*Field
+ if p.allowGenerics() && p.got(_Lbrack) {
+ if context != "" {
+ // accept but complain
+ p.syntaxErrorAt(typ.pos, context+" cannot have type parameters")
+ }
+ if p.tok == _Rbrack {
+ p.syntaxError("empty type parameter list")
+ p.next()
+ } else {
+ tparamList = p.paramList(nil, _Rbrack, true)
+ }
+ }
+
p.want(_Lparen)
typ.ParamList = p.paramList(nil, _Rparen, false)
typ.ResultList = p.funcResult()
- return typ
+ return tparamList, typ
}
// "[" has already been consumed, and pos is its position.
// already progressed, no need to advance
}
+ const context = "interface method"
+
switch p.tok {
case _Lparen:
// method
f.Name = name
- f.Type = p.funcType()
+ _, f.Type = p.funcType(context)
case _Lbrack:
if p.allowGenerics() {
// name[](
p.errorAt(pos, "empty type parameter list")
f.Name = name
- f.Type = p.funcType()
+ _, f.Type = p.funcType(context)
} else {
p.errorAt(pos, "empty type argument list")
f.Type = name
// as if [] were absent.
if p.tok == _Lparen {
f.Name = name
- f.Type = p.funcType()
+ _, f.Type = p.funcType(context)
} else {
f.Type = name
}
if list[0].Name != nil {
// generic method
f.Name = name
- f.Type = p.funcType()
+ _, f.Type = p.funcType(context)
// TODO(gri) Record list as type parameter list with f.Type
// if we want to type-check the generic method.
// For now, report an error so this is not a silent event.
--- /dev/null
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type _ func /* ERROR function type cannot have type parameters */ [ /* ERROR empty type parameter list */ ]()
+type _ func /* ERROR function type cannot have type parameters */ [ x /* ERROR missing type constraint */ ]()
+type _ func /* ERROR function type cannot have type parameters */ [P any]()
+
+var _ = func /* ERROR function literal cannot have type parameters */ [P any]() {}
+
+type _ interface{
+ m /* ERROR interface method cannot have type parameters */ [P any]()
+}