Description
Description
There is a SIL verification failure when attempting to build the following project in Release mode.
Much like this issue: #64642
it requires an internal Package to reproduce. If all the code is present in a single file, then the code will compile successfully.
The error message provided is:
SIL verification failed: stack dealloc with empty stack: !state.Stack.empty()
More details are shown below.
Steps to reproduce
This reproducer requires four files: two Package.swift files (one is for an internal package), and two regular Swift source files.
The directory tree looks like this:
./Package.swift
./Sources/InternalPackage/Package.swift
./Sources/InternalPackage/Sources/InternalPackage/U.swift
./Sources/ReproducerServer/A.swift
Listing for ./Package.swift
:
// swift-tools-version: 5.6
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "Reproducer",
platforms: [.macOS(.v12),],
products: [
.library(
name: "Reproducer",
targets: ["ReproducerServer"]
),
],
dependencies: [
.package(url: "https://github.com/vapor/jwt.git", "4.0.0" ..< "5.0.0"),
.package(url: "https://github.com/vapor/vapor.git", "4.0.0" ..< "5.0.0"),
.package(url: "https://github.com/vapor/leaf-kit.git", "1.0.0" ..< "2.0.0"),
.package(url: "https://github.com/vapor/leaf.git", "4.0.0" ..< "5.0.0"),
.package(url: "https://github.com/apple/swift-nio.git", "2.0.0" ..< "3.0.0"),
.package(url: "https://github.com/mczachurski/Swiftgger.git", "1.0.0" ..< "2.0.0"),
.package(name: "InternalPackage", path: "./Sources/InternalPackage"),
],
targets: [
.target(
name: "ReproducerServer",
dependencies: [
.product(name: "JWT", package: "jwt"),
.product(name: "Vapor", package: "vapor"),
.product(name: "InternalPackage", package: "InternalPackage"),
.product(name: "Leaf", package: "leaf"),
.product(name: "LeafKit", package: "leaf-kit"),
.product(name: "NIOCore", package: "swift-nio"),
.product(name: "Swiftgger", package: "Swiftgger"),
],
swiftSettings: [.unsafeFlags([], .when(platforms: [.macOS, .linux], configuration: .release))]
)
]
)
Listing for ./Sources/InternalPackage/Package.swift
:
// swift-tools-version: 5.6
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "InternalPackage",
platforms: [
.macOS(.v12),
.iOS(.v15),
],
products: [
.library(
name: "InternalPackage",
targets: ["InternalPackage"]
)
],
dependencies: [
.package(
url: "https://github.com/apple/swift-collections.git",
from: "1.0.3"
),
.package(url: "https://github.com/apple/swift-log.git", from: "1.4.2"),
.package(url: "https://github.com/vapor/fluent-kit.git", from: "1.13.1"),
.package(url: "https://github.com/vapor/async-kit.git", from: "1.14.0"),
.package(url: "https://github.com/vapor/sql-kit.git", from: "3.18.0"),
.package(url: "https://github.com/apple/swift-nio.git", from: "2.38.0"),
],
targets: [
.target(
name: "InternalPackage",
dependencies: [
.product(name: "Collections", package: "swift-collections"),
.product(name: "AsyncKit", package: "async-kit"),
.product(name: "SQLKit", package: "sql-kit"),
.product(name: "NIO", package: "swift-nio")
]
)
]
)
Listing for ./Sources/InternalPackage/Sources/InternalPackage/U.swift
:
import Collections; import Foundation; import NIO; import SQLKit; import AsyncKit
public class S {
public let e: EventLoopGroup; let d: any D
public init(d: any D, e: EventLoopGroup) {self.d = d; self.e = e}
public func w<T>(_ closure: @escaping ((S) -> EventLoopFuture<T>)) -> EventLoopFuture<T> {return self.e.next().makePromise(of: T.self).futureResult}
public func s() -> SQLDatabase {d.s()}
}
public protocol D {func s() -> SQLDatabase}
Listing for ./Sources/ReproducerServer/A.swift
:
import Foundation; import SQLKit; import NIO; import InternalPackage
public extension Q {
static var v: Q {
Q(
r: { u in
u.w { u in
let u = u.s()
return u.select().columns("*").from(T.v.A).all(decoding: b.A.self).tryFlatMap { h in try h.map {try u.insert(into: "s").model($0).run()}.flatten(on: MultiThreadedEventLoopGroup(numberOfThreads: 1).next())}
}
}
)
}
}
public enum T {enum v {static let A = "A"}}
protocol I {var ID: UUID { get }}
enum b {struct A: Codable, Hashable, I {let ID: UUID} }
public struct Q{public let r: (S) -> EventLoopFuture<Void>}
Expected behavior
The program should compile successfully.
Environment
- Swift compiler version info: Toolchains 2023-05-09a and 2023-05-31a exhibit this issue.
- Xcode version info: 14.2
- Deployment target: M1
Additional context
The full SIL-related error is as follows:
SIL verification failed: stack dealloc with empty stack: !state.Stack.empty()
Verifying instruction:
%21 = alloc_ref [stack] [tail_elems $b.A * %6 : $Builtin.Word] $_ContiguousArrayStorage<b.A> // users: %51, %50, %40, %92, %91, %81, %80, %39, %31, %22, %53, %94, %93, %52
-> dealloc_stack_ref %21 : $_ContiguousArrayStorage<b.A> // id: %94
In function:
// closure #1 in closure #1 in closure #1 in closure #1 in static Q.v.getter
sil private @$s16ReproducerServer1QV1vACvgZ7NIOCore15EventLoopFutureCyytG15InternalPackage1SCcfU_AhKcfU_AHSayAA1bO1AVGKcfU_AhOKXEfU_ : $@convention(thin) @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0, @in_guaranteed any SQLDatabase) -> (@out τ_0_1, @error any Error) for <b.A, EventLoopFuture<()>> {
[%0: noescape **, write v**]
[%1: read v**, copy v**]
[%2: read v**, copy v**]
[global: read,write,copy,destroy,allocate,deinit_barrier]
// %0 "$return_value" // user: %76
// %1 "$0" // users: %30, %3
// %2 "u" // users: %5, %4
bb0(%0 : $*EventLoopFuture<()>, %1 : $*b.A, %2 : @closureCapture $*any SQLDatabase):
debug_value %1 : $*b.A, let, name "$0", argno 1, implicit, expr op_deref // id: %3
debug_value %2 : $*any SQLDatabase, let, name "u", argno 3, expr op_deref // id: %4
%5 = open_existential_addr immutable_access %2 : $*any SQLDatabase to $*@opened("478FA0AE-01A2-11EE-86A3-FE6D09CC5DCC", any SQLDatabase) Self // users: %16, %16
%6 = integer_literal $Builtin.Word, 1 // user: %21
%7 = integer_literal $Builtin.Int64, 1 // user: %20
%8 = integer_literal $Builtin.Int64, 115 // user: %9
%9 = struct $UInt64 (%8 : $Builtin.Int64) // user: %12
%10 = integer_literal $Builtin.Int64, -2233785415175766016 // user: %11
%11 = value_to_bridge_object %10 : $Builtin.Int64 // user: %12
%12 = struct $_StringObject (%9 : $UInt64, %11 : $Builtin.BridgeObject) // user: %13
%13 = struct $_StringGuts (%12 : $_StringObject) // user: %14
%14 = struct $String (%13 : $_StringGuts) // user: %16
// function_ref SQLDatabase.insert(into:)
%15 = function_ref @$s6SQLKit11SQLDatabasePAAE6insert4intoAA16SQLInsertBuilderCSS_tF : $@convention(method) <τ_0_0 where τ_0_0 : SQLDatabase> (@guaranteed String, @in_guaranteed τ_0_0) -> @owned SQLInsertBuilder // user: %16
%16 = apply %15<@opened("478FA0AE-01A2-11EE-86A3-FE6D09CC5DCC", any SQLDatabase) Self>(%14, %5) : $@convention(method) <τ_0_0 where τ_0_0 : SQLDatabase> (@guaranteed String, @in_guaranteed τ_0_0) -> @owned SQLInsertBuilder // type-defs: %5; users: %95, %54, %37
%17 = enum $Optional<String>, #Optional.none!enumelt // user: %37
%18 = enum $SQLQueryEncoder.KeyEncodingStrategy, #SQLQueryEncoder.KeyEncodingStrategy.useDefaultKeys!enumelt // user: %37
%19 = enum $SQLQueryEncoder.NilEncodingStrategy, #SQLQueryEncoder.NilEncodingStrategy.`default`!enumelt // user: %37
%20 = struct $Int (%7 : $Builtin.Int64) // user: %25
%21 = alloc_ref [stack] [tail_elems $b.A * %6 : $Builtin.Word] $_ContiguousArrayStorage<b.A> // users: %51, %50, %40, %92, %91, %81, %80, %39, %31, %22, %53, %94, %93, %52
%22 = upcast %21 : $_ContiguousArrayStorage<b.A> to $__ContiguousArrayStorageBase // users: %29, %27
%23 = integer_literal $Builtin.Int64, 2 // user: %24
%24 = struct $UInt (%23 : $Builtin.Int64) // user: %25
%25 = struct $_SwiftArrayBodyStorage (%20 : $Int, %24 : $UInt) // user: %26
%26 = struct $_ArrayBody (%25 : $_SwiftArrayBodyStorage) // user: %28
%27 = ref_element_addr %22 : $__ContiguousArrayStorageBase, #__ContiguousArrayStorageBase.countAndCapacity // users: %83, %42, %28
store %26 to %27 : $*_ArrayBody // id: %28
%29 = ref_tail_addr %22 : $__ContiguousArrayStorageBase, $b.A // user: %30
copy_addr %1 to [init] %29 : $*b.A // id: %30
%31 = end_cow_mutation %21 : $_ContiguousArrayStorage<b.A> // user: %32
%32 = unchecked_ref_cast %31 : $_ContiguousArrayStorage<b.A> to $Builtin.BridgeObject // user: %33
%33 = struct $_BridgeStorage<__ContiguousArrayStorageBase> (%32 : $Builtin.BridgeObject) // user: %34
%34 = struct $_ArrayBuffer<b.A> (%33 : $_BridgeStorage<__ContiguousArrayStorageBase>) // user: %35
%35 = struct $Array<b.A> (%34 : $_ArrayBuffer<b.A>) // user: %37
// function_ref SQLInsertBuilder.models<A>(_:prefix:keyEncodingStrategy:nilEncodingStrategy:)
%36 = function_ref @$s6SQLKit16SQLInsertBuilderC6models_6prefix19keyEncodingStrategy03nilgH0ACXDSayxG_SSSgAA15SQLQueryEncoderV03KeygH0OAK03NilgH0OtKSERzlF : $@convention(method) <τ_0_0 where τ_0_0 : Encodable> (@guaranteed Array<τ_0_0>, @guaranteed Optional<String>, @guaranteed SQLQueryEncoder.KeyEncodingStrategy, SQLQueryEncoder.NilEncodingStrategy, @guaranteed SQLInsertBuilder) -> (@owned SQLInsertBuilder, @error any Error) // user: %37
try_apply %36<b.A>(%35, %17, %18, %19, %16) : $@convention(method) <τ_0_0 where τ_0_0 : Encodable> (@guaranteed Array<τ_0_0>, @guaranteed Optional<String>, @guaranteed SQLQueryEncoder.KeyEncodingStrategy, SQLQueryEncoder.NilEncodingStrategy, @guaranteed SQLInsertBuilder) -> (@owned SQLInsertBuilder, @error any Error), normal bb1, error bb2 // id: %37
// %38 // users: %74, %56, %62
bb1(%38 : $SQLInsertBuilder): // Preds: bb0
set_deallocating %21 : $_ContiguousArrayStorage<b.A> // id: %39
%40 = ref_tail_addr %21 : $_ContiguousArrayStorage<b.A>, $b.A // user: %41
%41 = address_to_pointer %40 : $*b.A to $Builtin.RawPointer // user: %49
%42 = struct_element_addr %27 : $*_ArrayBody, #_ArrayBody._storage // user: %43
%43 = struct_element_addr %42 : $*_SwiftArrayBodyStorage, #_SwiftArrayBodyStorage.count // user: %44
%44 = struct_element_addr %43 : $*Int, #Int._value // user: %45
%45 = load %44 : $*Builtin.Int64 // user: %46
%46 = builtin "assumeNonNegative_Int64"(%45 : $Builtin.Int64) : $Builtin.Int64 // user: %48
%47 = metatype $@thick b.A.Type // user: %49
%48 = builtin "truncOrBitCast_Int64_Word"(%46 : $Builtin.Int64) : $Builtin.Word // user: %49
%49 = builtin "destroyArray"<b.A>(%47 : $@thick b.A.Type, %41 : $Builtin.RawPointer, %48 : $Builtin.Word) : $()
fix_lifetime %21 : $_ContiguousArrayStorage<b.A> // id: %50
dealloc_ref %21 : $_ContiguousArrayStorage<b.A> // id: %51
dealloc_stack_ref %21 : $_ContiguousArrayStorage<b.A> // id: %52
dealloc_stack_ref %21 : $_ContiguousArrayStorage<b.A> // id: %53
strong_release %16 : $SQLInsertBuilder // id: %54
%55 = alloc_stack $any SQLDatabase // users: %75, %73, %60, %58
%56 = ref_element_addr %38 : $SQLInsertBuilder, #SQLInsertBuilder.database // user: %57
%57 = begin_access [read] [dynamic] [no_nested_conflict] %56 : $*any SQLDatabase // users: %59, %58
copy_addr %57 to [init] %55 : $*any SQLDatabase // id: %58
end_access %57 : $*any SQLDatabase // id: %59
%60 = open_existential_addr immutable_access %55 : $*any SQLDatabase to $*@opened("47A70E4C-01A2-11EE-86A3-FE6D09CC5DCC", any SQLDatabase) Self // users: %70, %70, %69
%61 = alloc_stack $any SQLExpression // users: %72, %71, %70, %64
%62 = ref_element_addr %38 : $SQLInsertBuilder, #SQLInsertBuilder.insert // user: %63
%63 = begin_access [read] [dynamic] [no_nested_conflict] %62 : $*SQLInsert // users: %66, %65
%64 = init_existential_addr %61 : $*any SQLExpression, $SQLInsert // user: %65
copy_addr %63 to [init] %64 : $*SQLInsert // id: %65
end_access %63 : $*SQLInsert // id: %66
// function_ref closure #1 in SQLQueryBuilder.run()
%67 = function_ref @$s6SQLKit15SQLQueryBuilderPAAE3run7NIOCore15EventLoopFutureCyytGyFyAA6SQLRow_pcfU_ : $@convention(thin) (@in_guaranteed any SQLRow) -> () // user: %68
%68 = thin_to_thick_function %67 : $@convention(thin) (@in_guaranteed any SQLRow) -> () to $@callee_guaranteed (@in_guaranteed any SQLRow) -> () // user: %70
%69 = witness_method $@opened("47A70E4C-01A2-11EE-86A3-FE6D09CC5DCC", any SQLDatabase) Self, #SQLDatabase.execute : <Self where Self : SQLKit.SQLDatabase> (Self) -> (any SQLKit.SQLExpression, @escaping (any SQLKit.SQLRow) -> ()) -> NIOCore.EventLoopFuture<()>, %60 : $*@opened("47A70E4C-01A2-11EE-86A3-FE6D09CC5DCC", any SQLDatabase) Self : $@convention(witness_method: SQLDatabase) <τ_0_0 where τ_0_0 : SQLDatabase> (@in_guaranteed any SQLExpression, @guaranteed @callee_guaranteed (@in_guaranteed any SQLRow) -> (), @in_guaranteed τ_0_0) -> @owned EventLoopFuture<()> // type-defs: %60; user: %70
%70 = apply %69<@opened("47A70E4C-01A2-11EE-86A3-FE6D09CC5DCC", any SQLDatabase) Self>(%61, %68, %60) : $@convention(witness_method: SQLDatabase) <τ_0_0 where τ_0_0 : SQLDatabase> (@in_guaranteed any SQLExpression, @guaranteed @callee_guaranteed (@in_guaranteed any SQLRow) -> (), @in_guaranteed τ_0_0) -> @owned EventLoopFuture<()> // type-defs: %60; user: %76
destroy_addr %61 : $*any SQLExpression // id: %71
dealloc_stack %61 : $*any SQLExpression // id: %72
destroy_addr %55 : $*any SQLDatabase // id: %73
strong_release %38 : $SQLInsertBuilder // id: %74
dealloc_stack %55 : $*any SQLDatabase // id: %75
store %70 to %0 : $*EventLoopFuture<()> // id: %76
%77 = tuple () // user: %78
return %77 : $() // id: %78
// %79 // user: %96
bb2(%79 : $any Error): // Preds: bb0
set_deallocating %21 : $_ContiguousArrayStorage<b.A> // id: %80
%81 = ref_tail_addr %21 : $_ContiguousArrayStorage<b.A>, $b.A // user: %82
%82 = address_to_pointer %81 : $*b.A to $Builtin.RawPointer // user: %90
%83 = struct_element_addr %27 : $*_ArrayBody, #_ArrayBody._storage // user: %84
%84 = struct_element_addr %83 : $*_SwiftArrayBodyStorage, #_SwiftArrayBodyStorage.count // user: %85
%85 = struct_element_addr %84 : $*Int, #Int._value // user: %86
%86 = load %85 : $*Builtin.Int64 // user: %87
%87 = builtin "assumeNonNegative_Int64"(%86 : $Builtin.Int64) : $Builtin.Int64 // user: %89
%88 = metatype $@thick b.A.Type // user: %90
%89 = builtin "truncOrBitCast_Int64_Word"(%87 : $Builtin.Int64) : $Builtin.Word // user: %90
%90 = builtin "destroyArray"<b.A>(%88 : $@thick b.A.Type, %82 : $Builtin.RawPointer, %89 : $Builtin.Word) : $()
fix_lifetime %21 : $_ContiguousArrayStorage<b.A> // id: %91
dealloc_ref %21 : $_ContiguousArrayStorage<b.A> // id: %92
dealloc_stack_ref %21 : $_ContiguousArrayStorage<b.A> // id: %93
dealloc_stack_ref %21 : $_ContiguousArrayStorage<b.A> // id: %94
strong_release %16 : $SQLInsertBuilder // id: %95
throw %79 : $any Error // id: %96
} // end sil function '$s16ReproducerServer1QV1vACvgZ7NIOCore15EventLoopFutureCyytG15InternalPackage1SCcfU_AhKcfU_AHSayAA1bO1AVGKcfU_AhOKXEfU_'
Stack trace:
1. Apple Swift version 5.9-dev (LLVM 5c02e17d873dc13, Swift 049c367900f9b51)
2. Compiling with the current language version
3. While verifying SIL function "@$s16ReproducerServer1QV1vACvgZ7NIOCore15EventLoopFutureCyytG15InternalPackage1SCcfU_AhKcfU_AHSayAA1bO1AVGKcfU_AhOKXEfU_".
for expression at [/Users/user/playground/64642/Sources/ReproducerServer/Auth.swift:8:116 - line:8:156] RangeText="{try u.insert(into: "s").model($0).run()"
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 0x0000000109098f44 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1 swift-frontend 0x00000001090982e8 llvm::sys::RunSignalHandlers() + 112
2 swift-frontend 0x0000000109099584 SignalHandler(int) + 304
3 libsystem_platform.dylib 0x000000018b2c2a84 _sigtramp + 56
4 libsystem_pthread.dylib 0x000000018b293c28 pthread_kill + 288
5 libsystem_c.dylib 0x000000018b1a1ae8 abort + 180
6 swift-frontend 0x0000000105161118 (anonymous namespace)::SILVerifier::_require(bool, llvm::Twine const&, std::__1::function<void ()> const&) + 1476
7 swift-frontend 0x00000001051628d0 (anonymous namespace)::SILVerifier::visitSILFunction(swift::SILFunction*) + 4440
8 swift-frontend 0x000000010515d6e0 swift::SILFunction::verify(swift::SILPassManager*, bool, bool, bool) const + 204
9 swift-frontend 0x00000001051605a4 swift::SILModule::verify(swift::SILPassManager*, bool, bool) const + 184
10 swift-frontend 0x00000001051604b4 swift::SILModule::verify(bool, bool) const + 88
11 swift-frontend 0x0000000104589678 swift::CompilerInstance::performSILProcessing(swift::SILModule*) + 616
12 swift-frontend 0x00000001043f77d4 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*) + 788
13 swift-frontend 0x00000001043f7118 swift::performCompileStepsPostSema(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 1116
14 swift-frontend 0x0000000104406018 withSemanticAnalysis(swift::CompilerInstance&, swift::FrontendObserver*, llvm::function_ref<bool (swift::CompilerInstance&)>, bool) + 160
15 swift-frontend 0x00000001043f9940 performCompile(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 620
16 swift-frontend 0x00000001043f894c swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 2428
17 swift-frontend 0x000000010425c1ac swift::mainEntry(int, char const**) + 2144
18 dyld 0x000000018af3bf28 start + 2236
Note that the above was built via Xcode.
If I attempt to perform a command-line build using swift build -c release
with the 2023-05-30a toolchain, I get a different error message:
Assertion failed: (CastInst::castIsValid(opc, C, Ty) && "Invalid constantexpr cast!"), function getCast, file Constants.cpp, line 1951.
when attempting to build files identical to, or in the same directory as:
Compiling NIOSSL ByteBufferBIO.swift
.
This will be reported as a separate issue.