I have a type conforming to both RawRepresentable
and CustomStringConvertible
, but something strange happens when I introduce the latter conformance โ apart from the expected init(rawValue:)
and init(stringLiteral:)
it seems to gain a non-failable init(_:String)
which calls init(stringLiteral:)
.
This even overrides any init
with anonymous argument defined explicitly for that type; but not if that init is called explicitly with S.init("bla")
as opposed to S("bla")
.
struct S: RawRepresentable {
var rawValue: String
init?(rawValue: String) {
guard rawValue.count > 3 else { return nil }
self.rawValue = rawValue
}
}
extension S {
init(_ value: String) {
self.rawValue = "Called from extra non-failable init with anonymous argument."
}
}
extension S: ExpressibleByStringLiteral {
init(stringLiteral value: RawValue.StringLiteralType) {
self.rawValue = .init(stringLiteral: value)
}
}
extension S: CustomStringConvertible {
var description: String { rawValue }
}
let tooShort = S(rawValue: "abc") // nil
let longEnough = S(rawValue: "abcdef") // "abcdef"
let fromStringLiteral: S = "abc123" // "abc123"
let what = S("What?") // "What?"
let extra = S.init("Hmm") // "Called from extra non-failable init with anonymous argument."
Where does this behaviour come from โ and why?