1
0
mirror of https://github.com/golang/go synced 2024-11-17 10:14:46 -07:00

[dev.typeparams] cmd/compile/internal/syntax: not all index expressions can be instantiated types

An index expression followed by an opening "{" may indicate
a composite literal but only if the index expression can be
a type. Exclude cases where the index expression cannot be
a type (e.g. s[0], a[i+j], etc.).

This leads to a better error message in code that is erroneous.

Fixes #46558.

Change-Id: Ida9291ca30683c211812dfb95abe4969f44c474f
Reviewed-on: https://go-review.googlesource.com/c/go/+/325009
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
Robert Griesemer 2021-06-03 20:53:08 -07:00
parent a94e4f5a85
commit 692399fbaa
2 changed files with 30 additions and 1 deletions

View File

@ -1100,7 +1100,7 @@ loop:
complit_ok = true complit_ok = true
} }
case *IndexExpr: case *IndexExpr:
if p.xnest >= 0 { if p.xnest >= 0 && !isValue(t) {
// x is possibly a composite literal type // x is possibly a composite literal type
complit_ok = true complit_ok = true
} }
@ -1127,6 +1127,21 @@ loop:
return x return x
} }
// isValue reports whether x syntactically must be a value (and not a type) expression.
func isValue(x Expr) bool {
switch x := x.(type) {
case *BasicLit, *CompositeLit, *FuncLit, *SliceExpr, *AssertExpr, *TypeSwitchGuard, *CallExpr:
return true
case *Operation:
return x.Op != Mul || x.Y != nil // *T may be a type
case *ParenExpr:
return isValue(x.X)
case *IndexExpr:
return isValue(x.X) || isValue(x.Index)
}
return false
}
// Element = Expression | LiteralValue . // Element = Expression | LiteralValue .
func (p *parser) bare_complitexpr() Expr { func (p *parser) bare_complitexpr() Expr {
if trace { if trace {

View File

@ -0,0 +1,14 @@
// 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.
package p
func F(s string) {
switch s[0] {
case 'a':
case s[2] { // ERROR unexpected {
case 'b':
}
}
} // ERROR non-declaration statement