Extension on Collection and MutableCollection collide and are declared Redundant by Xcode

Viewed 175

I have a file in which I have 2 different extensions:

extension MutableCollection where Indices.Iterator.Element == Index { }
extension Collection where Indices.Iterator.Element == Index {}

In the mutable one, I only have extensions that are mutable ( makes sense! right? ) and in Collection I have extensions that are common to both classes.

Problem is I get this warning from Swift Compiler:

Redundant same-type constraint 'Self.Index' == 'Self.Indices.Iterator.Element'

What should I do to fix it?

1 Answers

The problem is not that your two extension collide, you would get the same warning with a single extension

extension Collection where Indices.Iterator.Element == Index { }

The short answer is: Just remove the redundant constraints from your declarations:

extension MutableCollection { ... }
extension Collection { ... }

Explanation: Swift 3 did not allow to constrain associated types. Even if Indices.Iterator.Element == Index was satisfied for all concrete collections (Array, ArraySlice, Set, ...), the language could not require it. That's why you had to add this constraint to your extension if you needed it.

Swift 4 now allows to constrain associated types with a where clause, see SE-0142 Permit where clauses to constrain associated types.

The Collection protocol defines

associatedtype Indices : Sequence = DefaultIndices<Self>
         where Self.Index == Self.Indices.Element, ...

and the Sequence protocol defines

associatedtype Element where Self.Element == Self.Iterator.Element

So we always have the identities

Indices.Iterator.Element == Indices.Element == Index

and therefore you can remove those constraints from your code.

Related