You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Throw an error if types conforming to MemberMacro implement no expansion 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.
0 commit comments