Raw type 'Bool' is not expressible by any literal

Cœur picture Cœur · Feb 17, 2017 · Viewed 10k times · Source

I want to have my enums easily compatible with @IBInspectable, so for the sake of simplicity, I tried to have it representable with type Bool:

enum TopBarStyle: Bool {
    case darkOnLight
    case lightOnDark
}

But Xcode is giving me:

Raw type 'Bool' is not expressible by any literal

That's strange, as true and false seem to be perfect candidates for expressibility by literals.

I've also tried to add RawRepresentable conformance to type Bool with:

extension Bool: RawRepresentable {
    public init?(rawValue: Bool) {
        self = rawValue
    }
    public var rawValue: Bool {
        get { return self }
    }
}

But it didn't solve the error.

Answer

Cœur picture Cœur · Feb 17, 2017

Swift 3 natively defines those nine literal representations:

  • ExpressibleByNilLiteral (nil)
  • ExpressibleByBooleanLiteral (false)
  • ExpressibleByArrayLiteral ([])
  • ExpressibleByDictionaryLiteral ([:])
  • ExpressibleByIntegerLiteral (0)
  • ExpressibleByFloatLiteral (0.0)
  • ExpressibleByUnicodeScalarLiteral ("\u{0}")
  • ExpressibleByExtendedGraphemeClusterLiteral ("\u{0}")
  • ExpressibleByStringLiteral ("")

But enum raw representation will apparently only accept natively the subset of those representions that start with a digit (0-9), a sign (-, +) or a quote ("): the last five protocols of above list.

In my opinion, the error message should have been more specific. Maybe something explicit like that would have been nice:

Raw type 'Bool' is not expressible by any numeric or quoted-string literal

Extending Bool to conform to one of those protocols is still possible, for example:

extension Bool: ExpressibleByIntegerLiteral {
    public init(integerLiteral value: Int) {
        self = value != 0
    }
}

And after doing so, this code now builds fine:

enum TopBarStyle: Bool {
    case darkOnLight
    case lightOnDark
}

@IBInspectable var style = TopBarStyle(rawValue: false)!