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

[509] Add conformingTo parameter to MemberMacro.expansion function #2420

Merged

Commits on Jan 8, 2024

  1. [SE-0407] Add missingConformancesTo argument to MemberMacro expansion…

    … operation
    
    Stage in an entrypoint for member macros that allows them to learn
    about which conformances that they've asked about are "missing",
    meaning that they are not present on the type (ignoring those that
    would be generated by an extension macro). This information is
    equivalent to the information provided to extension macros, although
    the member macro itself cannot create the conformance.
    DougGregor authored and ahoppen committed Jan 8, 2024
    Configuration menu
    Copy the full SHA
    d295e6a View commit details
    Browse the repository at this point in the history
  2. Throw an error if types conforming to MemberMacro implement no `exp…

    …ansion` method
    
    When adding a new type that conforms to `MemberMacro`, no `expansion` function is required to be implemented. It’s necessary to do it this way because:
    
    - `expansion(of:providingMembersOf:in:)` needs to exist as a protocol requirement to keep Swift 5.9 macros that implement this method compiling
    - `expansion(of:providingMembersOf:in:)` needs to be defaulted so that macros implementing `expansion(of:providingMembersOf:conformingTo:in:)` don’t need to also provide an implementation for the legacy version that doesn’t have `conformingTo:`
    - `expansion(of:providingMembersOf:conformingTo:in:)` obviously needs to exist since it’s the new dedicated entry point
    - `expansion(of:providingMembersOf:conformingTo:in:)` needs to have a default implementation that calls `expansion(of:providingMembersOf:in:)` so that 5.9 macros continue to work
    - We can’t mark `expansion(of:providingMembersOf:in:)` as deprecated because it’s called by the default implementation of `expansion(of:providingMembersOf:conformingTo:in:)` and we want to keep swift-syntax building without warnings.
    
    At the moment, we provide default implementations for both `expansion` functions that call each other, which causes an infinite recursion, that makes it non-obvious to see what’s going wrong.
    
    With this change, the default implementation of the legacy `expansion(of:providingMembersOf:in:)` method throws an error saying that you need to implement either of the two expansion methods. That way you get the following behavior:
    - If you don’t implement either expansion function, the error gets thrown
    - If a macro implements the legacy `expansion(of:providingMembersOf:in:)` function, then it overrides the throwing version and the macro works.
    - If a macro implements the new `expansion(of:providingMembersOf:conformingTo:in:)` method, then the compiler calls into that method directly and the legacy `expansion(of:providingMembersOf:in:)` never gets invoked by the compiler.
    
    The only possible issue I can think of is if a library is calling `expansion(of:providingMembersOf:in:)` but the macro only implements `expansion(of:providingMembersOf:conformingTo:in:)`. In this case an error would get thrown where it currently isn’t. But since I don’t see any reason why anyone would be calling `expansion(of:providingMembersOf:in:)` directly, I think this is fine.
    ahoppen committed Jan 8, 2024
    Configuration menu
    Copy the full SHA
    d0a2288 View commit details
    Browse the repository at this point in the history