Macros with lazy var

Hi everyone,
I've been exploring Macros and was trying to create one that only returns a lazy var, using the following code:

public struct SubjectPublisherMacro: PeerMacro {

    public static func expansion(of node: AttributeSyntax,
                                 providingPeersOf declaration: some DeclSyntaxProtocol,
                                 in context: some MacroExpansionContext) throws -> [SwiftSyntax.DeclSyntax] {

        return [
            "lazy var state: AnyPublisher<String, Never> = { subject.eraseToAnyPublisher() }()"
        ]
    }
}

When applied to a Subject, like the following:

@SubjectPublisher
private var subject = PassthroughSubject<String, Never>()

If we expand the macro, the code generated is effectively:

lazy var state: AnyPublisher<String, Never> = {
    subject.eraseToAnyPublisher()
}()

However, when we compile, it gives an error, and we have the following Stack dump:


0.	Program arguments: /Applications/Xcode-15.2.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-frontend -frontend -c -primary-file /Users/xpto/macros/FFMacros/Sources/FFMacrosClient/main.swift -emit-dependencies-path /Users/xpto/Library/Developer/Xcode/DerivedData/FFMacros-byrxxptdunfedzeunapzrisyulor/Build/Intermediates.noindex/FFMacros.build/Debug/FFMacrosClient.build/Objects-normal/arm64/main.d -emit-const-values-path /Users/xpto/Library/Developer/Xcode/DerivedData/FFMacros-byrxxptdunfedzeunapzrisyulor/Build/Intermediates.noindex/FFMacros.build/Debug/FFMacrosClient.build/Objects-normal/arm64/main.swiftconstvalues -emit-reference-dependencies-path /Users/xpto/Library/Developer/Xcode/DerivedData/FFMacros-byrxxptdunfedzeunapzrisyulor/Build/Intermediates.noindex/FFMacros.build/Debug/FFMacrosClient.build/Objects-normal/arm64/main.swiftdeps -serialize-diagnostics-path /Users/xpto/Library/Developer/Xcode/DerivedData/FFMacros-byrxxptdunfedzeunapzrisyulor/Build/Intermediates.noindex/FFMacros.build/Debug/FFMacrosClient.build/Objects-normal/arm64/main.dia -target arm64-apple-macos10.15 -Xllvm -aarch64-use-tbi -enable-objc-interop -stack-check -sdk /Applications/Xcode-15.2.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk -I /Users/xpto/Library/Developer/Xcode/DerivedData/FFMacros-byrxxptdunfedzeunapzrisyulor/Build/Products/Debug -I /Applications/Xcode-15.2.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/lib -F /Users/xpto/Library/Developer/Xcode/DerivedData/FFMacros-byrxxptdunfedzeunapzrisyulor/Build/Products/Debug/PackageFrameworks -F /Users/xpto/Library/Developer/Xcode/DerivedData/FFMacros-byrxxptdunfedzeunapzrisyulor/Build/Products/Debug -F /Applications/Xcode-15.2.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks -no-color-diagnostics -enable-testing -g -module-cache-path /Users/xpto/Library/Developer/Xcode/DerivedData/ModuleCache.noindex -profile-generate -profile-coverage-mapping -swift-version 5 -enforce-exclusivity=checked -Onone -D SWIFT_PACKAGE -D DEBUG -D Xcode -serialize-debugging-options -load-plugin-executable /Users/xpto/Library/Developer/Xcode/DerivedData/FFMacros-byrxxptdunfedzeunapzrisyulor/Build/Products/Debug/FFMacrosMacros#FFMacrosMacros -package-name ffmacros -const-gather-protocols-file /Users/xpto/Library/Developer/Xcode/DerivedData/FFMacros-byrxxptdunfedzeunapzrisyulor/Build/Intermediates.noindex/FFMacros.build/Debug/FFMacrosClient.build/Objects-normal/arm64/FFMacrosClient_const_extract_protocols.json -empty-abi-descriptor -validate-clang-modules-once -clang-build-session-file /Users/xpto/Library/Developer/Xcode/DerivedData/ModuleCache.noindex/Session.modulevalidation -Xcc -working-directory -Xcc /Users/xpto/macros/FFMacros -resource-dir /Applications/Xcode-15.2.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift -enable-anonymous-context-mangled-names -Xcc -ivfsstatcache -Xcc /Users/xpto/Library/Developer/Xcode/DerivedData/SDKStatCaches.noindex/macosx14.2-23C53-ddea79c7890ab41bba4a63928c655a96.sdkstatcache -Xcc -I/Users/xpto/Library/Developer/Xcode/DerivedData/FFMacros-byrxxptdunfedzeunapzrisyulor/Build/Products/Debug/include -Xcc -I/Users/xpto/Library/Developer/Xcode/DerivedData/FFMacros-byrxxptdunfedzeunapzrisyulor/Build/Intermediates.noindex/FFMacros.build/Debug/FFMacrosClient.build/DerivedSources-normal/arm64 -Xcc -I/Users/xpto/Library/Developer/Xcode/DerivedData/FFMacros-byrxxptdunfedzeunapzrisyulor/Build/Intermediates.noindex/FFMacros.build/Debug/FFMacrosClient.build/DerivedSources/arm64 -Xcc -I/Users/xpto/Library/Developer/Xcode/DerivedData/FFMacros-byrxxptdunfedzeunapzrisyulor/Build/Intermediates.noindex/FFMacros.build/Debug/FFMacrosClient.build/DerivedSources -Xcc -DSWIFT_PACKAGE -Xcc -DDEBUG=1 -module-name FFMacrosClient -frontend-parseable-output -disable-clang-spi -target-sdk-version 14.2 -target-sdk-name macosx14.2 -external-plugin-path /Applications/Xcode-15.2.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk/usr/lib/swift/host/plugins#/Applications/Xcode-15.2.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk/usr/bin/swift-plugin-server -external-plugin-path /Applications/Xcode-15.2.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk/usr/local/lib/swift/host/plugins#/Applications/Xcode-15.2.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk/usr/bin/swift-plugin-server -external-plugin-path /Applications/Xcode-15.2.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/lib/swift/host/plugins#/Applications/Xcode-15.2.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/bin/swift-plugin-server -external-plugin-path /Applications/Xcode-15.2.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/local/lib/swift/host/plugins#/Applications/Xcode-15.2.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/bin/swift-plugin-server -plugin-path /Applications/Xcode-15.2.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/host/plugins -plugin-path /Applications/Xcode-15.2.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/local/lib/swift/host/plugins -o /Users/xpto/Library/Developer/Xcode/DerivedData/FFMacros-byrxxptdunfedzeunapzrisyulor/Build/Intermediates.noindex/FFMacros.build/Debug/FFMacrosClient.build/Objects-normal/arm64/main.o -index-unit-output-path /FFMacros.build/Debug/FFMacrosClient.build/Objects-normal/arm64/main.o -index-store-path /Users/xpto/Library/Developer/Xcode/DerivedData/FFMacros-byrxxptdunfedzeunapzrisyulor/Index.noindex/DataStore -index-system-modules
1.	Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5)
2.	Compiling with the current language version
3.	While evaluating request IRGenRequest(IR Generation for file "/Users/macros/FFMacros/Sources/FFMacrosClient/main.swift")
4.	While emitting IR SIL function "@$s14FFMacrosClient4TestC5state7Combine12AnyPublisherVySSs5NeverOGvg".
 for getter for state (at @__swiftmacro_14FFMacrosClient4TestC7subject33_32E41C858868D91DD4497E3BF955E2AFLL16SubjectPublisherfMp_.swift:1:10)
Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
0  swift-frontend           0x000000010728dabc llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1  swift-frontend           0x0000000109ef3cb0 llvm::sys::RunSignalHandlers() + 112
2  swift-frontend           0x0000000109c5d054 SignalHandler(int) + 352
3  libsystem_platform.dylib 0x0000000186829a24 _sigtramp + 56
4  swift-frontend           0x00000001098a52a4 swift::irgen::projectPhysicalClassMemberAddress(swift::irgen::IRGenFunction&, llvm::Value*, swift::SILType, swift::SILType, swift::VarDecl*, swift::GenericSignature) + 1036
5  swift-frontend           0x00000001098a52a4 swift::irgen::projectPhysicalClassMemberAddress(swift::irgen::IRGenFunction&, llvm::Value*, swift::SILType, swift::SILType, swift::VarDecl*, swift::GenericSignature) + 1036
6  swift-frontend           0x0000000106e90ee4 (anonymous namespace)::IRGenSILFunction::visitSILBasicBlock(swift::SILBasicBlock*) + 79544
7  swift-frontend           0x0000000109611fdc swift::irgen::IRGenModule::emitSILFunction(swift::SILFunction*) + 11680
8  swift-frontend           0x00000001072109c8 swift::irgen::IRGenerator::emitGlobalTopLevel(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>,
std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>> const&) + 2516
9  swift-frontend           0x00000001058b59d0 swift::IRGenRequest::evaluate(swift::Evaluator&, swift::IRGenDescriptor) const + 6532
10 swift-frontend           0x0000000105188adc swift::SimpleRequest<swift::IRGenRequest, swift::GeneratedModule (swift::IRGenDescriptor), (swift::RequestFlags)9>::evaluateRequest(swift::IRGenRequest const&, swift::Evaluator&) + 176
11 swift-frontend           0x0000000106b59f64 llvm::Expected<swift::IRGenRequest::OutputType> swift::Evaluator::getResultUncached<swift::IRGenRequest>(swift::IRGenRequest const&) + 1480
12 swift-frontend           0x0000000108e00fb8 swift::performIRGeneration(swift::FileUnit*, swift::IRGenOptions const&, swift::TBDGenOptions const&, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule>>, llvm::StringRef, swift::PrimarySpecificPaths const&, llvm::StringRef, llvm::GlobalVariable**) + 264
13 swift-frontend           0x00000001097cd99c generateIR(swift::IRGenOptions const&, swift::TBDGenOptions const&, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule>>, swift::PrimarySpecificPaths const&, llvm::StringRef, llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, llvm::GlobalVariable*&, llvm::ArrayRef<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>) + 156
14 swift-frontend           0x00000001097d56d4 performCompileStepsPostSILGen(swift::CompilerInstance&, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule>>, llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, swift::PrimarySpecificPaths const&, int&, swift::FrontendObserver*) + 1596
15 swift-frontend           0x00000001097d0a08 performCompile(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 1748
16 swift-frontend           0x00000001097d4854 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 4568
17 swift-frontend           0x000000010983bd44 swift::mainEntry(int, char const**) + 4408
18 dyld                     0x00000001864790e0 start + 2360
LLVM Profile Error: Failed to write file "default.profraw": Operation not permitted

If we modify our macro to return a computed var instead of a lazy var, we can compile successfully. However, our goal was to return the lazy var. Does anyone have an idea of what the issue might be?

Thanks for your help!

2 Likes

I see something similar, and generating lazy vars for dependency management is what I want to use SwiftMacros for the most. Backtrace on Xcode 16.1-beta1:

1.	Apple Swift version 6.0 (swiftlang-6.0.0.7.6 clang-1600.0.24.1)
2.	Compiling with effective version 5.10
3.	While evaluating request IRGenRequest(IR Generation for file "/Users/danielbeard/Dev/GenVarsSwiftMacro/Sources/GenVarsSwiftMacroClient/main.swift")
4.	While emitting IR SIL function "@$s23GenVarsSwiftMacroClient1AC12themeManager33_0E3B81B0FDC98D18539F28AD09635FF8LLAA05ThemeG4Type_pvg".
 for getter for themeManager (at @__swiftmacro_23GenVarsSwiftMacroClient1AC12Dependencies0aB0fMp_.swift:3:22)
Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
0  swift-frontend           0x0000000105f95194 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1  swift-frontend           0x0000000105f933e8 llvm::sys::RunSignalHandlers() + 112
2  swift-frontend           0x0000000105f95760 SignalHandler(int) + 292
3  libsystem_platform.dylib 0x000000018051e584 _sigtramp + 56
4  swift-frontend           0x00000001010275c4 swift::irgen::ElementLayout::project(swift::irgen::IRGenFunction&, swift::irgen::Address, std::__1::optional<swift::irgen::NonFixedOffsetsImpl*>, llvm::Twine const&) const + 816
5  swift-frontend           0x0000000100da0520 swift::irgen::projectPhysicalClassMemberAddress(swift::irgen::IRGenFunction&, llvm::Value*, swift::SILType, swift::SILType, swift::VarDecl*, swift::GenericSignature) + 1040
6  swift-frontend           0x0000000100f926dc (anonymous namespace)::IRGenSILFunction::visitSILBasicBlock(swift::SILBasicBlock*) + 49820
7  swift-frontend           0x0000000100f85124 (anonymous namespace)::IRGenSILFunction::emitSILFunction() + 13220
8  swift-frontend           0x0000000100f818dc swift::irgen::IRGenModule::emitSILFunction(swift::SILFunction*) + 2088
9  swift-frontend           0x0000000100dcd8b4 swift::irgen::IRGenerator::emitGlobalTopLevel(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>> const&) + 3364
10 swift-frontend           0x0000000100f39118 swift::IRGenRequest::evaluate(swift::Evaluator&, swift::IRGenDescriptor) const + 4700
11 swift-frontend           0x0000000100f80e28 swift::SimpleRequest<swift::IRGenRequest, swift::GeneratedModule (swift::IRGenDescriptor), (swift::RequestFlags)9>::evaluateRequest(swift::IRGenRequest const&, swift::Evaluator&) + 176
12 swift-frontend           0x0000000100f42010 swift::IRGenRequest::OutputType swift::Evaluator::getResultUncached<swift::IRGenRequest, swift::IRGenRequest::OutputType swift::evaluateOrFatal<swift::IRGenRequest>(swift::Evaluator&, swift::IRGenRequest)::'lambda'()>(swift::IRGenRequest const&, swift::IRGenRequest::OutputType swift::evaluateOrFatal<swift::IRGenRequest>(swift::Evaluator&, swift::IRGenRequest)::'lambda'()) + 784
13 swift-frontend           0x0000000100f3ba48 swift::performIRGeneration(swift::FileUnit*, swift::IRGenOptions const&, swift::TBDGenOptions const&, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule>>, llvm::StringRef, swift::PrimarySpecificPaths const&, llvm::StringRef, llvm::GlobalVariable**) + 180
14 swift-frontend           0x000000010094cd5c generateIR(swift::IRGenOptions const&, swift::TBDGenOptions const&, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule>>, swift::PrimarySpecificPaths const&, llvm::StringRef, llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, llvm::GlobalVariable*&, llvm::ArrayRef<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>) + 156
15 swift-frontend           0x0000000100948588 performCompileStepsPostSILGen(swift::CompilerInstance&, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule>>, llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, swift::PrimarySpecificPaths const&, int&, swift::FrontendObserver*) + 2176
16 swift-frontend           0x0000000100947474 swift::performCompileStepsPostSema(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 984
17 swift-frontend           0x000000010094a728 performCompile(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 1680
18 swift-frontend           0x0000000100949458 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 3572
19 swift-frontend           0x00000001008d050c swift::mainEntry(int, char const**) + 3680
20 dyld                     0x0000000180163154 start + 2476