Is there a blessed guide or documentation on "Optional Promotion"?
This "feature" seems to be a Swift only? I haven't used another language where I can pass T where T? is being required. I'd like to know more specifics about when this promotion can happen? How deep the chain can this happen? T??
This is the only thing I could find
This is so magical I think it is almost like everytime I say I can take an optional I am also saying I take a non optional as in func myFunc(_ thing: String? | String). In TS this would be something like function myFunc( thing: string | null)
Is there some form of a magical subtyping happening here? As in, is String a subtype of String? /? Is String?? a subtype of String??? /?
This may seem like I am trolling but I really want to have some sort of reference.
Yes, T is a subtype of Optional<T>. Therefore String?? is a subtype of String??? I'm not sure where the exact reference on this is, give me a few minutes to look it up.
EDIT: This was the best I could find, the built in subtyping support of Optional<T> should probably get an appendix in the Swift language guide or something.
Nice find but I guess those were "only vague notions." ;) I guess this is called "implicit promotion". Maybe @Ben_Cohen can update his 2014 article now that we is part of the core team. :)
I guess the teams was planning some work in this area.
As far as I know, there are two conversion rules in the type checker that are relevant to this question:
Rule 1: A type T1 is implicitly convertible to T2? if T1 is implicitly convertible to T2.
Examples:
let x = 2
let y: Int? = x // Int is implicitly convertible to Int?,
// because Int is implicitly convertible to itself.
let x = 2
let y: Int?? = x // Int is implicitly convertible to Int??,
// because Int is implicitly convertible to Int?,
// because Int is implicitly convertible to itself.
class B {}
class C: B {}
let c = C()
let b: B? = c // C is implicitly convertible to B?,
// because C is implicitly convertible to B,
// because a subclass is implicitly convertible to its base class.
Rule 2: A type T1? is implicitly convertible to T2? if T1 is implicitly convertible to T2.
Examples:
let x: Int? = 42
let y: Any? = x // Int? is implicitly convertible to Any?,
// because Int is implicitly convertible to Any,
// because any type is implicitly convertible to Any.
class B {}
class C: B {}
let c: C? = C()
let b: B? = c // C? is implicitly convertible to B?,
// because C is implicitly convertible to B,
// because a subclass is implicitly convertible to its base class.
I hope this helps. I don't know if there's an official reference of these implicit conversions somewhere, but I did list many of them in my master thesis (see chapter 6.6.14 Conversions on pages 118-120).