struct GamePiece: Equatable, ExpressibleByStringLiteral {
// empty struct - always equal to any other
init() { }
init(stringLiteral value: String) {
switch value {
case "king": self = .init()
case "queen": self = .init()
case "rook": self = .init()
default: self = .init()
}
}
}
enum ChessPiece: GamePiece, CaseIterable {
case king = "king"
// case king = GamePiece(stringLiteral: "king") // - error: raw value for enum case must be a literal
case queen = "queen"
// case rook = "queen" // - error: raw value for enum case is not unique
}
print(ChessPiece.king == ChessPiece.queen) // false
print(ChessPiece.king.rawValue == ChessPiece.queen.rawValue) // true
I wonder if that is kind of a bug or some work in the direction of using custom values with raw representable enums?
There are a few cases when compiler would allow duplicated raw values, a few examples:
enum Test1: Double {
case a = 0.0
case b = -0.0
}
enum Test2: Float {
case a = 0xCp127 // Warning: '0xCp127' overflows to inf during conversion to 'Float'
case b = 0xCp128 // Warning: '0xCp128' overflows to inf during conversion to 'Float'
}
enum Test3: String {
case a = "\u{00c5}" // Å precomposed form
case b = "A\u{030A}" // Å decomposed form
}
Duplicated raw values per se do not seem to cause major harm..
As for the user ExpressibleBy...Literal types used as enum raw types, probably compiler could do a better job checking if it can guarantee the uniqueness of raw values at compile time. For example if the type has a custom func == operator or a custom init(xxxLiteral:) initialiser – all bets are off.
However, if the restriction for uniqueness is not a problem, I wonder why is there restriction for values to be initialized from literals?
My first guess was - to guarantee static check and values uniqueness and further correct instantiation but probably it is not a problem and this limitation can be lifted.
Should a.rawValue == b.rawValue imply a == b. It certainly isn't enforced by the compiler, nor can it.
But I guess it could be considered a requirement in the same category as the Hashable/Equatable-relationship, ie. a non-enforced semantic requirement, spelled out by documentation, and assumed by all consumers.
Duplicated raw values constitute a semantically invalid conformance to RawRepresentable—i.e., user error. Compiler diagnostics of this and all semantic requirements are only ever best-effort and (for obvious reasons) cannot encompass custom types. If a type violates the semantic invariants of a protocol, then all expectations as to the behaviors guaranteed by that protocol are out the window.