Skip to content

Structs with deinit fail to compile when used from another file or module #66047

Closed
@TeamPuzel

Description

@TeamPuzel

Description
I tried implementing a basic server using move-only structs rather than classes, and it seems to be working. Unfortunately it's failing to compile if the Socket structs are moved to another file or a different module.

Output

[0/1] Planning build
Building for debugging...
error: compile command failed due to signal 6 (use -v to see invocation)
[1/3] Emitting module Server
Assertion failed: (deinit && "type has a deinit declared in AST but SIL deinit record is not present!"), function tryEmitDeinitCall, file GenType.cpp, line 2896.
Please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the crash backtrace.
Stack dump:
0.	Program arguments: /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2023-05-20-a.xctoolchain/usr/bin/swift-frontend -frontend -c -primary-file /Users/user/Projects/Swift/Server/src/Server/Server.swift -emit-dependencies-path /Users/user/Projects/Swift/Server/.build/arm64-apple-macosx/debug/Server.build/Server.d -emit-reference-dependencies-path /Users/user/Projects/Swift/Server/.build/arm64-apple-macosx/debug/Server.build/Server.swiftdeps -target arm64-apple-macosx13.0 -Xllvm -aarch64-use-tbi -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk -I /Users/user/Projects/Swift/Server/.build/arm64-apple-macosx/debug -I /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/lib -F /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks -enable-testing -g -module-cache-path /Users/user/Projects/Swift/Server/.build/arm64-apple-macosx/debug/ModuleCache -swift-version 5 -Onone -D SWIFT_PACKAGE -D DEBUG -new-driver-path /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2023-05-20-a.xctoolchain/usr/bin/swift-driver -entry-point-function-name Server_main -empty-abi-descriptor -plugin-path /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2023-05-20-a.xctoolchain/usr/lib/swift/host/plugins -plugin-path /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2023-05-20-a.xctoolchain/usr/local/lib/swift/host/plugins -resource-dir /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2023-05-20-a.xctoolchain/usr/lib/swift -enable-anonymous-context-mangled-names -Xcc -isysroot -Xcc /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk -Xcc -F -Xcc /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks -Xcc -fPIC -module-name Server -package-name server -target-sdk-version 13.3 -target-sdk-name macosx13.3 -parse-as-library -o /Users/user/Projects/Swift/Server/.build/arm64-apple-macosx/debug/Server.build/Server.swift.o -index-store-path /Users/user/Projects/Swift/Server/.build/arm64-apple-macosx/debug/index/store -index-system-modules
1.	Apple Swift version 5.9-dev (LLVM 3653146fb31d979, Swift 570c364cc4e6100)
2.	Compiling with the current language version
3.	While evaluating request IRGenRequest(IR Generation for file "/Users/user/Projects/Swift/Server/src/Server/Server.swift")
4.	While emitting IR SIL function "@$s6Server4MainO4mainyyKFZ".
 for 'main()' (at /Users/user/Projects/Swift/Server/src/Server/Server.swift:6:5)
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           0x00000001073a8a84 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1  swift-frontend           0x00000001073a7e28 llvm::sys::RunSignalHandlers() + 112
2  swift-frontend           0x00000001073a90c4 SignalHandler(int) + 304
3  libsystem_platform.dylib 0x0000000181d6aa24 _sigtramp + 56
4  libsystem_pthread.dylib  0x0000000181d3bc28 pthread_kill + 288
5  libsystem_c.dylib        0x0000000181c49ae8 abort + 180
6  libsystem_c.dylib        0x0000000181c48e44 err + 0
7  swift-frontend           0x0000000107441180 tryEmitDeinitCall(swift::irgen::IRGenFunction&, swift::SILType, llvm::function_ref<void (swift::irgen::Explosion&)>, llvm::function_ref<swift::irgen::Address ()>, llvm::function_ref<void ()>) (.cold.4) + 0
8  swift-frontend           0x0000000102b0c7f0 tryEmitDeinitCall(swift::irgen::IRGenFunction&, swift::SILType, llvm::function_ref<void (swift::irgen::Explosion&)>, llvm::function_ref<swift::irgen::Address ()>, llvm::function_ref<void ()>) + 1228
9  swift-frontend           0x0000000102b0c878 swift::irgen::tryEmitDestroyUsingDeinit(swift::irgen::IRGenFunction&, swift::irgen::Address, swift::SILType) + 80
10 swift-frontend           0x0000000102af079c (anonymous namespace)::StructTypeInfoBase<(anonymous namespace)::LoadableStructTypeInfo, swift::irgen::LoadableTypeInfo, (anonymous namespace)::StructFieldInfo>::destroy(swift::irgen::IRGenFunction&, swift::irgen::Address, swift::SILType, bool) const + 76
11 swift-frontend           0x0000000102b7ac74 swift::SILInstructionVisitor<(anonymous namespace)::IRGenSILFunction, void>::visit(swift::SILInstruction*) + 20444
12 swift-frontend           0x0000000102b71400 (anonymous namespace)::IRGenSILFunction::emitSILFunction() + 7436
13 swift-frontend           0x0000000102b6f194 swift::irgen::IRGenModule::emitSILFunction(swift::SILFunction*) + 948
14 swift-frontend           0x0000000102a1b6c0 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&) + 684
15 swift-frontend           0x0000000102b20e04 swift::IRGenRequest::evaluate(swift::Evaluator&, swift::IRGenDescriptor) const + 1620
16 swift-frontend           0x0000000102b6e8b8 swift::GeneratedModule swift::SimpleRequest<swift::IRGenRequest, swift::GeneratedModule (swift::IRGenDescriptor), (swift::RequestFlags)9>::callDerived<0ul>(swift::Evaluator&, std::__1::integer_sequence<unsigned long, 0ul>) const + 208
17 swift-frontend           0x0000000102b2f9b0 llvm::Expected<swift::IRGenRequest::OutputType> swift::Evaluator::getResultUncached<swift::IRGenRequest>(swift::IRGenRequest const&) + 364
18 swift-frontend           0x0000000102b22f34 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**) + 212
19 swift-frontend           0x00000001027022d0 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*) + 1664
20 swift-frontend           0x0000000102701684 swift::performCompileStepsPostSema(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 568
21 swift-frontend           0x0000000102710798 withSemanticAnalysis(swift::CompilerInstance&, swift::FrontendObserver*, llvm::function_ref<bool (swift::CompilerInstance&)>, bool) + 160
22 swift-frontend           0x00000001027040d0 performCompile(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 620
23 swift-frontend           0x00000001027030dc swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 2428
24 swift-frontend           0x00000001025563a4 swift::mainEntry(int, char const**) + 2144
25 dyld                     0x00000001819e3f28 start + 2236

Code
Main:

import Net

func main() throws {
    let server = try ServerSocket(port: 3000).intoListening()
    let client = try server.accept()
    try print(client.read(count: 3000))
}

Module:

import Darwin

public typealias Port = UInt16
public typealias Descriptor = CInt

var unixErr: String { String(cString: strerror(errno)) }

struct Address {
    let a, b, c, d: UInt8
    
    var value: UInt32 {
        unsafeBitCast(self, to: UInt32.self)
    }
    
    init(_ a: UInt8, _ b: UInt8, _ c: UInt8, _ d: UInt8) {
        self.a = a; self.b = b; self.c = c; self.d = d
    }
    
    static let localhost = Self(127, 0, 0, 1)
    static let zero      = Self(0, 0, 0, 0)
}

public struct ServerSocket: ~Copyable {
    private let descriptor: Descriptor
    private let address: sockaddr
    
    public init(port: Port) throws {
        self.descriptor = socket(PF_INET, SOCK_STREAM, 0)
        guard self.descriptor != -1 else {
            throw Error.couldNotCreateSocket(unixErr)
        }
        
        self.address = unsafeBitCast(sockaddr_in(
            sin_len: 0, 
            sin_family: UInt8(AF_INET),
            sin_port: port.bigEndian, 
            sin_addr: in_addr(s_addr: Address.localhost.value), 
            sin_zero: (0, 0, 0, 0, 0, 0, 0, 0)
        ), to: sockaddr.self)
        
        guard withUnsafePointer(to: self.address, { ptr in 
            bind(self.descriptor, ptr, UInt32(MemoryLayout<sockaddr>.stride))
        }) != -1 else {
            throw Error.couldNotBindSocket(unixErr)
        }
    }
    
    deinit {
        close(self.descriptor)
    }
    
    public enum Error: Swift.Error {
        case couldNotCreateSocket(String)
        case couldNotBindSocket(String)
        case couldNotListenToSocket(String)
    }
    
    public consuming func intoListening(maxQueue: Int32 = 10) throws -> ListeningSocket {
        guard listen(self.descriptor, maxQueue) != -1 else {
            throw Error.couldNotListenToSocket(unixErr)
        }
        
        let descriptor = self.descriptor
        let address    = self.address
        discard self
        
        return ListeningSocket(descriptor: descriptor, address: address)
    }
}

public struct ListeningSocket: ~Copyable {
    private let descriptor: Descriptor
    private let address: sockaddr
    
    fileprivate init(descriptor: Descriptor, address: sockaddr) {
        self.descriptor = descriptor
        self.address = address
    }
    
    deinit {
        close(self.descriptor)
    }
    
    public func accept() throws -> ReadWriteSocket {
        var len  = UInt32(MemoryLayout<sockaddr>.stride)
        var addr = self.address
        let rw   = Darwin.accept(self.descriptor, &addr, &len)
        guard rw != -1 else { throw Error.couldNotAcceptSocket(unixErr) }
        return ReadWriteSocket(descriptor: rw, address: addr)
    }
    
    public enum Error: Swift.Error {
        case couldNotAcceptSocket(String)
    }
}

public struct ReadWriteSocket: ~Copyable {
    private let descriptor: Descriptor
    private let address: sockaddr
    
    fileprivate init(descriptor: Descriptor, address: sockaddr) {
        self.descriptor = descriptor
        self.address = address
    }
    
    deinit {
        close(self.descriptor)
    }
    
    public func read(count: Int) throws -> String {
        try withUnsafeTemporaryAllocation(of: UInt8.self, capacity: count) { buf in
            guard Darwin.read(self.descriptor, buf.baseAddress, count) != -1 else {
                throw Error.couldNotReadFromSocket(unixErr)
            }
            return String(cString: buf.baseAddress!)
        }
    }
    
    public func write(str: String) {
        fatalError("TODO!")
    }
    
    public enum Error: Swift.Error {
        case couldNotReadFromSocket(String)
    }
}

Environment

Apple Swift version 5.9-dev (LLVM 3653146fb31d979, Swift 570c364cc4e6100)
Target: arm64-apple-macosx13.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    IRGenLLVM IR generationassertion failureBug → crash: An assertion failurebugA deviation from expected or documented behavior. Also: expected but undesirable behavior.compilerThe Swift compiler itselfcrashBug: A crash, i.e., an abnormal termination of softwaredeclarationsFeature: declarationsmove-onlyFeature → type declarations: Move-only type declarationsswift 5.9type declarationsFeature → declarations: Type declarations

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions