I'm trying to write a protocol that conforms to the Collection Protocol, and it has an associatedType - Object and a property object.
protocol DDCDataSource: Collection
{
associatedtype Object
var object: Object {get set}
}
I want to add some default functionality for the case where Object also conforms to the Collection protocol, namely just directly return Object's implementation of these required Collection properties and functions. It seems like it all works except for Collection's requirement for a subscript.
Cannot subscript a value of type 'Self.Object' with an index of type 'Self.Object.Index'
extension DDCDataSource where Object: Collection
{
typealias Index = Object.Index
var startIndex: Object.Index {
get {
return object.startIndex
}
}
var endIndex: Object.Index {
get {
return object.endIndex
}
}
subscript(position: Object.Index) -> Element
{
return object[position]
}
func index(after i: Object.Index) -> Object.Index {
return object.index(after: i)
}
}

Short answer: Change the return type of the subscript method to
Object.Elementor add a type alias (in a similar way as you did for the
Indextype)That makes the code compile and run as expected.
Explanation: The
subscriptmethod ofCollectionis declared aswhere
Self.IndexandSelf.Elementare associated types of `Collection. With your codethe compiler infers
Self.Indexto beObject.Index, but there is no relation betweenSelf.ElementandObject.Element(which is returned byobject[position]). The error becomes more apparent if you add an explicit cast:Now the compiler complains
The correct solution is not the forced cast but to make the compiler know that
Self.ElementisObject.Element, by adding a type alias or by changing the return typeso that the compiler infers
DDCDataSource.Elementto beObject.Element.Full self-contained example: (Swift 4, Xcode 9 beta 6)
(Note that you can omit the
getkeyword for read-only computed properties.)