fix(iter/tuples): support break iteration over Zip[By] seq (#757)

fix all https://pkg.go.dev/golang.org/x/tools/gopls/internal/analysis/yield
This commit is contained in:
d-enk
2026-01-07 23:31:02 +03:00
committed by GitHub
parent 37c07828c3
commit 27e2842ca8
4 changed files with 48 additions and 20 deletions
+18
View File
@@ -5,8 +5,26 @@ package it
import (
"iter"
"slices"
"testing"
"github.com/stretchr/testify/assert"
)
// assertSeqSupportBreak checks whether it is possible to break iteration over a [iter.Seq]
func assertSeqSupportBreak[T any](t *testing.T, seq iter.Seq[T]) iter.Seq[T] {
assert.NotPanics(t, func() {
for range seq {
break
}
for range seq {
return
}
})
return seq
}
func values[T any](v ...T) iter.Seq[T] { return slices.Values(v) }
type foo struct {
+2 -3
View File
@@ -31,9 +31,8 @@ func TestDrain(t *testing.T) {
var done bool
list := iter.Seq[int](func(yield func(int) bool) {
yield(1)
yield(2)
yield(3)
_ = yield(1) && yield(2) && yield(3)
done = true
})
+8 -16
View File
@@ -26,10 +26,9 @@ func Zip2[A, B any](a iter.Seq[A], b iter.Seq[B]) iter.Seq[lo.Tuple2[A, B]] {
var ok [2]bool
item.A, ok[0] = next.A()
item.B, ok[1] = next.B()
if ok == [2]bool{} {
if ok == [2]bool{} || !yield(item) {
return
}
yield(item)
}
}
}
@@ -55,10 +54,9 @@ func Zip3[A, B, C any](a iter.Seq[A], b iter.Seq[B], c iter.Seq[C]) iter.Seq[lo.
item.A, ok[0] = next.A()
item.B, ok[1] = next.B()
item.C, ok[2] = next.C()
if ok == [3]bool{} {
if ok == [3]bool{} || !yield(item) {
return
}
yield(item)
}
}
}
@@ -87,10 +85,9 @@ func Zip4[A, B, C, D any](a iter.Seq[A], b iter.Seq[B], c iter.Seq[C], d iter.Se
item.B, ok[1] = next.B()
item.C, ok[2] = next.C()
item.D, ok[3] = next.D()
if ok == [4]bool{} {
if ok == [4]bool{} || !yield(item) {
return
}
yield(item)
}
}
}
@@ -122,10 +119,9 @@ func Zip5[A, B, C, D, E any](a iter.Seq[A], b iter.Seq[B], c iter.Seq[C], d iter
item.C, ok[2] = next.C()
item.D, ok[3] = next.D()
item.E, ok[4] = next.E()
if ok == [5]bool{} {
if ok == [5]bool{} || !yield(item) {
return
}
yield(item)
}
}
}
@@ -160,10 +156,9 @@ func Zip6[A, B, C, D, E, F any](a iter.Seq[A], b iter.Seq[B], c iter.Seq[C], d i
item.D, ok[3] = next.D()
item.E, ok[4] = next.E()
item.F, ok[5] = next.F()
if ok == [6]bool{} {
if ok == [6]bool{} || !yield(item) {
return
}
yield(item)
}
}
}
@@ -201,10 +196,9 @@ func Zip7[A, B, C, D, E, F, G any](a iter.Seq[A], b iter.Seq[B], c iter.Seq[C],
item.E, ok[4] = next.E()
item.F, ok[5] = next.F()
item.G, ok[6] = next.G()
if ok == [7]bool{} {
if ok == [7]bool{} || !yield(item) {
return
}
yield(item)
}
}
}
@@ -245,10 +239,9 @@ func Zip8[A, B, C, D, E, F, G, H any](a iter.Seq[A], b iter.Seq[B], c iter.Seq[C
item.F, ok[5] = next.F()
item.G, ok[6] = next.G()
item.H, ok[7] = next.H()
if ok == [8]bool{} {
if ok == [8]bool{} || !yield(item) {
return
}
yield(item)
}
}
}
@@ -292,10 +285,9 @@ func Zip9[A, B, C, D, E, F, G, H, I any](a iter.Seq[A], b iter.Seq[B], c iter.Se
item.G, ok[6] = next.G()
item.H, ok[7] = next.H()
item.I, ok[8] = next.I()
if ok == [9]bool{} {
if ok == [9]bool{} || !yield(item) {
return
}
yield(item)
}
}
}
+20 -1
View File
@@ -6,8 +6,9 @@ import (
"slices"
"testing"
"github.com/samber/lo"
"github.com/stretchr/testify/assert"
"github.com/samber/lo"
)
func TestZip(t *testing.T) {
@@ -82,6 +83,15 @@ func TestZip(t *testing.T) {
values[int32](1, 2, 3, 4, 5, 6, 7, 8, 9),
)
assertSeqSupportBreak(t, r1)
assertSeqSupportBreak(t, r2)
assertSeqSupportBreak(t, r3)
assertSeqSupportBreak(t, r4)
assertSeqSupportBreak(t, r5)
assertSeqSupportBreak(t, r6)
assertSeqSupportBreak(t, r7)
assertSeqSupportBreak(t, r8)
is.Equal([]lo.Tuple2[string, int]{
{A: "a", B: 1},
{A: "b", B: 2},
@@ -231,6 +241,15 @@ func TestZipBy(t *testing.T) {
lo.T9[string, int, int, bool, float32, float64, int8, int16, int32],
)
assertSeqSupportBreak(t, r1)
assertSeqSupportBreak(t, r2)
assertSeqSupportBreak(t, r3)
assertSeqSupportBreak(t, r4)
assertSeqSupportBreak(t, r5)
assertSeqSupportBreak(t, r6)
assertSeqSupportBreak(t, r7)
assertSeqSupportBreak(t, r8)
is.Equal([]lo.Tuple2[string, int]{
{A: "a", B: 1},
{A: "b", B: 2},