How to define a protocol for Int-backed enums so that conforming enums' cases can be held in an array of the protocol type?

I'm trying to define a protocol that only Int-backed enums can conform to. The goal is for all cases of all conforming enums to be placed in a single [ParentEnumProtocol] array, but doing so produces the much-dreaded message:

Protocol can only be used as a generic constraint because it has Self or associated type requirements

The error message does not make much sense to me, however, because I'm already explicitly stating the RawValue type in the protocol definition. Here is my sample code:

protocol ParentEnumProtocol: RawRepresentable where RawValue == Int { }

enum ValuesForCountryA: Int, CaseIterable, ParentEnumProtocol {
  case condominium = 1
  case houseAndLot = 2
  case lotOnly = 3
  case apartment = 7
}

enum ValuesForCountryB: Int, CaseIterable, ParentEnumProtocol {
  case condominium = 4
  case bungalow = 5
  case manor = 6
  case lotOnly = 8
}

And this is the erroneous code (error is thrown in first line):

private let allCasesEver: [ParentEnumProtocol] = [
  ValuesForCountryA.allCases,
  ValuesForCountryB.allCases
].reduce(into: [ParentEnumProtocol]()) { aggregate, currentArray in
  aggregate.append(contentsOf: currentArray)
}.sorted(by: { $0.rawValue < $1.rawValue })

Additionally, even something as simple as typecasting an enum case in the following manner:

(ValuesForCountryA.condominium as ParentEnumProtocol).rawValue

Produces the following error message on top of the one above:

Member 'rawValue' cannot be used on value of protocol type 'ParentEnumProtocol'; use a generic constraint instead

Which, again, I find confusing because the RawValue type is already explicitly stated.

Would someone kindly shed light as to why this is happening, and is what I want to do possible with Swift right now? Thank you in advance.

See:

Full implementation of SE-0309 will solve this problem in the future. That is not yet done.

1 Like