Is it expected that multiple levels of macro expansions should compile?

I’ve got a simple example with a macro that creates a swift-testing test.

public struct FuzzTestMacro: PeerMacro {
    public static func expansion(
        of node: AttributeSyntax,
        providingPeersOf declaration: some DeclSyntaxProtocol,
        in context: some MacroExpansionContext
    ) throws -> [DeclSyntax] {
        return [
            DeclSyntax(
                stringLiteral: """
                @Test
                func fuzzy() {
                    fatalError()
                }
                """
            )
        ]
    }
}
@FuzzTest
func fuzzTest(_ input: String, _ otherInput: Int) async throws {
    print()
}

If I copy the expansion into my editor, it compiles fine, but it looks like being part of a parent macro breaks the @Test macro by causing some sort of scoping issue.

Cannot find '$s23PropertyTestingKitTests5fuzzy4TestfMp_24generator51b5d19e81bfb5ffMu_' in scope
Cannot find '$s23PropertyTestingKitTests5fuzzy4TestfMp_23accessor51b5d19e81bfb5ffMu_' in scope

Is this an intentional restriction of macros or a bug with swift-testing? Do any workarounds exist?

This is a constraint of Swift macros, not Swift Testing specifically. Please file a GitHub issue against the Swift repository describing your use case and what's gone wrong, thanks!

(@Douglas_Gregor, would you be able to provide any guidance here?)

Done: Macros who's expansions contain macros do not compile in some cases · Issue #85469 · swiftlang/swift · GitHub

2 Likes