Workaround for SIGSEGV failures when using Iter[Natural]

This commit is contained in:
Tomasz Bekas 2024-06-27 11:51:20 +02:00
parent 11eaebfd77
commit 51c2a930e3
No known key found for this signature in database
GPG Key ID: 4854E04C98824959
3 changed files with 39 additions and 7 deletions

View File

@ -103,29 +103,33 @@ proc map*[T, U](iter: Iter[T], fn: Function[T, U]): Iter[U] =
)
proc mapFilter*[T, U](iter: Iter[T], mapPredicate: Function[T, Option[U]]): Iter[U] =
var nextUOrErr: Option[Result[U, ref CatchableError]]
var
hasNext = false
nextUOrErr: Result[U, ref CatchableError]
proc tryFetch(): void =
nextUOrErr = Result[U, ref CatchableError].none
hasNext = false
while not iter.finished:
try:
let t = iter.next()
if u =? mapPredicate(t):
nextUOrErr = some(success(u))
hasNext = true
nextUOrErr = success(u)
break
except CatchableError as err:
nextUOrErr = some(U.failure(err))
hasNext = true
nextUOrErr = U.failure(err)
proc genNext(): U {.raises: [CatchableError].} =
# at this point nextUOrErr should always be some(..)
without u =? nextUOrErr.unsafeGet, err:
# at this point hasNext is always true
without u =? nextUOrErr, err:
raise err
tryFetch()
return u
proc isFinished(): bool =
nextUOrErr.isNone
not hasNext
tryFetch()
Iter[U].new(genNext, isFinished)

View File

@ -158,3 +158,21 @@ asyncchecksuite "Test AsyncIter":
check:
collected == @["0", "1"]
iter2.finished
test "Should not crash with range type":
let
iter1 = AsyncIter[Natural].new(0.Natural..<5.Natural).delayBy(10.millis)
iter2 = await filter[Natural](iter1,
proc (i: Natural): Future[bool] {.async.} =
(i mod 2) == 1
)
var collected: seq[Natural]
for fut in iter2:
collected.add(await fut)
check:
collected == @[Natural 1, 3]
GC_fullCollect()

View File

@ -127,3 +127,13 @@ checksuite "Test Iter":
check:
collected == @["0", "1", "2"]
iter2.finished
test "Should not crash with range type":
let
iter = Iter.new(0.Natural..<5.Natural)
.filter((i: Natural) => (i mod 2) == 1)
check:
iter.toSeq() == @[Natural 1, 3]
GC_fullCollect()