diff options
| author | qiulaidongfeng <2645477756@qq.com> | 2026-02-14 18:47:17 +0800 |
|---|---|---|
| committer | Robert Griesemer <gri@google.com> | 2026-02-25 14:50:24 -0800 |
| commit | 0ac9d84e3dd7eacc66b0bcc6bef86a90f4ec7714 (patch) | |
| tree | 45572082fb9280a2d3f8875be6392690b76e6228 /src | |
| parent | ed0367718f3b17677c9112f259d27892b2b53424 (diff) | |
| download | go-0ac9d84e3dd7eacc66b0bcc6bef86a90f4ec7714.tar.xz | |
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>
Diffstat (limited to 'src')
| -rw-r--r-- | src/reflect/iter.go | 4 | ||||
| -rw-r--r-- | src/reflect/iter_test.go | 17 | ||||
| -rw-r--r-- | src/reflect/type.go | 24 |
3 files changed, 23 insertions, 22 deletions
diff --git a/src/reflect/iter.go b/src/reflect/iter.go index 03df87b178..b23c50a393 100644 --- a/src/reflect/iter.go +++ b/src/reflect/iter.go @@ -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]))} diff --git a/src/reflect/iter_test.go b/src/reflect/iter_test.go index 668d665280..164440f692 100644 --- a/src/reflect/iter_test.go +++ b/src/reflect/iter_test.go @@ -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() }) +} diff --git a/src/reflect/type.go b/src/reflect/type.go index cf22152ab2..c58bbaa26d 100644 --- a/src/reflect/type.go +++ b/src/reflect/type.go @@ -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] { |
