- Proposal: SE-0014
- Author: Max Moiseev
- Review Manager: Doug Gregor
- Status: Implemented (Swift 2.2)
- Decision Notes: Rationale
- Bug: SR-474
In order to allow AnySequence
delegate calls to the underlying sequence,
its initializer should have extra constraints.
At the moment AnySequence
does not delegate calls to SequenceType
protocol
methods to the underlying base sequence, which results in dynamic downcasts in
places where this behavior is needed (see default implementations of
SequenceType.dropFirst
or SequenceType.prefix
). Besides, and this is even
more important, customized implementations of SequenceType
methods would be
ignored without delegation.
See the implementation in this PR.
In order for this kind of delegation to become possible, _SequenceBox
needs to
be able to 'wrap' not only the base sequence but also its associated
SubSequence
. So instead of being declared like this:
internal class _SequenceBox<S : SequenceType>
: _AnySequenceBox<S.Generator.Element> { ... }
it would become this:
internal class _SequenceBox<
S : SequenceType
where
S.SubSequence : SequenceType,
S.SubSequence.Generator.Element == S.Generator.Element,
S.SubSequence.SubSequence == S.SubSequence
> : _AnySequenceBox<S.Generator.Element> { ... }
Which, in its turn, will lead to AnySequence.init
getting a new set of
constraints as follows.
Before the change:
public struct AnySequence<Element> : SequenceType {
public init<
S: SequenceType
where
S.Generator.Element == Element
>(_ base: S) { ... }
}
After the change:
public struct AnySequence<Element> : SequenceType {
public init<
S: SequenceType
where
S.Generator.Element == Element,
S.SubSequence : SequenceType,
S.SubSequence.Generator.Element == Element,
S.SubSequence.SubSequence == S.SubSequence
>(_ base: S) { ... }
}
These constraints, in fact, should be applied to SequenceType
protocol itself
(although, that is not currently possible), as we expect every SequenceType
implementation to satisfy them already. Worth mentioning that technically
S.SubSequence.SubSequence == S.SubSequence
does not have to be this strict,
as any sequence with the same element type would do, but that is currently not
representable.
New constraints do not affect any built-in types that conform to
SequenceType
protocol as they are essentially constructed like this
(SubSequence.SubSequence == SubSequence
). 3rd party collections, if they use
the default SubSequence
(i.e. Slice
), should also be fine. Those having
custom SubSequence
s may stop conforming to the protocol.