aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorqiulaidongfeng <2645477756@qq.com>2026-02-14 18:47:17 +0800
committerRobert Griesemer <gri@google.com>2026-02-25 14:50:24 -0800
commit0ac9d84e3dd7eacc66b0bcc6bef86a90f4ec7714 (patch)
tree45572082fb9280a2d3f8875be6392690b76e6228 /src
parented0367718f3b17677c9112f259d27892b2b53424 (diff)
downloadgo-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.go4
-rw-r--r--src/reflect/iter_test.go17
-rw-r--r--src/reflect/type.go24
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] {