aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/syntax/parser.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/syntax/parser.go')
-rw-r--r--src/cmd/compile/internal/syntax/parser.go31
1 files changed, 29 insertions, 2 deletions
diff --git a/src/cmd/compile/internal/syntax/parser.go b/src/cmd/compile/internal/syntax/parser.go
index e7b8840b33..acffd84885 100644
--- a/src/cmd/compile/internal/syntax/parser.go
+++ b/src/cmd/compile/internal/syntax/parser.go
@@ -604,7 +604,7 @@ func (p *parser) typeDecl(group *Group) Decl {
} else {
// x is the array length expression
if debug && x == nil {
- panic("internal error: nil expression")
+ panic("length expression is nil")
}
d.Type = p.arrayType(pos, x)
}
@@ -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 {
@@ -1443,6 +1458,18 @@ func (p *parser) interfaceType() *InterfaceType {
}
return false
}
+
+ default:
+ if p.mode&AllowGenerics != 0 {
+ pos := p.pos()
+ if t := p.typeOrNil(); t != nil {
+ f := new(Field)
+ f.pos = pos
+ f.Type = t
+ typ.MethodList = append(typ.MethodList, p.embeddedElem(f))
+ return false
+ }
+ }
}
if p.mode&AllowGenerics != 0 {