Why some type-erasure use _AnyTypeBoxBase/_AnyTypeBox classes, and some only use _AnyTypeBox?

For example, AnyIterator uses two classes to implement type-erasure: _AnyIteratorBoxBase (which implements the Iterator Protocol) and _AnyIteratorBox(which inherits from _AnyIteratorBoxBase)

A for example, AnySequence uses only _AnySequenceBox(which does not implement the Sequence Protocol, but simply repeats all its methods and properties, naming them with underscores.

Is there a reasonable explanation for this? Or is it an attempt to avoid some bug?

P.S. This question was prompted by a compiler bug that when trying to override the generic method inherited from the _AnyMyTypeBoxBase class inside the _AnyMyTypeBox class:

Declaration '...' cannot override more than one superclass declaration

In ExistentialCollection.swift as it exists today on master:

  • AnyIterator has a _box property of type _AnyIteratorBoxBase<Element>, which it initializes to some instance of _IteratorBox (a subclass of _AnyIteratorBoxBase).

  • AnySequence has a _box property of type _AnySequenceBox<Element>, which it initializes to some instance of _SequenceBox (a subclass of _AnySequenceBox).

So both type erasers use a two-class implementation, with an “abstract” base class and a “concrete” subclass. The base class names are inconsistent regarding the Base suffix.

I’m not sure why _AnyIteratorBox conforms to IteratorProtocol. If there’s a reason, it could be discovered by commenting out the conformance and compiling the standard library. But who has that kind of time...

I guess it could be because of Self requirements in the protocol?

I was just writing a type-eraser and found out that it can be impossible (well, at least I struggled) to make the base class conform to the protocol if the protocol has an initializer which takes Self as a parameter. The problem is in the box subclass where a different initializer is desired - but which then has to call the super class without anything useful for said parameter.