]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/syntax: correct follow token for type parameter lists
authorRobert Griesemer <gri@golang.org>
Thu, 9 Sep 2021 22:43:19 +0000 (15:43 -0700)
committerRobert Griesemer <gri@golang.org>
Fri, 10 Sep 2021 16:08:21 +0000 (16:08 +0000)
When parsing a type parameter declaration, parts of the code still
expected a ) as closing token. Use the correct follow token ) or ]
depending on parameter list kind.

Also, consistently use tokstring (not tok.String()) for user-facing
(error) messages.

Follow-up on comment in CL 348730.

For #43527.

Change-Id: Ib1d4feb526771a1668a54c3bb7a671f6c8a65940
Reviewed-on: https://go-review.googlesource.com/c/go/+/348742
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
src/cmd/compile/internal/syntax/parser.go
src/cmd/compile/internal/syntax/testdata/tparams.go2

index c836a21c2fd437b8bf6fe46bc5a2d4708b7ef618..82cb06b1804337af37db1c6928191c72ea5ab093 100644 (file)
@@ -276,7 +276,9 @@ func (p *parser) syntaxErrorAt(pos Pos, msg string) {
 }
 
 // tokstring returns the English word for selected punctuation tokens
-// for more readable error messages.
+// for more readable error messages. Use tokstring (not tok.String())
+// for user-facing (error) messages; use tok.String() for debugging
+// output.
 func tokstring(tok token) string {
        switch tok {
        case _Comma:
@@ -1839,7 +1841,7 @@ func (p *parser) embeddedTerm() Expr {
 }
 
 // ParameterDecl = [ IdentifierList ] [ "..." ] Type .
-func (p *parser) paramDeclOrNil(name *Name) *Field {
+func (p *parser) paramDeclOrNil(name *Name, follow token) *Field {
        if trace {
                defer p.trace("paramDecl")()
        }
@@ -1893,8 +1895,8 @@ func (p *parser) paramDeclOrNil(name *Name) *Field {
                return f
        }
 
-       p.syntaxError("expecting )")
-       p.advance(_Comma, _Rparen)
+       p.syntaxError("expecting " + tokstring(follow))
+       p.advance(_Comma, follow)
        return nil
 }
 
@@ -1911,7 +1913,7 @@ func (p *parser) paramList(name *Name, close token, requireNames bool) (list []*
        var named int // number of parameters that have an explicit name and type
        var typed int // number of parameters that have an explicit type
        end := p.list(_Comma, close, func() bool {
-               par := p.paramDeclOrNil(name)
+               par := p.paramDeclOrNil(name, close)
                name = nil // 1st name was consumed if present
                if par != nil {
                        if debug && par.Name == nil && par.Type == nil {
@@ -2211,7 +2213,7 @@ func (p *parser) header(keyword token) (init SimpleStmt, cond Expr, post SimpleS
        if p.tok != _Semi {
                // accept potential varDecl but complain
                if p.got(_Var) {
-                       p.syntaxError(fmt.Sprintf("var declaration not allowed in %s initializer", keyword.String()))
+                       p.syntaxError(fmt.Sprintf("var declaration not allowed in %s initializer", tokstring(keyword)))
                }
                init = p.simpleStmt(nil, keyword)
                // If we have a range clause, we are done (can only happen for keyword == _For).
index 8e47ff5ed84d9ce44c25d91737962ea63407a18f..80e155bfe05213df73abaa04ffea861e377cfd49 100644 (file)
@@ -20,3 +20,5 @@ type t interface {
 func f[ /* ERROR empty type parameter list */ ]()
 func f[a, b /* ERROR missing type constraint */ ]()
 func f[a t, b t, c /* ERROR missing type constraint */ ]()
+
+func f[a b,  /* ERROR expecting ] */ 0] ()