]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] cmd/compile/internal/syntax: not all index expressions can be instan...
authorRobert Griesemer <gri@golang.org>
Fri, 4 Jun 2021 03:53:08 +0000 (20:53 -0700)
committerRobert Griesemer <gri@golang.org>
Sat, 5 Jun 2021 01:52:24 +0000 (01:52 +0000)
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>
src/cmd/compile/internal/syntax/parser.go
src/cmd/compile/internal/syntax/testdata/issue46558.src [new file with mode: 0644]

index 0e711a0113fb29f238dccbfefaa7f241511550d9..503dea7fae6ed295b42358078d1dd1eed8133d97 100644 (file)
@@ -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 (file)
index 0000000..a22b600
--- /dev/null
@@ -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