From 1be8fcdcdce01ca7cffb1fd90c1cd706c3ea4ee4 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Wed, 31 Aug 2022 15:54:28 -0700 Subject: [PATCH] cmd/compile/internal/syntax: more strict parsing of type instances Report a syntax error if the first element of a type instance is not actually a type (but some other expression), rather then relying on the type checker error in this case. This matches the behavior of go/parser. Adjust the corresponding types2 test case. For #54511. Change-Id: Ia82b3a7d444738c56955ce6c15609470b3431fd1 Reviewed-on: https://go-review.googlesource.com/c/go/+/426657 Reviewed-by: Robert Griesemer Auto-Submit: Robert Griesemer Run-TryBot: Robert Griesemer Reviewed-by: Robert Findley TryBot-Result: Gopher Robot --- src/cmd/compile/internal/syntax/parser.go | 20 +++++++++++-------- .../types2/testdata/fixedbugs/issue48827.go | 2 +- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/cmd/compile/internal/syntax/parser.go b/src/cmd/compile/internal/syntax/parser.go index b956028404..1f5e8bc449 100644 --- a/src/cmd/compile/internal/syntax/parser.go +++ b/src/cmd/compile/internal/syntax/parser.go @@ -1117,7 +1117,7 @@ loop: p.syntaxError("expected operand") i = p.badExpr() } else { - i, comma = p.typeList() + i, comma = p.typeList(false) } if comma || p.tok == _Rbrack { p.want(_Rbrack) @@ -1401,7 +1401,7 @@ func (p *parser) typeInstance(typ Expr) Expr { p.syntaxError("expected type argument list") x.Index = p.badExpr() } else { - x.Index, _ = p.typeList() + x.Index, _ = p.typeList(true) } p.want(_Rbrack) return x @@ -1670,7 +1670,7 @@ func (p *parser) arrayOrTArgs() Expr { } // x [n]E or x[n,], x[n1, n2], ... - n, comma := p.typeList() + n, comma := p.typeList(false) p.want(_Rbrack) if !comma { if elem := p.typeOrNil(); elem != nil { @@ -2752,21 +2752,25 @@ func (p *parser) exprList() Expr { return x } -// typeList parses a non-empty, comma-separated list of expressions, -// optionally followed by a comma. The first list element may be any -// expression, all other list elements must be type expressions. +// typeList parses a non-empty, comma-separated list of types, +// optionally followed by a comma. If strict is set to false, +// the first element may also be a (non-type) expression. // If there is more than one argument, the result is a *ListExpr. // The comma result indicates whether there was a (separating or // trailing) comma. // // typeList = arg { "," arg } [ "," ] . -func (p *parser) typeList() (x Expr, comma bool) { +func (p *parser) typeList(strict bool) (x Expr, comma bool) { if trace { defer p.trace("typeList")() } p.xnest++ - x = p.expr() + if strict { + x = p.type_() + } else { + x = p.expr() + } if p.got(_Comma) { comma = true if t := p.typeOrNil(); t != nil { diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48827.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48827.go index 52ccd1ce0c..408031cdbc 100644 --- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48827.go +++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48827.go @@ -15,5 +15,5 @@ type ( // The example from the issue. func _() { - _ = &([10]bool /* ERROR "invalid operation.*bool is not a generic type" */ [1]{}) + _ = &([10]bool /* ERROR "invalid operation.*bool is not a generic type" */ [1 /* ERROR expected type */ ]{}) } -- 2.50.0