diff options
| author | Robert Griesemer <gri@golang.org> | 2022-04-18 17:19:47 -0700 |
|---|---|---|
| committer | Robert Griesemer <gri@golang.org> | 2022-04-19 23:20:11 +0000 |
| commit | 86fa2551fb12338405721089d6db1b9d78e4f05e (patch) | |
| tree | 82f0b85c290391aeb9f7c9a7d77cbb4437aeb620 /src/cmd/compile/internal/syntax/parser.go | |
| parent | 3ae414c31e59c9ee210fa3606f36cf0ea36b9906 (diff) | |
| download | go-86fa2551fb12338405721089d6db1b9d78e4f05e.tar.xz | |
cmd/compile/internal/types2: permit parentheses around types in interfaces
Before Go 1.18, an embedded type name in an interface could not be
parenthesized. With generalized embedding of types in interfaces,
where one might write ~(chan<- int) for clarity (making clear that
the ~ applies to the entire channel type), it also makes sense to
permit (chan<- int), or (int) for that matter.
Adjust the parser accordingly to match the spec.
(go/types already accepts the notation as specified by the spec.)
Fixes #52391.
Change-Id: Ifdd9a199c5ccc3473b2dac40dbca31d2df10d12b
Reviewed-on: https://go-review.googlesource.com/c/go/+/400797
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Griesemer <gri@google.com>
Diffstat (limited to 'src/cmd/compile/internal/syntax/parser.go')
| -rw-r--r-- | src/cmd/compile/internal/syntax/parser.go | 44 |
1 files changed, 7 insertions, 37 deletions
diff --git a/src/cmd/compile/internal/syntax/parser.go b/src/cmd/compile/internal/syntax/parser.go index f18d526877..9de6d4f45e 100644 --- a/src/cmd/compile/internal/syntax/parser.go +++ b/src/cmd/compile/internal/syntax/parser.go @@ -1499,44 +1499,14 @@ func (p *parser) interfaceType() *InterfaceType { p.want(_Interface) p.want(_Lbrace) p.list("interface type", _Semi, _Rbrace, func() bool { - switch p.tok { - case _Name: - f := p.methodDecl() - if f.Name == nil { - f = p.embeddedElem(f) - } - typ.MethodList = append(typ.MethodList, f) - return false - - case _Lparen: - p.syntaxError("cannot parenthesize embedded type") - f := new(Field) - f.pos = p.pos() - p.next() - f.Type = p.qualifiedName(nil) - p.want(_Rparen) - typ.MethodList = append(typ.MethodList, f) - return false - - case _Operator: - if p.op == Tilde { - typ.MethodList = append(typ.MethodList, p.embeddedElem(nil)) - return false - } - - default: - 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 - } + var f *Field + if p.tok == _Name { + f = p.methodDecl() } - - p.syntaxError("expecting method or embedded element") - p.advance(_Semi, _Rbrace) + if f == nil || f.Name == nil { + f = p.embeddedElem(f) + } + typ.MethodList = append(typ.MethodList, f) return false }) |
