extracting from another thread. i believe this behaviour is broken and needs fixing:
struct S {
var a: Int
var b: Int?
var c: Int? = nil
}
let x = S(a: 0, b: nil, c: nil) // ok
let z = S(a: 0, b: nil) // ok
let y = S(a: 0, c: nil) // *** HHHMMM???
let w = S(a: 0) // *** HHHMMM???
this is because the synthesized memberwise initializer is generated as:
init(a: Int, b: Int? = nil, c: Int? = nil)
i believe this is a mistake and it should be generated as:
init(a: Int, b: Int?, c: Int? = nil)
note that initializer is generated correctly with the full Optional form:
struct S {
var a: Int
var b: Optional<Int>
var c: Optional<Int> = nil
}
in order to "opt out" of argument default value i need to change Int? to Optional - and that's not obvious at all, as the Int? feels just a short hand syntax for Optional (same way as [Int:Int] is a short hand syntax to Dictionary<Int, Int>)
please note, to keep the scope of this issue minimal i suggest to keep this issue distinct and separate to the infamous "Pre-pitch: remove the implicit initialization of Optional variables" et al. this is to only "fix one thing at a time", especially given that the other thing might not be broken. so, "var b: Int?" is still treated as if it was written "var b: Int? = nil" for all other intents and purposes, just when it comes to memberwise initializer the following two will be errors:
let y = S(a: 0, c: nil) // error: value for b is missing
let w = S(a: 0) // error: value for b is missing
and the actual initializer generated would be:
init(a: Int, b: Int?, c: Int? = nil)
this is a breaking change, will need a fix-it.