mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.typeparams] cmd/compile/internal/types2: port of https://golang.org/cl/270957
This ports the latest updates to the dev.go2go version of types2 to the dev.typeparams version. Change-Id: Ic1b09a8aaeefc701a5c194a587be26e0878e64da Reviewed-on: https://go-review.googlesource.com/c/go/+/270958 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>
This commit is contained in:
parent
6877ee1e07
commit
2140049172
3 changed files with 61 additions and 15 deletions
|
|
@ -1467,18 +1467,18 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
|
||||||
var key operand
|
var key operand
|
||||||
check.expr(&key, e.Index)
|
check.expr(&key, e.Index)
|
||||||
check.assignment(&key, typ.key, "map index")
|
check.assignment(&key, typ.key, "map index")
|
||||||
if x.mode == invalid {
|
// ok to continue even if indexing failed - map element type is known
|
||||||
goto Error
|
|
||||||
}
|
|
||||||
x.mode = mapindex
|
x.mode = mapindex
|
||||||
x.typ = typ.elem
|
x.typ = typ.elem
|
||||||
x.expr = e
|
x.expr = e
|
||||||
return expression
|
return expression
|
||||||
|
|
||||||
case *Sum:
|
case *Sum:
|
||||||
// A sum type can be indexed if all the sum's types
|
// A sum type can be indexed if all of the sum's types
|
||||||
// support indexing and have the same element type.
|
// support indexing and have the same index and element
|
||||||
var elem Type
|
// type. Special rules apply for maps in the sum type.
|
||||||
|
var tkey, telem Type // key is for map types only
|
||||||
|
nmaps := 0 // number of map types in sum type
|
||||||
if typ.is(func(t Type) bool {
|
if typ.is(func(t Type) bool {
|
||||||
var e Type
|
var e Type
|
||||||
switch t := t.Under().(type) {
|
switch t := t.Under().(type) {
|
||||||
|
|
@ -1495,21 +1495,58 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
|
||||||
case *Slice:
|
case *Slice:
|
||||||
e = t.elem
|
e = t.elem
|
||||||
case *Map:
|
case *Map:
|
||||||
|
// If there are multiple maps in the sum type,
|
||||||
|
// they must have identical key types.
|
||||||
|
// TODO(gri) We may be able to relax this rule
|
||||||
|
// but it becomes complicated very quickly.
|
||||||
|
if tkey != nil && !Identical(t.key, tkey) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
tkey = t.key
|
||||||
e = t.elem
|
e = t.elem
|
||||||
|
nmaps++
|
||||||
case *TypeParam:
|
case *TypeParam:
|
||||||
check.errorf(x, "type of %s contains a type parameter - cannot index (implementation restriction)", x)
|
check.errorf(x, "type of %s contains a type parameter - cannot index (implementation restriction)", x)
|
||||||
case *instance:
|
case *instance:
|
||||||
unimplemented()
|
panic("unimplemented")
|
||||||
}
|
}
|
||||||
if e != nil && (e == elem || elem == nil) {
|
if e == nil || telem != nil && !Identical(e, telem) {
|
||||||
elem = e
|
return false
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
return false
|
telem = e
|
||||||
|
return true
|
||||||
}) {
|
}) {
|
||||||
valid = true
|
// If there are maps, the index expression must be assignable
|
||||||
x.mode = variable
|
// to the map key type (as for simple map index expressions).
|
||||||
x.typ = elem
|
if nmaps > 0 {
|
||||||
|
var key operand
|
||||||
|
check.expr(&key, e.Index)
|
||||||
|
check.assignment(&key, tkey, "map index")
|
||||||
|
// ok to continue even if indexing failed - map element type is known
|
||||||
|
|
||||||
|
// If there are only maps, we are done.
|
||||||
|
if nmaps == len(typ.types) {
|
||||||
|
x.mode = mapindex
|
||||||
|
x.typ = telem
|
||||||
|
x.expr = e
|
||||||
|
return expression
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise we have mix of maps and other types. For
|
||||||
|
// now we require that the map key be an integer type.
|
||||||
|
// TODO(gri) This is probably not good enough.
|
||||||
|
valid = isInteger(tkey)
|
||||||
|
// avoid 2nd indexing error if indexing failed above
|
||||||
|
if !valid && key.mode == invalid {
|
||||||
|
goto Error
|
||||||
|
}
|
||||||
|
x.mode = value // map index expressions are not addressable
|
||||||
|
} else {
|
||||||
|
// no maps
|
||||||
|
valid = true
|
||||||
|
x.mode = variable
|
||||||
|
}
|
||||||
|
x.typ = telem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,7 @@ func indexes() {
|
||||||
var ok mybool
|
var ok mybool
|
||||||
_, ok = m["bar"]
|
_, ok = m["bar"]
|
||||||
_ = ok
|
_ = ok
|
||||||
|
_ = m[0 /* ERROR "cannot convert 0" */ ] + "foo" // ERROR "cannot convert"
|
||||||
|
|
||||||
var t string
|
var t string
|
||||||
_ = t[- /* ERROR "negative" */ 1]
|
_ = t[- /* ERROR "negative" */ 1]
|
||||||
|
|
|
||||||
|
|
@ -94,11 +94,19 @@ func _[T any] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
|
||||||
func _[T interface{ type int }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
|
func _[T interface{ type int }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
|
||||||
func _[T interface{ type string }] (x T, i int) { _ = x[i] }
|
func _[T interface{ type string }] (x T, i int) { _ = x[i] }
|
||||||
func _[T interface{ type []int }] (x T, i int) { _ = x[i] }
|
func _[T interface{ type []int }] (x T, i int) { _ = x[i] }
|
||||||
func _[T interface{ type [10]int, *[20]int, map[string]int }] (x T, i int) { _ = x[i] }
|
func _[T interface{ type [10]int, *[20]int, map[int]int }] (x T, i int) { _ = x[i] }
|
||||||
func _[T interface{ type string, []byte }] (x T, i int) { _ = x[i] }
|
func _[T interface{ type string, []byte }] (x T, i int) { _ = x[i] }
|
||||||
func _[T interface{ type []int, [1]rune }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
|
func _[T interface{ type []int, [1]rune }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
|
||||||
func _[T interface{ type string, []rune }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
|
func _[T interface{ type string, []rune }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
|
||||||
|
|
||||||
|
// indexing with various combinations of map types in type lists (see issue #42616)
|
||||||
|
func _[T interface{ type []E, map[int]E }, E any](x T, i int) { _ = x[i] }
|
||||||
|
func _[T interface{ type []E }, E any](x T, i int) { _ = &x[i] }
|
||||||
|
func _[T interface{ type map[int]E }, E any](x T, i int) { _, _ = x[i] } // comma-ok permitted
|
||||||
|
func _[T interface{ type []E, map[int]E }, E any](x T, i int) { _ = &x /* ERROR cannot take address */ [i] }
|
||||||
|
func _[T interface{ type []E, map[int]E, map[uint]E }, E any](x T, i int) { _ = x /* ERROR cannot index */ [i] } // different map element types
|
||||||
|
func _[T interface{ type []E, map[string]E }, E any](x T, i int) { _ = x[i /* ERROR cannot use i */ ] }
|
||||||
|
|
||||||
// slicing
|
// slicing
|
||||||
// TODO(gri) implement this
|
// TODO(gri) implement this
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue