Implied resultBuilder is lost through protocol conformance via ExtensionMacro

1 day ago 1
ARTICLE AD BOX

I'm pretty sure this one is impossible at the moment but I'll post hoping i'm wrong.

A simple protocol which uses a simple resultBuilder:

@resultBuilder public enum MyResultBuilder { public static func buildBlock ( _ components: String... ) -> [ String ] { components } } public protocol MyProtocol { @MyResultBuilder var strings: [ String ] { get } }

... Made into an ExtensionMacro ( ConformanceMacro deprecated : https://github.com/swiftlang/swift-evolution/blob/main/proposals/0402-extension-macros.md )

@attached( extension , conformances: MyProtocol ) public macro MyMacro ( ) = #externalMacro ( module: "MacroDefinitions" , type: "MyConformanceMacro" ) public struct MyConformanceMacro: ExtensionMacro { public static func expansion ( of node: SwiftSyntax.AttributeSyntax , attachedTo declaration: some SwiftSyntax.DeclGroupSyntax , providingExtensionsOf type: some SwiftSyntax.TypeSyntaxProtocol , conformingTo protocols: [ SwiftSyntax.TypeSyntax ] , in context: some SwiftSyntaxMacros.MacroExpansionContext ) throws -> [ SwiftSyntax.ExtensionDeclSyntax ] { let r: SwiftSyntax.ExtensionDeclSyntax = try .init ( "extension \(type): MyProtocol { }" ) return [ r ] } }

Detail

The strings variable is ment to be dynamically defined by the developer.

Problem

when @MyMacro is called, the expansion creates an extension conformance to MyProtocol , in which the predefined @MyResultBuilder is lost.

This results in an error.

Fixes

inline the Macro and define the strings variable inside of target object. // Macro is heavy, not feasible.

have the user manually prepend @MyResultBuilder to var strings: [ String ] // ehh

Question

How can I write a macro which implements a protocol conformance in which the implied @MyResultBuilder is not lost?

Goal

@MyMacro struct MyStruct { var strings: [ String ] { // no errors "one" "two" "three" } }

pic of error

Read Entire Article