swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.37k stars 10.34k forks source link

Compiler crash when adding `lazy var` via peer attached macro #74087

Open momo-youngg opened 3 months ago

momo-youngg commented 3 months ago

Description

After create a macro that adds the same name, the same type, and the same initialization value, an unknown compilation error occurs.

Because it is macro, declaring and implementing this macro does not cause compilation errors, but compilation errors occur in actual use.

It works without lazy keyword, so I think lazy makes problem.

Reproduction

This is a macro declaration.

@attached(peer, names: prefixed(_))
public macro AddPeer() = #externalMacro(module: "MacroStudyMacros", type: "AddPeerMacro")

This is a test case which is passed

    func testAddPeer() throws {
        #if canImport(MacroStudyMacros)
        assertMacroExpansion(
            #"""
            public class SomeClass {
                @AddPeer
                private var someVar: Int = 3
            }
            """#,
            expandedSource: #"""
            public class SomeClass {
                private var someVar: Int = 3

                lazy var _someVar: Int = {
                    return 3
                }()
            }
            """#,
            macros: testMacros
        )
        #else
        throw XCTSkip("macros are only supported when running tests for the host platform")
        #endif
    }

This is an implementation

public struct AddPeerMacro: PeerMacro {
    public static func expansion(
        of node: SwiftSyntax.AttributeSyntax,
        providingPeersOf declaration: some SwiftSyntax.DeclSyntaxProtocol,
        in context: some SwiftSyntaxMacros.MacroExpansionContext
    ) throws -> [SwiftSyntax.DeclSyntax] {
        if let bindings = declaration.as(VariableDeclSyntax.self)?.bindings.as(PatternBindingListSyntax.self) {
            if let propertyName = bindings
                .compactMap({ $0.as(PatternBindingSyntax.self) })
                .map({ $0.pattern })
                .compactMap({ $0.as(IdentifierPatternSyntax.self) })
                .map({ $0.identifier }).first {

                if let typeName = bindings
                    .compactMap({ $0.as(PatternBindingSyntax.self) })
                    .compactMap({ $0.typeAnnotation })
                    .compactMap({ $0.as(TypeAnnotationSyntax.self) })
                    .map({ $0.type })
                    .compactMap({ $0.as(IdentifierTypeSyntax.self) })
                    .map({ $0.name })
                    .first {

                    if let value = bindings.compactMap({ $0.initializer?.as(InitializerClauseSyntax.self) }).compactMap({ $0.value.as(IntegerLiteralExprSyntax.self) }).first {
                        let newDeclaration: DeclSyntax = """
                        lazy var _\(propertyName.trimmed): \(typeName.trimmed) = {
                            return \(raw: value)
                        }()
                        """
                        return [newDeclaration]

                    }

                }
            }
        }
        return []
    }
}

and this is a client code which causing compiler crash

public class TestClass {
    @AddPeer
    var testValue: Int = 3
}

Stack dump

Please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the crash backtrace.
Stack dump:
0.  Program arguments: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-frontend -frontend -c -primary-file /Users/momo/Documents/side/MacroStudy/Sources/MacroStudyClient/main.swift -emit-dependencies-path /Users/momo/Library/Developer/Xcode/DerivedData/MacroStudy-cgmmukrwlramcbehvszuogojmthr/Build/Intermediates.noindex/MacroStudy.build/Debug/MacroStudyClient.build/Objects-normal/arm64/main.d -emit-const-values-path /Users/momo/Library/Developer/Xcode/DerivedData/MacroStudy-cgmmukrwlramcbehvszuogojmthr/Build/Intermediates.noindex/MacroStudy.build/Debug/MacroStudyClient.build/Objects-normal/arm64/main.swiftconstvalues -emit-reference-dependencies-path /Users/momo/Library/Developer/Xcode/DerivedData/MacroStudy-cgmmukrwlramcbehvszuogojmthr/Build/Intermediates.noindex/MacroStudy.build/Debug/MacroStudyClient.build/Objects-normal/arm64/main.swiftdeps -serialize-diagnostics-path /Users/momo/Library/Developer/Xcode/DerivedData/MacroStudy-cgmmukrwlramcbehvszuogojmthr/Build/Intermediates.noindex/MacroStudy.build/Debug/MacroStudyClient.build/Objects-normal/arm64/main.dia -target arm64-apple-macos10.15 -Xllvm -aarch64-use-tbi -enable-objc-interop -stack-check -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.5.sdk -I /Users/momo/Library/Developer/Xcode/DerivedData/MacroStudy-cgmmukrwlramcbehvszuogojmthr/Build/Products/Debug -I /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/lib -F /Users/momo/Library/Developer/Xcode/DerivedData/MacroStudy-cgmmukrwlramcbehvszuogojmthr/Build/Products/Debug/PackageFrameworks -F /Users/momo/Library/Developer/Xcode/DerivedData/MacroStudy-cgmmukrwlramcbehvszuogojmthr/Build/Products/Debug -F /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks -no-color-diagnostics -enable-testing -g -module-cache-path /Users/momo/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/momo/Library/Developer/Xcode/DerivedData/MacroStudy-cgmmukrwlramcbehvszuogojmthr/Build/Products/Debug/MacroStudyMacros#MacroStudyMacros -package-name macrostudy -const-gather-protocols-file /Users/momo/Library/Developer/Xcode/DerivedData/MacroStudy-cgmmukrwlramcbehvszuogojmthr/Build/Intermediates.noindex/MacroStudy.build/Debug/MacroStudyClient.build/Objects-normal/arm64/MacroStudyClient_const_extract_protocols.json -empty-abi-descriptor -validate-clang-modules-once -clang-build-session-file /Users/momo/Library/Developer/Xcode/DerivedData/ModuleCache.noindex/Session.modulevalidation -Xcc -working-directory -Xcc /Users/momo/Documents/side/MacroStudy -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift -enable-anonymous-context-mangled-names -Xcc -ivfsstatcache -Xcc /Users/momo/Library/Developer/Xcode/DerivedData/SDKStatCaches.noindex/macosx14.5-23F73-7e3fd6dc4171e65dbd154ba8db3956d2.sdkstatcache -Xcc -I/Users/momo/Library/Developer/Xcode/DerivedData/MacroStudy-cgmmukrwlramcbehvszuogojmthr/Build/Products/Debug/include -Xcc -I/Users/momo/Library/Developer/Xcode/DerivedData/MacroStudy-cgmmukrwlramcbehvszuogojmthr/Build/Intermediates.noindex/MacroStudy.build/Debug/MacroStudyClient.build/DerivedSources-normal/arm64 -Xcc -I/Users/momo/Library/Developer/Xcode/DerivedData/MacroStudy-cgmmukrwlramcbehvszuogojmthr/Build/Intermediates.noindex/MacroStudy.build/Debug/MacroStudyClient.build/DerivedSources/arm64 -Xcc -I/Users/momo/Library/Developer/Xcode/DerivedData/MacroStudy-cgmmukrwlramcbehvszuogojmthr/Build/Intermediates.noindex/MacroStudy.build/Debug/MacroStudyClient.build/DerivedSources -Xcc -DSWIFT_PACKAGE -Xcc -DDEBUG=1 -module-name MacroStudyClient -frontend-parseable-output -disable-clang-spi -target-sdk-version 14.5 -target-sdk-name macosx14.5 -external-plugin-path /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.5.sdk/usr/lib/swift/host/plugins#/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.5.sdk/usr/bin/swift-plugin-server -external-plugin-path /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.5.sdk/usr/local/lib/swift/host/plugins#/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.5.sdk/usr/bin/swift-plugin-server -external-plugin-path /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/lib/swift/host/plugins#/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/bin/swift-plugin-server -external-plugin-path /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/local/lib/swift/host/plugins#/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/bin/swift-plugin-server -plugin-path /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/host/plugins -plugin-path /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/local/lib/swift/host/plugins -o /Users/momo/Library/Developer/Xcode/DerivedData/MacroStudy-cgmmukrwlramcbehvszuogojmthr/Build/Intermediates.noindex/MacroStudy.build/Debug/MacroStudyClient.build/Objects-normal/arm64/main.o -index-unit-output-path /MacroStudy.build/Debug/MacroStudyClient.build/Objects-normal/arm64/main.o -index-store-path /Users/momo/Library/Developer/Xcode/DerivedData/MacroStudy-cgmmukrwlramcbehvszuogojmthr/Index.noindex/DataStore -index-system-modules
1.  Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)
2.  Compiling with the current language version
3.  While evaluating request IRGenRequest(IR Generation for file "/Users/momo/Documents/side/MacroStudy/Sources/MacroStudyClient/main.swift")
4.  While emitting IR SIL function "@$s16MacroStudyClient9TestClassC10_testValueSivg".
 for getter for _testValue (at @__swiftmacro_16MacroStudyClient9TestClassC9testValue7AddPeerfMp_.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           0x0000000108517f3c llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1  swift-frontend           0x00000001085170f8 llvm::sys::RunSignalHandlers() + 112
2  swift-frontend           0x0000000108518544 SignalHandler(int) + 360
3  libsystem_platform.dylib 0x000000018bc07584 _sigtramp + 56
4  swift-frontend           0x000000010315f3c0 swift::irgen::projectPhysicalClassMemberAddress(swift::irgen::IRGenFunction&, llvm::Value*, swift::SILType, swift::SILType, swift::VarDecl*, swift::GenericSignature) + 1036
5  swift-frontend           0x000000010315f3c0 swift::irgen::projectPhysicalClassMemberAddress(swift::irgen::IRGenFunction&, llvm::Value*, swift::SILType, swift::SILType, swift::VarDecl*, swift::GenericSignature) + 1036
6  swift-frontend           0x000000010334b934 (anonymous namespace)::IRGenSILFunction::visitSILBasicBlock(swift::SILBasicBlock*) + 72500
7  swift-frontend           0x00000001033384fc swift::irgen::IRGenModule::emitSILFunction(swift::SILFunction*) + 11556
8  swift-frontend           0x000000010318c430 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&) + 2472
9  swift-frontend           0x00000001032eb940 swift::IRGenRequest::evaluate(swift::Evaluator&, swift::IRGenDescriptor) const + 4016
10 swift-frontend           0x000000010333554c swift::SimpleRequest<swift::IRGenRequest, swift::GeneratedModule (swift::IRGenDescriptor), (swift::RequestFlags)9>::evaluateRequest(swift::IRGenRequest const&, swift::Evaluator&) + 176
11 swift-frontend           0x00000001032f8264 llvm::Expected<swift::IRGenRequest::OutputType> swift::Evaluator::getResultUncached<swift::IRGenRequest>(swift::IRGenRequest const&) + 836
12 swift-frontend           0x00000001032ee438 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           0x0000000102e1c0b8 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           0x0000000102e16294 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*) + 1892
15 swift-frontend           0x0000000102e15444 swift::performCompileStepsPostSema(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 608
16 swift-frontend           0x0000000102e19694 performCompile(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 1448
17 swift-frontend           0x0000000102e176d0 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 4968
18 swift-frontend           0x0000000102da6e8c swift::mainEntry(int, char const**) + 2612
19 dyld                     0x000000018b84e0e0 start + 2360
LLVM Profile Error: Failed to write file "default.profraw": Operation not permitted

Expected behavior

No compiler crash

Environment

swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4) Target: x86_64-apple-macosx14.0

Additional information

No response

kevinrpb commented 2 days ago

I've also encountered this error when using Xcode 16 (swiftlang-6.0.0.9.10 clang-1600.0.26.2).

@hborla are there any other pointers to this? Any known workarounds? 😄 Thank you.

daniel-beard commented 1 day ago

@kevinrpb it looks like macros just don't work at all for lazy vars. Here's some other examples from the forums: https://forums.swift.org/t/macros-with-lazy-var/69747