In my code I want to assign Iterators of diferent types (but with Elements of the same type) to the same variable.

struct ChainedSequence<C1: Collection, C2: Collection>: Sequence 
  where C1.Element == C2.Element {
    var c1: C1
    var c2: C2

    func makeIterator() -> AnyIterator<C1.Element> {
        var iter = c1.makeIterator()  
        return AnyIterator<C1.Element> {
          if let el = iter.next() {
            return el
          } else {
            iter = c2.makeIterator() 
            return iter.next()
          }
          return nil
        }
    }
}

The compiler shows this error:

error: cannot assign value of type 'C2.Iterator' to type 'C1.Iterator'
            iter = c2.makeIterator() 
                   ~~~^~~~~~~~~~~~~~
                                     as! C1.Iterator

I tried to specify an opaque type for iter:

var iter: some IteratorProtocol = c1.makeIterator()

but then I get another error:

error: cannot convert return expression of type '(some IteratorProtocol).Element' to return type 'C1.Element?'

What should be the type of iter in order for this code to compile?

@wtedst thanks for your suggestion. Actually we started with exactly the same solution, but there are some issues with that:

  • after the first iterator gets exhausted, for each iteration of the second iterator we will still be calling next() on the first one
  • we've been thinking about making our class more general, supporting multiple collections, not only two.

All this brings the more general question: how to use multiple iterators uniformly? That's why I put such title on this topic.