Skip to content

Commit 8f80e40

Browse files
reflect: let Value.Seq iterated integer implementation conform to the spec
See CL 557596,According to the go specification, the iterated variable type should be the same as the iterated integer type. For #66056 Change-Id: I6a19cc211d081ebd8142c5a702601c8b49a6d736
1 parent 1259a30 commit 8f80e40

File tree

2 files changed

+57
-16
lines changed

2 files changed

+57
-16
lines changed

src/reflect/iter.go

+33-16
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,17 @@ package reflect
66

77
import "iter"
88

9+
func rangeNum[T int8 | int16 | int32 | int64 | int | uint8 | uint16 | uint32 | uint64 | uint | uintptr, N int64 | uint64](v N) iter.Seq[Value] {
10+
return func(yield func(v Value) bool) {
11+
// cannot use range T(v) because no core type.
12+
for i := T(0); i < T(v); i++ {
13+
if !yield(ValueOf(i)) {
14+
return
15+
}
16+
}
17+
}
18+
}
19+
920
// Seq returns an iter.Seq[Value] that loops over the elements of v.
1021
// If v's kind is Func, it must be a function that has no results and
1122
// that takes a single argument of type func(T) bool for some type T.
@@ -22,22 +33,28 @@ func (v Value) Seq() iter.Seq[Value] {
2233
}
2334
}
2435
switch v.Kind() {
25-
case Int, Int8, Int16, Int32, Int64:
26-
return func(yield func(Value) bool) {
27-
for i := range v.Int() {
28-
if !yield(ValueOf(i)) {
29-
return
30-
}
31-
}
32-
}
33-
case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
34-
return func(yield func(Value) bool) {
35-
for i := range v.Uint() {
36-
if !yield(ValueOf(i)) {
37-
return
38-
}
39-
}
40-
}
36+
case Int:
37+
return rangeNum[int](v.Int())
38+
case Int8:
39+
return rangeNum[int8](v.Int())
40+
case Int16:
41+
return rangeNum[int16](v.Int())
42+
case Int32:
43+
return rangeNum[int32](v.Int())
44+
case Int64:
45+
return rangeNum[int64](v.Int())
46+
case Uint:
47+
return rangeNum[uint](v.Uint())
48+
case Uint8:
49+
return rangeNum[uint8](v.Uint())
50+
case Uint16:
51+
return rangeNum[uint16](v.Uint())
52+
case Uint32:
53+
return rangeNum[uint32](v.Uint())
54+
case Uint64:
55+
return rangeNum[uint64](v.Uint())
56+
case Uintptr:
57+
return rangeNum[uintptr](v.Uint())
4158
case Pointer:
4259
if v.Elem().kind() != Array {
4360
break

src/reflect/iter_test.go

+24
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,18 @@ func TestValueSeq(t *testing.T) {
4040
t.Fatalf("should loop four times")
4141
}
4242
}},
43+
{"int8", ValueOf(int8(4)), func(t *testing.T, s iter.Seq[Value]) {
44+
i := int8(0)
45+
for v := range s {
46+
if v.Interface().(int8) != i {
47+
t.Fatalf("got %d, want %d", v.Int(), i)
48+
}
49+
i++
50+
}
51+
if i != 4 {
52+
t.Fatalf("should loop four times")
53+
}
54+
}},
4355
{"uint", ValueOf(uint64(4)), func(t *testing.T, s iter.Seq[Value]) {
4456
i := uint64(0)
4557
for v := range s {
@@ -52,6 +64,18 @@ func TestValueSeq(t *testing.T) {
5264
t.Fatalf("should loop four times")
5365
}
5466
}},
67+
{"uint8", ValueOf(uint8(4)), func(t *testing.T, s iter.Seq[Value]) {
68+
i := uint8(0)
69+
for v := range s {
70+
if v.Interface().(uint8) != i {
71+
t.Fatalf("got %d, want %d", v.Int(), i)
72+
}
73+
i++
74+
}
75+
if i != 4 {
76+
t.Fatalf("should loop four times")
77+
}
78+
}},
5579
{"*[4]int", ValueOf(&[4]int{1, 2, 3, 4}), func(t *testing.T, s iter.Seq[Value]) {
5680
i := int64(0)
5781
for v := range s {

0 commit comments

Comments
 (0)