No-expansion attached macro

Currently there are specific sets of attached macros available providing some form of expansion and the usage of these macros are guarded by the expansion type these macros have declared.

However there are use-cases where macros are being used just to provide some metadata to another macro that generates declaration. For example my Codable macro in MetaCodable uses some macros attached to struct properties (CodedAt, CodedIn, Default etc.) to perform expansion producing Codable protocol implementations.

The limitations of using macros in such a way is that there is no macro role that defines such use case and using existing roles causes errors in certain scenarios:

Allowing to support such use-cases will be really helpful. These type of macros:

  • Can just confirm to AttachedMacro without any implementation.


  • Can confirm to AttachedMacro with an implementation that validates macro usage without returning any declaration.

    public AttachedMacro {
      /// Validate macro usage without performing any expansion.
      static func validation(
        of node: AttributeSyntax,
        attachedTo declaration: some DeclSyntaxProtocol,
        in context: some MacroExpansionContext
      ) async throws

This is something I did come up with! The following paragraph is extracted from something I wrote (but not publicized) this April for the GSoC proposal SwiftPM support for Swift scripts:

With the new SwiftSyntax and macro system, I feel like the preferable option is to introduce a new kind of macro that provides additional information for tooling without modifying the AST. We only define the macro interface and different build systems can provide different implementations for it. While this might be a viable solution, the new macro kind itself is a pretty big proposal that, with 99% probability, cannot land during the GSoC cycle.

To expand on the idea, I think users can be provided with a metadata macro API package (which only contains the interface), with which they can apply metadata macros to their codes. External tools like build system and IDE then invokes the Swift compiler with the real implementation to extract the metadata in a batch. In this way, external tools can provide metadata functionality while preserving user code compatibility without them.

1 Like