]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/syntax: more strict parsing of type instances
authorRobert Griesemer <gri@golang.org>
Wed, 31 Aug 2022 22:54:28 +0000 (15:54 -0700)
committerGopher Robot <gobot@golang.org>
Fri, 2 Sep 2022 02:14:57 +0000 (02:14 +0000)
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 <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
Run-TryBot: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/compile/internal/syntax/parser.go
src/cmd/compile/internal/types2/testdata/fixedbugs/issue48827.go

index b956028404d121ffbdd646cc2715b6263589fb25..1f5e8bc449f882dd10bb32d0b0aedd98dcd42af1 100644 (file)
@@ -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 {
index 52ccd1ce0c2475a54d1d10ea2b57d81355f62620..408031cdbc2bb210a4f2b28e357b2460d0ddfdc8 100644 (file)
@@ -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 */ ]{})
 }