Skip to content

Apparent miscompilation with iterators of seqs #16417

@LordAro

Description

@LordAro

Not quite sure how to explain this one. Unless I've massively misunderstood iterators, an iterator that returns a sequence appears to be iterated over inconsistently. The original example this was reduced from appeared to show no iteration, rather than more than expected (which this shows). I imagine whatever it is is the same cause.

Example

# Just taken straight out of sequtils
proc all(s: openArray[int], pred: proc(x: int): bool): bool =
  for i in s:
    if not pred(i):
      return false
  return true

proc f(t: seq[bool]): seq[bool] =
  result = t

# Commenting out either of the values in the iterator results in the correct answer
iterator getMatrixVariants(t: seq[bool]): seq[bool] =
  for v in [t, f(t)]:
    yield v

# Identical, except unrolled
iterator getMatrixVariantsBroken(t: seq[bool]): seq[bool] =
  yield t
  yield f(t)

let matrix = @[true, true, false, true]

var countGood = 0
for v in getMatrixVariants(matrix):
  for b in v:
    if [0].all(proc(d: int): bool = b):
      inc countGood

var countBad = 0
for v in getMatrixVariantsBroken(matrix):
  for b in v:
    if [0].all(proc(d: int): bool = b):
      inc countBad

echo countGood, " ", countBad # 6, 7 ???

Current Output

nim 1.4.2

6 7

Not a clue where it manages to get 7 from

Expected Output

6 6

Possible Solution

???

Additional Information

Removing either of the statements from the iterators appears to make it return the right value.
all appears to be necessary, replacing it with if b: makes the example work as expected.
No additional compilation flags (nim r bug.nim)

Nim Compiler Version 1.4.2 [Linux: amd64]
Compiled at 2020-12-14
Copyright (c) 2006-2020 by Andreas Rumpf

active boot switches: -d:release -d:nativeStackTrace

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions