aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2021-06-03 20:53:08 -0700
committerRobert Griesemer <gri@golang.org>2021-06-05 01:52:24 +0000
commit692399fbaa09578314f8583e49505c6784e8d335 (patch)
tree848362e0ef07e32f8a50cb8eadf6f71e9bd2b070
parenta94e4f5a8590e7c8d3aa058fb592561d870285a9 (diff)
downloadgo-692399fbaa09578314f8583e49505c6784e8d335.tar.gz
go-692399fbaa09578314f8583e49505c6784e8d335.zip
[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>
-rw-r--r--src/cmd/compile/internal/syntax/parser.go17
-rw-r--r--src/cmd/compile/internal/syntax/testdata/issue46558.src14
2 files changed, 30 insertions, 1 deletions
diff --git a/src/cmd/compile/internal/syntax/parser.go b/src/cmd/compile/internal/syntax/parser.go
index 0e711a0113..503dea7fae 100644
--- a/src/cmd/compile/internal/syntax/parser.go
+++ b/src/cmd/compile/internal/syntax/parser.go
@@ -1100,7 +1100,7 @@ loop:
complit_ok = true
}
case *IndexExpr:
- if p.xnest >= 0 {
+ if p.xnest >= 0 && !isValue(t) {
// x is possibly a composite literal type
complit_ok = true
}
@@ -1127,6 +1127,21 @@ loop:
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 .
func (p *parser) bare_complitexpr() Expr {
if trace {
diff --git a/src/cmd/compile/internal/syntax/testdata/issue46558.src b/src/cmd/compile/internal/syntax/testdata/issue46558.src
new file mode 100644
index 0000000000..a22b600825
--- /dev/null
+++ b/src/cmd/compile/internal/syntax/testdata/issue46558.src
@@ -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