]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/types2: permit parentheses around types in interfaces
authorRobert Griesemer <gri@golang.org>
Tue, 19 Apr 2022 00:19:47 +0000 (17:19 -0700)
committerRobert Griesemer <gri@golang.org>
Tue, 19 Apr 2022 23:20:11 +0000 (23:20 +0000)
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>
src/cmd/compile/internal/syntax/parser.go
src/cmd/compile/internal/syntax/testdata/issue52391.go [new file with mode: 0644]

index f18d5268772f1771797616ee0b60bd84c97e0d4f..9de6d4f45ebd80acc9d8f2c78530d9423409331e 100644 (file)
@@ -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
        })
 
diff --git a/src/cmd/compile/internal/syntax/testdata/issue52391.go b/src/cmd/compile/internal/syntax/testdata/issue52391.go
new file mode 100644 (file)
index 0000000..f2098ce
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2022 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
+
+type _ interface {
+       int
+       (int)
+       (*int)
+       *([]byte)
+       ~(int)
+       (int) | (string)
+       (int) | ~(string)
+       (/* ERROR unexpected ~ */ ~int)
+       (int /* ERROR unexpected \| */ | /* ERROR unexpected string */ string /* ERROR unexpected \) */ )
+}