mirror of
https://github.com/golang/go
synced 2024-09-15 22:20:06 +00:00
[dev.typeparams] go/types: implement close(ch) where ch is of type parameter type
This is a port of CL 333713 to go/types. Change-Id: I517f52592f65cc76e11a12d9148b20c12d9e3e81 Reviewed-on: https://go-review.googlesource.com/c/go/+/335077 Trust: Robert Findley <rfindley@google.com> Run-TryBot: Robert Findley <rfindley@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
parent
19b4142f24
commit
cf7e66b7d4
|
@ -217,19 +217,23 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
|
||||||
|
|
||||||
case _Close:
|
case _Close:
|
||||||
// close(c)
|
// close(c)
|
||||||
c := asChan(x.typ)
|
if !underIs(x.typ, func(u Type) bool {
|
||||||
if c == nil {
|
uch, _ := u.(*Chan)
|
||||||
check.invalidArg(x, _InvalidClose, "%s is not a channel", x)
|
if uch == nil {
|
||||||
|
check.invalidOp(x, _InvalidClose, "cannot close non-channel %s", x)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if uch.dir == RecvOnly {
|
||||||
|
check.invalidOp(x, _InvalidClose, "cannot close receive-only channel %s", x)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if c.dir == RecvOnly {
|
|
||||||
check.invalidArg(x, _InvalidClose, "%s must not be a receive-only channel", x)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
x.mode = novalue
|
x.mode = novalue
|
||||||
if check.Types != nil {
|
if check.Types != nil {
|
||||||
check.recordBuiltinType(call.Fun, makeSig(nil, c))
|
check.recordBuiltinType(call.Fun, makeSig(nil, x.typ))
|
||||||
}
|
}
|
||||||
|
|
||||||
case _Complex:
|
case _Complex:
|
||||||
|
|
39
src/go/types/testdata/check/builtins.go2
vendored
39
src/go/types/testdata/check/builtins.go2
vendored
|
@ -6,6 +6,45 @@
|
||||||
|
|
||||||
package builtins
|
package builtins
|
||||||
|
|
||||||
|
// close
|
||||||
|
|
||||||
|
type C0 interface{ int }
|
||||||
|
type C1 interface{ chan int }
|
||||||
|
type C2 interface{ chan int | <-chan int }
|
||||||
|
type C3 interface{ chan int | chan float32 }
|
||||||
|
type C4 interface{ chan int | chan<- int }
|
||||||
|
type C5[T any] interface{ ~chan T | chan<- T }
|
||||||
|
|
||||||
|
func _[T any](ch T) {
|
||||||
|
close(ch /* ERROR cannot close non-channel */)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _[T C0](ch T) {
|
||||||
|
close(ch /* ERROR cannot close non-channel */)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _[T C1](ch T) {
|
||||||
|
close(ch)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _[T C2](ch T) {
|
||||||
|
close(ch /* ERROR cannot close receive-only channel */)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _[T C3](ch T) {
|
||||||
|
close(ch)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _[T C4](ch T) {
|
||||||
|
close(ch)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _[T C5[X], X any](ch T) {
|
||||||
|
close(ch)
|
||||||
|
}
|
||||||
|
|
||||||
|
// make
|
||||||
|
|
||||||
type Bmc interface {
|
type Bmc interface {
|
||||||
~map[rune]string | ~chan int
|
~map[rune]string | ~chan int
|
||||||
}
|
}
|
||||||
|
|
2
src/go/types/testdata/check/builtins.src
vendored
2
src/go/types/testdata/check/builtins.src
vendored
|
@ -144,7 +144,7 @@ func close1() {
|
||||||
var r <-chan int
|
var r <-chan int
|
||||||
close() // ERROR not enough arguments
|
close() // ERROR not enough arguments
|
||||||
close(1, 2) // ERROR too many arguments
|
close(1, 2) // ERROR too many arguments
|
||||||
close(42 /* ERROR not a channel */)
|
close(42 /* ERROR cannot close non-channel */)
|
||||||
close(r /* ERROR receive-only channel */)
|
close(r /* ERROR receive-only channel */)
|
||||||
close(c)
|
close(c)
|
||||||
_ = close /* ERROR used as value */ (c)
|
_ = close /* ERROR used as value */ (c)
|
||||||
|
|
|
@ -105,11 +105,6 @@ func asPointer(t Type) *Pointer {
|
||||||
return op
|
return op
|
||||||
}
|
}
|
||||||
|
|
||||||
func asTuple(t Type) *Tuple {
|
|
||||||
op, _ := optype(t).(*Tuple)
|
|
||||||
return op
|
|
||||||
}
|
|
||||||
|
|
||||||
func asSignature(t Type) *Signature {
|
func asSignature(t Type) *Signature {
|
||||||
op, _ := optype(t).(*Signature)
|
op, _ := optype(t).(*Signature)
|
||||||
return op
|
return op
|
||||||
|
@ -120,11 +115,6 @@ func asMap(t Type) *Map {
|
||||||
return op
|
return op
|
||||||
}
|
}
|
||||||
|
|
||||||
func asChan(t Type) *Chan {
|
|
||||||
op, _ := optype(t).(*Chan)
|
|
||||||
return op
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the argument to asInterface, asNamed, or asTypeParam is of the respective type
|
// If the argument to asInterface, asNamed, or asTypeParam is of the respective type
|
||||||
// (possibly after expanding an instance type), these methods return that type.
|
// (possibly after expanding an instance type), these methods return that type.
|
||||||
// Otherwise the result is nil.
|
// Otherwise the result is nil.
|
||||||
|
|
Loading…
Reference in a new issue