aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/types2/expr.go
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2021-07-09 17:12:07 -0700
committerRobert Griesemer <gri@golang.org>2021-07-14 23:33:43 +0000
commitff33d3dc3a47a4eed17728b8460de4572198cec3 (patch)
tree46f509e94483cc1f04e6aa5cf9fd34fe7146e1fc /src/cmd/compile/internal/types2/expr.go
parente3e6cd30221185d6e4fa76f109f96fdede580729 (diff)
downloadgo-ff33d3dc3a47a4eed17728b8460de4572198cec3.tar.gz
go-ff33d3dc3a47a4eed17728b8460de4572198cec3.zip
[dev.typeparams] cmd/compile/internal/types2: implement <-ch where ch is of type parameter type
For #43671 Change-Id: I7db4b3886fab44ec0de7c0935e0ab21c26e3335c Reviewed-on: https://go-review.googlesource.com/c/go/+/333709 Trust: Robert Griesemer <gri@golang.org> Run-TryBot: Robert Griesemer <gri@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
Diffstat (limited to 'src/cmd/compile/internal/types2/expr.go')
-rw-r--r--src/cmd/compile/internal/types2/expr.go36
1 files changed, 27 insertions, 9 deletions
diff --git a/src/cmd/compile/internal/types2/expr.go b/src/cmd/compile/internal/types2/expr.go
index bd35417c64..d4425a2bfd 100644
--- a/src/cmd/compile/internal/types2/expr.go
+++ b/src/cmd/compile/internal/types2/expr.go
@@ -157,6 +157,14 @@ var op2str2 = [...]string{
syntax.Shl: "shift",
}
+func underIs(typ Type, f func(Type) bool) bool {
+ u := under(typ)
+ if tpar, _ := u.(*TypeParam); tpar != nil {
+ return tpar.underIs(f)
+ }
+ return f(u)
+}
+
func (check *Checker) unary(x *operand, e *syntax.Operation) {
check.expr(x, e.X)
if x.mode == invalid {
@@ -177,19 +185,29 @@ func (check *Checker) unary(x *operand, e *syntax.Operation) {
return
case syntax.Recv:
- typ := asChan(x.typ)
- if typ == nil {
- check.errorf(x, invalidOp+"cannot receive from non-channel %s", x)
- x.mode = invalid
- return
- }
- if typ.dir == SendOnly {
- check.errorf(x, invalidOp+"cannot receive from send-only channel %s", x)
+ var elem Type
+ if !underIs(x.typ, func(u Type) bool {
+ ch, _ := u.(*Chan)
+ if ch == nil {
+ check.errorf(x, invalidOp+"cannot receive from non-channel %s", x)
+ return false
+ }
+ if ch.dir == SendOnly {
+ check.errorf(x, invalidOp+"cannot receive from send-only channel %s", x)
+ return false
+ }
+ if elem != nil && !Identical(ch.elem, elem) {
+ check.errorf(x, invalidOp+"channels of %s must have the same element type", x)
+ return false
+ }
+ elem = ch.elem
+ return true
+ }) {
x.mode = invalid
return
}
x.mode = commaok
- x.typ = typ.elem
+ x.typ = elem
check.hasCallOrRecv = true
return
}