when i write types, i like to put the properties and simpler subscripts and nested types in the body of the main declaration, and the functions in an
extension. however this doesn’t really work well with the synthesized
inits, because if i implement my own
init in an extension, it conflicts with the automatic one.
invalid redeclaration of synthesized memberwise 'init'...
but if i take it out, the synthesized
private due to some of the stored properties being
private, so this turns into an access control error.
error: '...' initializer is inaccessible due to 'private' protection level
why can’t the initializer in the extension just disable the
private synthesized initializer?
So that an extension 1000 lines into a file doesn't affect the existence or non-existence of a synthesized initializer in potentially a different file? Not permitting such effects helps humans reading the code reason about what's going on, which is quite reasonable given that the whole point of this synthesized initializer feature is to help humans writing the code.
but extensions in the same file can access
private properties, surely that argument applies to that too, but it’s still allowed
If you're suggesting that same-file private initializers should be able to suppress a synthesized default memberwise private initializer, I think I could get behind that.
that’s exactly what i’m suggesting, the same rules should apply for both property access and synthesized
I think I could get behind this, but only if we also had Explicit Memberwise Initializers so there isn’t a lot of boilerplate required to recover the synthesized initializer if it was actually desired in addition to the manually written initializer.
the synthesized initializer would have the exact same signature as the written one so i don’t think this is actually something we’d want
In your use case maybe, but if we were to change the rule to suppress the synthesized initializer I think the new rule would be to suppress it when any initializer is declared in the same file as the type. I don't think we would want complicated rules where some initializers suppress it and others don't.
In any case, I think this is a moot point for the foreseeable future. It would be a nontrivial breaking change. I don't see anything "actively harmful" which would motivate such a change. That said, I do hope we have a release in the future (maybe Swift 10) where we can make breaking changes to polish rough edges and remove cruft that has been accumulated.