Behavior of calling `next()` after “end of sequence” in different Swift versions

The documentation of the next() method in the IteratorProtocol states that

[...] As soon as the sequence has run out of elements, all subsequent calls return nil.

Before Swift 3, the next() method in the GeneratorProtocol stated that

Requires: [...] no preceding call to self.next() has returned nil.
Specific implementations of this protocol are encouraged to respond to
violations of this requirement by calling preconditionFailure("...").

So apparently the “responsibility” changed in Swift 3:

  • Before Swift 3, the consumer of the generator had to ensure not to call
    next() again after nil was returned. The generator method itself could
    rely on that.

  • As of Swift 3, the consumer of the iterator can call next() as often as
    it likes. The iterator method must expect to be called again, even after it
    reported the end of the sequence.

Is this understanding correct?

1 Like

That sounds right to me

https://github.com/apple/swift/commit/020841d4ba2be7d92a376e959e386f5b121b4d0d#diff-b9ba8d4ad76ba94c1eeabc504d582b57

1 Like