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?
timv
(Tim Vermeulen)
2
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