aboutsummaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2021-11-03 14:58:59 -0700
committerRobert Griesemer <gri@golang.org>2021-11-04 00:29:42 +0000
commita419f2f5c364031e2f65a9f031e8bb52e9c22fc9 (patch)
tree287f7a5b51f0f1d02a9956a6db0aabe16e188916 /src/cmd
parent9cf671106721451af4a556dc0bf56c133836d008 (diff)
downloadgo-a419f2f5c364031e2f65a9f031e8bb52e9c22fc9.tar.xz
cmd/compile/internal/syntax: better error message when type parameters are not permitted
Fixes #48382. Change-Id: I215896a4429839c41c9136b6922b1b748ed47734 Reviewed-on: https://go-review.googlesource.com/c/go/+/361259 Trust: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/compile/internal/syntax/parser.go45
-rw-r--r--src/cmd/compile/internal/syntax/testdata/issue48382.go215
2 files changed, 43 insertions, 17 deletions
diff --git a/src/cmd/compile/internal/syntax/parser.go b/src/cmd/compile/internal/syntax/parser.go
index 9f02cb6c2c..770175fe54 100644
--- a/src/cmd/compile/internal/syntax/parser.go
+++ b/src/cmd/compile/internal/syntax/parser.go
@@ -708,15 +708,7 @@ func (p *parser) funcDeclOrNil() *FuncDecl {
}
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()
}
@@ -944,7 +936,7 @@ func (p *parser) operand(keep_parens bool) Expr {
case _Func:
pos := p.pos()
p.next()
- ftyp := p.funcType()
+ _, ftyp := p.funcType("function literal")
if p.tok == _Lbrace {
p.xnest++
@@ -1284,7 +1276,8 @@ func (p *parser) typeOrNil() Expr {
case _Func:
// fntype
p.next()
- return p.funcType()
+ _, t := p.funcType("function type")
+ return t
case _Lbrack:
// '[' oexpr ']' ntype
@@ -1357,18 +1350,34 @@ func (p *parser) typeInstance(typ Expr) Expr {
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.
@@ -1697,11 +1706,13 @@ func (p *parser) methodDecl() *Field {
// 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() {
@@ -1721,7 +1732,7 @@ func (p *parser) methodDecl() *Field {
// 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
@@ -1738,7 +1749,7 @@ func (p *parser) methodDecl() *Field {
// as if [] were absent.
if p.tok == _Lparen {
f.Name = name
- f.Type = p.funcType()
+ _, f.Type = p.funcType(context)
} else {
f.Type = name
}
@@ -1749,7 +1760,7 @@ func (p *parser) methodDecl() *Field {
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.
diff --git a/src/cmd/compile/internal/syntax/testdata/issue48382.go2 b/src/cmd/compile/internal/syntax/testdata/issue48382.go2
new file mode 100644
index 0000000000..1e8f4b0ec6
--- /dev/null
+++ b/src/cmd/compile/internal/syntax/testdata/issue48382.go2
@@ -0,0 +1,15 @@
+// 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]()
+}