Why doesn’t an `init` in an extension suppress the synthesized `init`?

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 init is 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?

1 Like

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.

1 Like

that’s exactly what i’m suggesting, the same rules should apply for both property access and synthesized inits

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.

1 Like

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.