Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide an initializer at the requested access level or fail #10

Closed
gohanlon opened this issue Nov 17, 2023 · 1 comment · Fixed by #15
Closed

Provide an initializer at the requested access level or fail #10

gohanlon opened this issue Nov 17, 2023 · 1 comment · Fixed by #15
Assignees
Labels
enhancement New feature or request

Comments

@gohanlon
Copy link
Owner

gohanlon commented Nov 17, 2023

Continuing the theme of #7:

@MemberwiseInit has traditionally mirrored Swift's memberwise initializer, adapting to the access levels of struct properties. This adapting behavior is necessary for Swift's initializer, which operates without explicit developer intent.

However, when a developer annotates a struct with @MemberwiseInit(.public), their intention is clear: they expect a public initializer. If the struct includes a private property, MemberwiseInit, as it stands, provides a non-public initializer. This outcome, often discovered later and indirectly, is surprising.

@MemberwiseInit should instead fail immediately in such cases, offering immediate, actionable diagnostics. For example, suggesting the annotation of properties with @Init(.public) or recommending access level adjustments.

With this change:

  • MemberwiseInit better aligns with the explicit and intentional practices preferred in Swift.
  • Unburdened from the nuance and complexity of Swift's memberwise initializer, README will become considerably shorter.
  • Usage will become more obvious and incrementally learnable through experience applying the macro and responding to diagnostics—"reading the manual" becomes much less necessary.
  • MemberwiseInit is still safe by default.

While residing in a somewhat grey area, I consider this a non-breaking change:

  • It aligns with the logical use of MemberwiseInit: using @MemberwiseInit(.public) while intending a non-public initializer is unlikely to begin with. Furthermore, were your intent to add an internal or private initializer, you wouldn't have much reason to reach for MemberwiseInit over Swift's memberwise initializer.
  • Existing code using @MemberwiseInit(.public) but not requiring a public initializer likely indicates a mistake, which this change proactively corrects.
@gohanlon gohanlon added the bug Something isn't working label Nov 17, 2023
@gohanlon gohanlon self-assigned this Nov 17, 2023
@gohanlon gohanlon added enhancement New feature or request and removed bug Something isn't working labels Nov 17, 2023
@davdroman
Copy link
Contributor

Perfect! I think this is the right design philosophy to adopt 👌

gohanlon added a commit that referenced this issue Nov 22, 2023
`@MemberwiseInit` now creates initializers at the specified access level
or fails if it cannot do so. This change sharpens the safety and clarity
of the macro, providing developers with immediate and actionable
diagnostics when the desired initialization level cannot be met due to
access restrictions on properties.

Caveat: the diagnostics don't include fix-its (yet).

Developers can resolve errors by adjusting property access levels or by
configuring individual properties with `@Init` attributes to match the
desired initializer access level.

Resolves #10.
gohanlon added a commit that referenced this issue Nov 23, 2023
`@MemberwiseInit` now creates initializers at the specified access level
or fails if it cannot do so. This change sharpens the safety and clarity
of the macro, providing developers with immediate and actionable
diagnostics when the desired initialization level cannot be met due to
access restrictions on properties.

Caveat: the diagnostics don't include fix-its (yet).

Developers can resolve errors by adjusting property access levels or by
configuring individual properties with `@Init` attributes to match the
desired initializer access level.

Resolves #10.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants