var names []*ast.Ident
var typ ast.Expr
- if p.tok == token.IDENT {
+ switch p.tok {
+ case token.IDENT:
name := p.parseIdent()
if p.tok == token.PERIOD || p.tok == token.STRING || p.tok == token.SEMICOLON || p.tok == token.RBRACE {
// embedded type
typ = p.parseType()
}
}
- } else {
- // embedded, possibly generic type
- // (using the enclosing parentheses to distinguish it from a named field declaration)
- // TODO(rFindley) confirm that this doesn't allow parenthesized embedded type
- typ = p.parseType()
+ case token.MUL:
+ star := p.pos
+ p.next()
+ if p.tok == token.LPAREN {
+ // *(T)
+ p.error(p.pos, "cannot parenthesize embedded type")
+ p.next()
+ typ = p.parseQualifiedIdent(nil)
+ // expect closing ')' but no need to complain if missing
+ if p.tok == token.RPAREN {
+ p.next()
+ }
+ } else {
+ // *T
+ typ = p.parseQualifiedIdent(nil)
+ }
+ typ = &ast.StarExpr{Star: star, X: typ}
+
+ case token.LPAREN:
+ p.error(p.pos, "cannot parenthesize embedded type")
+ p.next()
+ if p.tok == token.MUL {
+ // (*T)
+ star := p.pos
+ p.next()
+ typ = &ast.StarExpr{Star: star, X: p.parseQualifiedIdent(nil)}
+ } else {
+ // (T)
+ typ = p.parseQualifiedIdent(nil)
+ }
+ // expect closing ')' but no need to complain if missing
+ if p.tok == token.RPAREN {
+ p.next()
+ }
+
+ default:
+ pos := p.pos
+ p.errorExpected(pos, "field name or embedded type")
+ p.advance(exprEnd)
+ typ = &ast.BadExpr{From: pos, To: p.pos}
}
var tag *ast.BasicLit
`package p; type T = int`,
`package p; type (T = p.T; _ = struct{}; x = *T)`,
`package p; type T (*int)`,
- `package p; type _ struct{ ((int)) }`,
- `package p; type _ struct{ (*(int)) }`,
- `package p; type _ struct{ ([]byte) }`, // disallowed by type-checker
+ `package p; type _ struct{ int }`,
+ `package p; type _ struct{ pkg.T }`,
+ `package p; type _ struct{ *pkg.T }`,
`package p; var _ = func()T(nil)`,
`package p; func _(T (P))`,
`package p; func _(T []E)`,
`package p; func (type /* ERROR "found 'type'" */ T)(T) _()`,
`package p; type _[A+B, /* ERROR "unexpected comma" */ ] int`,
+ `package p; type _ struct{ [ /* ERROR "expected '}', found '\['" */ ]byte }`,
+ `package p; type _ struct{ ( /* ERROR "cannot parenthesize embedded type" */ int) }`,
+ `package p; type _ struct{ ( /* ERROR "cannot parenthesize embedded type" */ []byte) }`,
+ `package p; type _ struct{ *( /* ERROR "cannot parenthesize embedded type" */ int) }`,
+ `package p; type _ struct{ *( /* ERROR "cannot parenthesize embedded type" */ []byte) }`,
+
// TODO(rfindley): this error should be positioned on the ':'
`package p; var a = a[[]int:[ /* ERROR "expected expression" */ ]int];`,