mirror of
https://github.com/golang/go.git
synced 2026-04-02 17:30:01 +09:00
reflect: fix support for iter with named boolean in Seq/Seq2
Fixes #77542 Change-Id: Ic2f33f5aabbdf064cbf5aa850f6c08f01352db80 Reviewed-on: https://go-review.googlesource.com/c/go/+/745580 Auto-Submit: Alan Donovan <adonovan@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Alan Donovan <adonovan@google.com> Reviewed-by: Robert Griesemer <gri@google.com>
This commit is contained in:
committed by
Robert Griesemer
parent
ed0367718f
commit
0ac9d84e3d
@@ -36,7 +36,7 @@ func rangeNum[T int8 | int16 | int32 | int64 | int |
|
||||
// Uint, Uint8, Uint16, Uint32, Uint64, Uintptr,
|
||||
// Array, Chan, Map, Slice, or String.
|
||||
func (v Value) Seq() iter.Seq[Value] {
|
||||
if canRangeFunc(v.abiType()) {
|
||||
if canRangeFunc(v.abiType(), 1) {
|
||||
return func(yield func(Value) bool) {
|
||||
rf := MakeFunc(v.Type().In(0), func(in []Value) []Value {
|
||||
return []Value{ValueOf(yield(in[0]))}
|
||||
@@ -122,7 +122,7 @@ func (v Value) Seq() iter.Seq[Value] {
|
||||
// If v's kind is Pointer, the pointer element type must have kind Array.
|
||||
// Otherwise v's kind must be Array, Map, Slice, or String.
|
||||
func (v Value) Seq2() iter.Seq2[Value, Value] {
|
||||
if canRangeFunc2(v.abiType()) {
|
||||
if canRangeFunc(v.abiType(), 2) {
|
||||
return func(yield func(Value, Value) bool) {
|
||||
rf := MakeFunc(v.Type().In(0), func(in []Value) []Value {
|
||||
return []Value{ValueOf(yield(in[0], in[1]))}
|
||||
|
||||
@@ -410,3 +410,20 @@ func (methodIter2) Seq2(yield func(int, int) bool) {
|
||||
|
||||
// For Type.CanSeq2 test.
|
||||
func (methodIter2) NonSeq2(yield func(int, int)) {}
|
||||
|
||||
func TestSeqRetNamedBool(t *testing.T) {
|
||||
type Bool bool
|
||||
// Note: Type.Name() == "bool" is a incorrect check,
|
||||
// the named boolean type below will pass the incorrect check.
|
||||
type bool Bool
|
||||
v := ValueOf(func(func(int) bool) {})
|
||||
if v.Type().CanSeq() {
|
||||
t.Fatal("got true, want false")
|
||||
}
|
||||
shouldPanic("reflect: func(func(int) reflect_test.bool) cannot produce iter.Seq[Value]", func() { v.Seq() })
|
||||
v2 := ValueOf(func(func(int, int) bool) {})
|
||||
if v2.Type().CanSeq() {
|
||||
t.Fatal("got true, want false")
|
||||
}
|
||||
shouldPanic("func(func(int, int) reflect_test.bool) cannot produce iter.Seq2[Value, Value]", func() { v2.Seq2() })
|
||||
}
|
||||
|
||||
@@ -906,42 +906,26 @@ func (t *rtype) CanSeq() bool {
|
||||
case Int8, Int16, Int32, Int64, Int, Uint8, Uint16, Uint32, Uint64, Uint, Uintptr, Array, Slice, Chan, String, Map:
|
||||
return true
|
||||
case Func:
|
||||
return canRangeFunc(&t.t)
|
||||
return canRangeFunc(&t.t, 1)
|
||||
case Pointer:
|
||||
return t.Elem().Kind() == Array
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func canRangeFunc(t *abi.Type) bool {
|
||||
if t.Kind() != abi.Func {
|
||||
return false
|
||||
}
|
||||
f := t.FuncType()
|
||||
if f.InCount != 1 || f.OutCount != 0 {
|
||||
return false
|
||||
}
|
||||
y := f.In(0)
|
||||
if y.Kind() != abi.Func {
|
||||
return false
|
||||
}
|
||||
yield := y.FuncType()
|
||||
return yield.InCount == 1 && yield.OutCount == 1 && yield.Out(0).Kind() == abi.Bool
|
||||
}
|
||||
|
||||
func (t *rtype) CanSeq2() bool {
|
||||
switch t.Kind() {
|
||||
case Array, Slice, String, Map:
|
||||
return true
|
||||
case Func:
|
||||
return canRangeFunc2(&t.t)
|
||||
return canRangeFunc(&t.t, 2)
|
||||
case Pointer:
|
||||
return t.Elem().Kind() == Array
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func canRangeFunc2(t *abi.Type) bool {
|
||||
func canRangeFunc(t *abi.Type, seq uint16) bool {
|
||||
if t.Kind() != abi.Func {
|
||||
return false
|
||||
}
|
||||
@@ -954,7 +938,7 @@ func canRangeFunc2(t *abi.Type) bool {
|
||||
return false
|
||||
}
|
||||
yield := y.FuncType()
|
||||
return yield.InCount == 2 && yield.OutCount == 1 && yield.Out(0).Kind() == abi.Bool
|
||||
return yield.InCount == seq && yield.OutCount == 1 && yield.Out(0).Kind() == abi.Bool && toRType(yield.Out(0)).PkgPath() == ""
|
||||
}
|
||||
|
||||
func (t *rtype) Fields() iter.Seq[StructField] {
|
||||
|
||||
Reference in New Issue
Block a user