]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: report error for invalid use of ... in parameter lists
authorRobert Griesemer <gri@golang.org>
Mon, 22 Oct 2018 21:07:36 +0000 (14:07 -0700)
committerRobert Griesemer <gri@golang.org>
Mon, 22 Oct 2018 22:01:12 +0000 (22:01 +0000)
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: Alan Donovan <adonovan@google.com>
src/go/types/api_test.go
src/go/types/testdata/issues.src
src/go/types/typestring_test.go
src/go/types/typexpr.go

index 85de9f6079392f1b4d8d4d2166ca8026767166fd..fe3950a52d87c0e66465fcbd6089bd210a1d8be5 100644 (file)
@@ -262,7 +262,7 @@ func TestTypesInfo(t *testing.T) {
                        `...int`,
                        `[]int`,
                },
-               {`package issue28277_b; func f(a, b, c ...[]struct{})`,
+               {`package issue28277_b; func f(a, b int, c ...[]struct{})`,
                        `...[]struct{}`,
                        `[][]struct{}`,
                },
index 13f8309c829d7cfcb281867c73e0458ff48f65b0..8260f58519d012c5cafde1c4181adbdae73141ea 100644 (file)
@@ -302,3 +302,14 @@ var issue27346 = [][n /* ERROR undeclared */ ]int{
 }
 
 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
index 0efb7f0013f3d1762675ee3e2dc08eb3376794d0..3cae4f134a8b48674bccb86e79f95bff4fe2e184 100644 (file)
@@ -89,7 +89,7 @@ var independentTestTypes = []testEntry{
        dup("func(...int) string"),
        dup("func(x ...int) 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
        dup("interface{}"),
index 0a9c0f13e30a64ea8feabf666bda22343450a828..b16bf962cdb7124a92aa418a921def3f43a6362f 100644 (file)
@@ -414,10 +414,10 @@ func (check *Checker) collectParams(scope *Scope, list *ast.FieldList, variadicO
                ftype := field.Type
                if t, _ := ftype.(*ast.Ellipsis); t != nil {
                        ftype = t.Elt
-                       if variadicOk && i == len(list.List)-1 {
+                       if variadicOk && i == len(list.List)-1 && len(field.Names) <= 1 {
                                variadic = true
                        } else {
-                               check.invalidAST(field.Pos(), "... not permitted")
+                               check.softErrorf(t.Pos(), "can only use ... with final parameter in list")
                                // ignore ... and continue
                        }
                }