mirror of
https://github.com/golang/go
synced 2024-11-12 00:30:22 -07:00
[dev.typeparams] go/types: implement delete(m, k) where m is of type parameter type
This is a port of CL 333729 to go/types. Change-Id: I8682f549a7a15124b1b338f8c73e83a57d138368 Reviewed-on: https://go-review.googlesource.com/c/go/+/335078 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
cf7e66b7d4
commit
b3d91e3a24
@ -369,25 +369,40 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
|
|||||||
x.typ = Typ[Int]
|
x.typ = Typ[Int]
|
||||||
|
|
||||||
case _Delete:
|
case _Delete:
|
||||||
// delete(m, k)
|
// delete(map_, key)
|
||||||
m := asMap(x.typ)
|
// map_ must be a map type or a type parameter describing map types.
|
||||||
if m == nil {
|
// The key cannot be a type parameter for now.
|
||||||
|
map_ := x.typ
|
||||||
|
var key Type
|
||||||
|
if !underIs(map_, func(u Type) bool {
|
||||||
|
map_, _ := u.(*Map)
|
||||||
|
if map_ == nil {
|
||||||
check.invalidArg(x, _InvalidDelete, "%s is not a map", x)
|
check.invalidArg(x, _InvalidDelete, "%s is not a map", x)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if key != nil && !Identical(map_.key, key) {
|
||||||
|
check.invalidArg(x, _Todo, "maps of %s must have identical key types", x)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
key = map_.key
|
||||||
|
return true
|
||||||
|
}) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
arg(x, 1) // k
|
arg(x, 1) // k
|
||||||
if x.mode == invalid {
|
if x.mode == invalid {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
check.assignment(x, m.key, "argument to delete")
|
check.assignment(x, key, "argument to delete")
|
||||||
if x.mode == invalid {
|
if x.mode == invalid {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
x.mode = novalue
|
x.mode = novalue
|
||||||
if check.Types != nil {
|
if check.Types != nil {
|
||||||
check.recordBuiltinType(call.Fun, makeSig(nil, m, m.key))
|
check.recordBuiltinType(call.Fun, makeSig(nil, map_, key))
|
||||||
}
|
}
|
||||||
|
|
||||||
case _Imag, _Real:
|
case _Imag, _Real:
|
||||||
|
37
src/go/types/testdata/check/builtins.go2
vendored
37
src/go/types/testdata/check/builtins.go2
vendored
@ -43,6 +43,43 @@ func _[T C5[X], X any](ch T) {
|
|||||||
close(ch)
|
close(ch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// delete
|
||||||
|
|
||||||
|
type M0 interface{ int }
|
||||||
|
type M1 interface{ map[string]int }
|
||||||
|
type M2 interface { map[string]int | map[string]float64 }
|
||||||
|
type M3 interface{ map[string]int | map[rune]int }
|
||||||
|
type M4[K comparable, V any] interface{ map[K]V | map[rune]V }
|
||||||
|
|
||||||
|
func _[T any](m T) {
|
||||||
|
delete(m /* ERROR not a map */, "foo")
|
||||||
|
}
|
||||||
|
|
||||||
|
func _[T M0](m T) {
|
||||||
|
delete(m /* ERROR not a map */, "foo")
|
||||||
|
}
|
||||||
|
|
||||||
|
func _[T M1](m T) {
|
||||||
|
delete(m, "foo")
|
||||||
|
}
|
||||||
|
|
||||||
|
func _[T M2](m T) {
|
||||||
|
delete(m, "foo")
|
||||||
|
delete(m, 0 /* ERROR cannot use .* as string */)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _[T M3](m T) {
|
||||||
|
delete(m /* ERROR must have identical key types */, "foo")
|
||||||
|
}
|
||||||
|
|
||||||
|
func _[T M4[rune, V], V any](m T) {
|
||||||
|
delete(m, 'k')
|
||||||
|
}
|
||||||
|
|
||||||
|
func _[T M4[K, V], K comparable, V any](m T) {
|
||||||
|
delete(m /* ERROR must have identical key types */, "foo")
|
||||||
|
}
|
||||||
|
|
||||||
// make
|
// make
|
||||||
|
|
||||||
type Bmc interface {
|
type Bmc interface {
|
||||||
|
@ -110,11 +110,6 @@ func asSignature(t Type) *Signature {
|
|||||||
return op
|
return op
|
||||||
}
|
}
|
||||||
|
|
||||||
func asMap(t Type) *Map {
|
|
||||||
op, _ := optype(t).(*Map)
|
|
||||||
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 New Issue
Block a user