What is the syntax for restricting a generic constraint to an associated type?

What is the correct syntax for indicating that a generic type should at least conform to an associated type?

protocol ListDescriptor {
  associatedtype ItemType: Hashable

  var items: [ItemType] { get }
}

struct SimpleList<ItemType>: ListDescriptor where ItemType == ListDescriptor.ItemType {
  var items: [ItemType] = []
}

Error:
Associated type 'ItemType' can only be used with a concrete type or generic parameter base

There might be several constraints on the protocol's associated type that need to be adhered to by the generic types in a class or struct. How do I effectively "bubble up" this information?

3 Likes

In my basic example, then explicitly setting Hashable is viable, but in an application I'm working on, there are several constraints that end up propagating several levels "deep". I could go through them all and annotate them appropriately, but then making a change because a pain because I have to go back through and find all the "broken" ones.

For example, SimpleList has a property for configuring layout which in term is also generic over ItemType while a property inside the layout property is also generic over `ItemType. That might leave me with:

  • SimpleList<ItemType>
    • GridLayout<ItemType>
      • SectionLayout<ItemType>
        • ItemLayout<ItemType>

I'm curious if there's a better way to constrain each ItemType to the ItemType of it's parent class or protocol. In this case, all the ItemType constraints should be the same.

The best I've come up with is to create yet another protocol and use that everywhere. Something like:

protocol ListableItem: Hashable {}

...and then to use ListableItem as a constraint everywhere I need it, but I was wondering what other options might exist.