Commit 553237aa authored by Robert Griesemer's avatar Robert Griesemer

go/types: report error for invalid use of ... in parameter lists

The parser accepts ...T types in parameter lists whereever a type
is permitted; this matches the syntax and allows for more tolerant
parsing and error recovery.

go/types on the other hand assumed that the parser would report
those errors and assumed any outstanding such errors would be due
to otherwise manipulated ASTs leading to invalid ASTs.

go/types further assumed that a parameter list (a, b, c ...int)
was permitted (a couple of tests used such parameter lists).

With this CL, go/types now correctly refuses invalid parameter lists.

Fixes #28281.

Change-Id: Ib788255f7b7819fdb972c7801bb153a53ce2ddf7
Reviewed-on: https://go-review.googlesource.com/c/143857
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarAlan Donovan <adonovan@google.com>
parent 9258c3f9
...@@ -262,7 +262,7 @@ func TestTypesInfo(t *testing.T) { ...@@ -262,7 +262,7 @@ func TestTypesInfo(t *testing.T) {
`...int`, `...int`,
`[]int`, `[]int`,
}, },
{`package issue28277_b; func f(a, b, c ...[]struct{})`, {`package issue28277_b; func f(a, b int, c ...[]struct{})`,
`...[]struct{}`, `...[]struct{}`,
`[][]struct{}`, `[][]struct{}`,
}, },
......
...@@ -302,3 +302,14 @@ var issue27346 = [][n /* ERROR undeclared */ ]int{ ...@@ -302,3 +302,14 @@ var issue27346 = [][n /* ERROR undeclared */ ]int{
} }
var issue22467 = map[int][... /* ERROR invalid use of ... */ ]int{0: {}} var issue22467 = map[int][... /* ERROR invalid use of ... */ ]int{0: {}}
// Test that invalid use of ... in parameter lists is recognized
// (issue #28281).
func issue28281a(int, int, ...int)
func issue28281b(a, b int, c ...int)
func issue28281c(a, b, c ... /* ERROR can only use ... with final parameter */ int)
func issue28281d(... /* ERROR can only use ... with final parameter */ int, int)
func issue28281e(a, b, c ... /* ERROR can only use ... with final parameter */ int, d int)
func issue28281f(... /* ERROR can only use ... with final parameter */ int, ... /* ERROR can only use ... with final parameter */ int, int)
func (... /* ERROR expected type */ TT) f()
func issue28281g() (... /* ERROR expected type */ TT)
\ No newline at end of file
...@@ -89,7 +89,7 @@ var independentTestTypes = []testEntry{ ...@@ -89,7 +89,7 @@ var independentTestTypes = []testEntry{
dup("func(...int) string"), dup("func(...int) string"),
dup("func(x ...int) string"), dup("func(x ...int) string"),
dup("func(x ...int) (u string)"), dup("func(x ...int) (u string)"),
{"func(x, y ...int) (u string)", "func(x int, y ...int) (u string)"}, {"func(x int, y ...int) (u string)", "func(x int, y ...int) (u string)"},
// interfaces // interfaces
dup("interface{}"), dup("interface{}"),
......
...@@ -414,10 +414,10 @@ func (check *Checker) collectParams(scope *Scope, list *ast.FieldList, variadicO ...@@ -414,10 +414,10 @@ func (check *Checker) collectParams(scope *Scope, list *ast.FieldList, variadicO
ftype := field.Type ftype := field.Type
if t, _ := ftype.(*ast.Ellipsis); t != nil { if t, _ := ftype.(*ast.Ellipsis); t != nil {
ftype = t.Elt ftype = t.Elt
if variadicOk && i == len(list.List)-1 { if variadicOk && i == len(list.List)-1 && len(field.Names) <= 1 {
variadic = true variadic = true
} else { } else {
check.invalidAST(field.Pos(), "... not permitted") check.softErrorf(t.Pos(), "can only use ... with final parameter in list")
// ignore ... and continue // ignore ... and continue
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment