]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] go/parser: error for type instances without ParseTypeParams
authorRob Findley <rfindley@google.com>
Fri, 15 Jan 2021 16:08:02 +0000 (11:08 -0500)
committerRobert Findley <rfindley@google.com>
Tue, 19 Jan 2021 21:28:51 +0000 (21:28 +0000)
It should be an invariant that the parser does not produce ast.CallExprs
with Brackets == true unless parsing with ParseTypeParams.

Fix the one case where this invariant was violated, and add a test for
errors produced in valid generic code when ParseTypeParams is unset. We
did have some coverage of errors in short_test.go, but I find them to be
easier to read in a testdata file and would like to gradually migrate
them there.

Change-Id: If2d174377087daa1b820cabc2b5bf8bcb0b39d8e
Reviewed-on: https://go-review.googlesource.com/c/go/+/284192
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
Trust: Robert Griesemer <gri@golang.org>
Trust: Robert Findley <rfindley@google.com>

src/go/parser/parser.go
src/go/parser/testdata/typeparams.src [new file with mode: 0644]

index 24e84d5103a7aea8cc141a1206aefcb63832993d..ccbcef8f260efc24c487b855794482ee382e9025 100644 (file)
@@ -1494,6 +1494,7 @@ func (p *parser) parseIndexOrSliceOrInstance(x ast.Expr) ast.Expr {
        var args []ast.Expr
        var index [N]ast.Expr
        var colons [N - 1]token.Pos
+       var firstComma token.Pos
        if p.tok != token.COLON {
                // We can't know if we have an index expression or a type instantiation;
                // so even if we see a (named) type we are not going to be in type context.
@@ -1512,6 +1513,7 @@ func (p *parser) parseIndexOrSliceOrInstance(x ast.Expr) ast.Expr {
                        }
                }
        case token.COMMA:
+               firstComma = p.pos
                // instance expression
                args = append(args, index[0])
                for p.tok == token.COMMA {
@@ -1549,6 +1551,11 @@ func (p *parser) parseIndexOrSliceOrInstance(x ast.Expr) ast.Expr {
                return &ast.IndexExpr{X: x, Lbrack: lbrack, Index: index[0], Rbrack: rbrack}
        }
 
+       if p.mode&ParseTypeParams == 0 {
+               p.error(firstComma, "expected ']' or ':', found ','")
+               return &ast.BadExpr{From: args[0].Pos(), To: args[len(args)-1].End()}
+       }
+
        // instance expression
        return &ast.CallExpr{Fun: x, Lparen: lbrack, Args: args, Rparen: rbrack, Brackets: true}
 }
diff --git a/src/go/parser/testdata/typeparams.src b/src/go/parser/testdata/typeparams.src
new file mode 100644 (file)
index 0000000..1fea23f
--- /dev/null
@@ -0,0 +1,17 @@
+// 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.
+
+// Test cases for error messages produced while parsing code that uses type
+// parameters, without ParseTypeParams being enabled.
+
+package p
+
+type List[E any /* ERROR "expected ']', found any" */ ] []E
+
+type Pair[L, /* ERROR "expected ']', found ','" */ R any] struct {
+       Left L
+       Right R
+}
+
+var _ = Pair[int, /* ERROR "expected ']' or ':', found ','" */ string]{}