From: cia-rana Date: Mon, 14 Nov 2022 08:01:03 +0000 (+0900) Subject: go/parser: allow trailing commas in embedded instantiated types X-Git-Tag: go1.20rc1~189 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=cafb49ac731f862f386862d64b27b8314eeb2909;p=gostls13.git go/parser: allow trailing commas in embedded instantiated types go/parser can correctly parse interfaces that instantiate and embed generic interfaces, but not structs. This is because in the case of structs, it does not expect RBRACK as a token trailing COMMA in the type argument, even though it is allowed by the spec. For example, go/parser produces an error for the type declaration below: type A struct { B[byte, []byte,] } Fixes #56748 Change-Id: Ibb2addd6cf9b381d8470a6d20eedb93f13f93cd6 Reviewed-on: https://go-review.googlesource.com/c/go/+/450175 Run-TryBot: Robert Griesemer Reviewed-by: Robert Findley TryBot-Result: Gopher Robot Auto-Submit: Robert Griesemer Reviewed-by: Robert Griesemer --- diff --git a/src/go/parser/parser.go b/src/go/parser/parser.go index 4dcfaca299..fac24dfa05 100644 --- a/src/go/parser/parser.go +++ b/src/go/parser/parser.go @@ -587,15 +587,19 @@ func (p *parser) parseArrayFieldOrTypeInstance(x *ast.Ident) (*ast.Ident, ast.Ex defer un(trace(p, "ArrayFieldOrTypeInstance")) } - // TODO(gri) Should we allow a trailing comma in a type argument - // list such as T[P,]? (We do in parseTypeInstance). lbrack := p.expect(token.LBRACK) + trailingComma := token.NoPos // if valid, the position of a trailing comma preceding the ']' var args []ast.Expr if p.tok != token.RBRACK { p.exprLev++ args = append(args, p.parseRhs()) for p.tok == token.COMMA { + comma := p.pos p.next() + if p.tok == token.RBRACK { + trailingComma = comma + break + } args = append(args, p.parseRhs()) } p.exprLev-- @@ -613,6 +617,10 @@ func (p *parser) parseArrayFieldOrTypeInstance(x *ast.Ident) (*ast.Ident, ast.Ex elt := p.tryIdentOrType() if elt != nil { // x [P]E + if trailingComma.IsValid() { + // Trailing commas are invalid in array type fields. + p.error(trailingComma, "unexpected comma; expecting ]") + } return x, &ast.ArrayType{Lbrack: lbrack, Len: args[0], Elt: elt} } } diff --git a/src/go/parser/testdata/tparams.go2 b/src/go/parser/testdata/tparams.go2 index abde5dc050..1a9a6c635d 100644 --- a/src/go/parser/testdata/tparams.go2 +++ b/src/go/parser/testdata/tparams.go2 @@ -9,12 +9,19 @@ type _[a t, b t, c /* ERROR "type parameters must be named" */ ] struct{} type _ struct { t [n]byte t[a] + t[a,] t[a, b] + t[a, b,] +} +type _ struct { + t [n, /* ERROR "unexpected comma; expecting ]" */ ]byte } type _ interface { t[a] + t[a,] m[ /* ERROR "method must have no type parameters" */ _ _, /* ERROR mixed */ _]() t[a, b] + t[a, b,] } func _[] /* ERROR "empty type parameter list" */ ()