Protocol inheritance with default implementation causing ambiguous candidates

I am working on a two-layer collection, e.g. an array of arrays of integers should also be a collection of integers. I have created a concrete struct JoinedCollection for this purpose, and would like to bridge existing code using such functionality. Problem is, existing code might use different representation for things like indices, so I decided to create two protocols, JoinedCollectionAdaptable, and JoinedBidirectionalCollectionAdaptable.

I have no idea of how to make this work so I just follow what the compiler errors and warnings suggest, and ended up with:

public protocol JoinedCollectionAdaptable: Collection where Element == Outer.Element.Element {
    associatedtype Outer where Outer: Collection, Outer.Element: Collection, Outer.Element.Index: Inhabitable

    var outer: Outer { get }
    func toJoinedIndex(_ index: Index) -> JoinedCollection<Outer>.Index
    func fromJoinedIndex(_ joinedIndex: JoinedCollection<Outer>.Index) -> Index
}

public protocol JoinedBidirectionalCollectionAdaptable: JoinedCollectionAdaptable, BidirectionalCollection where Outer: BidirectionalCollection, Outer.Element: BidirectionalCollection {}

I then add some default implementation using those to/fromJoinedIndex to implement requirements of Collection, and BidirectionalCollection:

  • startIndex, endIndex, index(after:), distance(from:to:) for Collection;
  • index(before:) for BidirectionalCollection.

I also implemented things like count and index(_:offsetBy) for efficiency.

The problem is, when I actually trying to conform to JoinedBidirectionalCollectionAdaptable, the compiler complains:

/Swift.BidirectionalCollection:12:10: Multiple matching functions named 'distance(from:to:)' with type '(Document.CharacterView.Index, Document.CharacterView.Index) -> Int' (aka '(CharacterPosition, CharacterPosition) -> Int')

The compiler gives this error twice, one for Collection and one for BidirectionalError. For each, it gives four candidates exactly matching each other. What is even more peculiar is that when I copied my implementation for distance(from:to:) to JoinedBidirectionalCollectionAdaptable, those errors disappeared!

Could anybody help me understand what's going on? Huge thanks!

Terms of Service

Privacy Policy

Cookie Policy