Conforming a Wrapper Type to an ExpressibleBy Protocol

Let's say I have a very simple wrapper type called Wrapper:

struct Wrapper<T> {
    var value: T
}

I have the default initializer for it, but I would like some convenience when working with literal values, so I conform it to an ExpressibleBy protocol:

extension Wrapper: ExpressibleByBooleanLiteral where T: ExpressibleByBooleanLiteral {
    init(booleanLiteral value: T.BooleanLiteralType) {
        self = Wrapper(value: T(booleanLiteral: value))
    }
}

Now if I have a property of type Wrapper<Bool>, I can assign it with a boolean literal:

let wrapped: Wrapper<Bool> = true

For some reason though, if T is optional, I get a compiler error:

let wrapped: Wrapper<Bool?> = true
// cannot convert value of type 'Bool' to specified type 'Wrapper<Bool?>'

I thought this would work. Optional conforms to ExpressibleByBooleanLiteral if it's Wrapped sub-type does also. So is this a known language limitation or a compiler bug?

Bool? doesn't conform to ExpressibleByBooleanLiteral, so neither does Wrapper<Bool?>. The reason

let x: Bool? = true

still compiles is that true gets the type Bool, which is then turned into Bool? using implicit optional promotion (the same mechanism that lets you pass a T to a function that takes a T?). This behavior is specific to optionals and doesn't let you to implicitly promote Wrapper<T> values to Wrapper<T?>.

1 Like

I could have sworn I tried conforming Optional before and got a redundant conformance error. Anyway, adding the conformance fixed it. Thanks!

1 Like