Description
Description
The compiler crashes when handling a protocol with an associated type that is recursively constrained to conform to itself. Specifically, the issue occurs in a setup where:
- A protocol
Foo
has an associated typeBar
constrained toFoo
. - An existential type
any Foo
is used as a parameter in a function. - A generic function
_crash<V: Foo>
within the aforementioned function attempts to returnsome Foo
using the associated type. - The function
_openExistential
is used to open the existential container, leading to the crash.
Reproduction
protocol Foo {
associatedtype Bar: Foo
var bar: Bar { get }
}
func crash(existential foo: any Foo) {
func _crash<V: Foo>(open foo: V) -> some Foo { foo.bar }
let bar = _openExistential(foo, do: _crash(open:)) // ← Crashes
}
It's almost possible to workaround the issue, by providing the following code, though it fails to compile as it still retains the existential type and not the underlying concrete.
protocol Foo {
associatedtype Bar: Foo
var bar: Bar { get }
}
func crash(existential foo: any Foo) -> some Foo {
func _crash<V: Foo>(open foo: V) -> some Foo { foo.bar }
return _crash(open: foo) // Type 'any Foo' cannot conform to 'Foo'
}
My naive thinking is that it should be possible given that the concrete type is available... though this is not the right place to raise this request:
protocol Foo {
associatedtype Bar: Foo
var bar: Bar { get }
}
struct Qux<A, B>: Foo {
var description: String
var bar: Qux<String, String> { Qux<String, String>(description: "bar") }
}
struct Erased {
let existential: any Foo
init<V: Foo>(_ view: V) {
existential = view
}
}
let erased = Erased(Qux<Bool, Bool>(description: "qux"))
func printing(existential foo: any Foo) {
func printing<F: Foo>(foo: F) {
Swift.print("🪟", String(describing: foo)) // 🪟 Qux<Bool, Bool>(description: "qux")
Swift.print("🪟", String(describing: foo.bar)) // 🪟 Qux<String, String>(description: "bar")
}
printing(foo: foo)
}
printing(existential: erased.existential)
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-15.1.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-frontend -frontend -c -primary-file /Users/oliveratkinson/Development/Page/Sources/Page/Page.swift -emit-dependencies-path /Users/oliveratkinson/Library/Developer/Xcode/DerivedData/Page-biekgzigjyhbfrfwypmsqcetysjd/Build/Intermediates.noindex/Page.build/Debug-iphonesimulator/Page.build/Objects-normal/arm64/Page.d -emit-const-values-path /Users/oliveratkinson/Library/Developer/Xcode/DerivedData/Page-biekgzigjyhbfrfwypmsqcetysjd/Build/Intermediates.noindex/Page.build/Debug-iphonesimulator/Page.build/Objects-normal/arm64/Page.swiftconstvalues -emit-reference-dependencies-path /Users/oliveratkinson/Library/Developer/Xcode/DerivedData/Page-biekgzigjyhbfrfwypmsqcetysjd/Build/Intermediates.noindex/Page.build/Debug-iphonesimulator/Page.build/Objects-normal/arm64/Page.swiftdeps -serialize-diagnostics-path /Users/oliveratkinson/Library/Developer/Xcode/DerivedData/Page-biekgzigjyhbfrfwypmsqcetysjd/Build/Intermediates.noindex/Page.build/Debug-iphonesimulator/Page.build/Objects-normal/arm64/Page.dia -target arm64-apple-ios17.0-simulator -Xllvm -aarch64-use-tbi -enable-objc-interop -sdk /Applications/Xcode-15.1.0.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator17.2.sdk -I /Users/oliveratkinson/Library/Developer/Xcode/DerivedData/Page-biekgzigjyhbfrfwypmsqcetysjd/Build/Products/Debug-iphonesimulator -I /Applications/Xcode-15.1.0.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/lib -F /Users/oliveratkinson/Library/Developer/Xcode/DerivedData/Page-biekgzigjyhbfrfwypmsqcetysjd/Build/Products/Debug-iphonesimulator -F /Applications/Xcode-15.1.0.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks -F /Applications/Xcode-15.1.0.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator17.2.sdk/Developer/Library/Frameworks -no-color-diagnostics -enable-testing -g -module-cache-path /Users/oliveratkinson/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 -package-name page -const-gather-protocols-file /Users/oliveratkinson/Library/Developer/Xcode/DerivedData/Page-biekgzigjyhbfrfwypmsqcetysjd/Build/Intermediates.noindex/Page.build/Debug-iphonesimulator/Page.build/Objects-normal/arm64/Page_const_extract_protocols.json -empty-abi-descriptor -validate-clang-modules-once -clang-build-session-file /Users/oliveratkinson/Library/Developer/Xcode/DerivedData/ModuleCache.noindex/Session.modulevalidation -Xcc -working-directory -Xcc /Users/oliveratkinson/Development/Page -resource-dir /Applications/Xcode-15.1.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift -enable-anonymous-context-mangled-names -Xcc -ivfsstatcache -Xcc /Users/oliveratkinson/Library/Developer/Xcode/DerivedData/SDKStatCaches.noindex/iphonesimulator17.2-21C52-74d182069ce2f8b17958adf49e5cbcd9.sdkstatcache -Xcc -I/Users/oliveratkinson/Library/Developer/Xcode/DerivedData/Page-biekgzigjyhbfrfwypmsqcetysjd/Build/Intermediates.noindex/Page.build/Debug-iphonesimulator/Page.build/swift-overrides.hmap -Xcc -I/Users/oliveratkinson/Library/Developer/Xcode/DerivedData/Page-biekgzigjyhbfrfwypmsqcetysjd/Build/Products/Debug-iphonesimulator/include -Xcc -I/Users/oliveratkinson/Library/Developer/Xcode/DerivedData/Page-biekgzigjyhbfrfwypmsqcetysjd/Build/Intermediates.noindex/Page.build/Debug-iphonesimulator/Page.build/DerivedSources-normal/arm64 -Xcc -I/Users/oliveratkinson/Library/Developer/Xcode/DerivedData/Page-biekgzigjyhbfrfwypmsqcetysjd/Build/Intermediates.noindex/Page.build/Debug-iphonesimulator/Page.build/DerivedSources/arm64 -Xcc -I/Users/oliveratkinson/Library/Developer/Xcode/DerivedData/Page-biekgzigjyhbfrfwypmsqcetysjd/Build/Intermediates.noindex/Page.build/Debug-iphonesimulator/Page.build/DerivedSources -Xcc -DSWIFT_PACKAGE -Xcc -DDEBUG=1 -module-name Page -frontend-parseable-output -disable-clang-spi -target-sdk-version 17.2 -target-sdk-name iphonesimulator17.2 -external-plugin-path /Applications/Xcode-15.1.0.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator17.2.sdk/usr/lib/swift/host/plugins#/Applications/Xcode-15.1.0.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator17.2.sdk/usr/bin/swift-plugin-server -external-plugin-path /Applications/Xcode-15.1.0.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator17.2.sdk/usr/local/lib/swift/host/plugins#/Applications/Xcode-15.1.0.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator17.2.sdk/usr/bin/swift-plugin-server -external-plugin-path /Applications/Xcode-15.1.0.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/lib/swift/host/plugins#/Applications/Xcode-15.1.0.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/swift-plugin-server -external-plugin-path /Applications/Xcode-15.1.0.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/local/lib/swift/host/plugins#/Applications/Xcode-15.1.0.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/swift-plugin-server -plugin-path /Applications/Xcode-15.1.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/host/plugins -plugin-path /Applications/Xcode-15.1.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/local/lib/swift/host/plugins -parse-as-library -o /Users/oliveratkinson/Library/Developer/Xcode/DerivedData/Page-biekgzigjyhbfrfwypmsqcetysjd/Build/Intermediates.noindex/Page.build/Debug-iphonesimulator/Page.build/Objects-normal/arm64/Page.o -index-unit-output-path /Page.build/Debug-iphonesimulator/Page.build/Objects-normal/arm64/Page.o -index-store-path /Users/oliveratkinson/Library/Developer/Xcode/DerivedData/Page-biekgzigjyhbfrfwypmsqcetysjd/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/oliveratkinson/Development/Page/Sources/Page/Page.swift")
4. While emitting IR SIL function "@$s4Page5crash11existentialyAA3Foo_p_tF".
for 'crash(existential:)' (at /Users/oliveratkinson/Development/Page/Sources/Page/Page.swift:8:1)
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 0x0000000107b19abc llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1 swift-frontend 0x000000010a77fcb0 llvm::sys::RunSignalHandlers() + 112
2 swift-frontend 0x000000010a4e9054 SignalHandler(int) + 352
3 libsystem_platform.dylib 0x000000018d8c1a24 _sigtramp + 56
4 swift-frontend 0x0000000109007d48 swift::irgen::emitArchetypeTypeMetadataRef(swift::irgen::IRGenFunction&, swift::CanTypeWrapper<swift::ArchetypeType>, swift::irgen::DynamicMetadataRequest) + 288
5 swift-frontend 0x0000000109007e18 swift::irgen::emitArchetypeTypeMetadataRef(swift::irgen::IRGenFunction&, swift::CanTypeWrapper<swift::ArchetypeType>, swift::irgen::DynamicMetadataRequest) + 496
6 swift-frontend 0x000000010a5b64d8 emitDirectTypeMetadataRef(swift::irgen::IRGenFunction&, swift::CanType, swift::irgen::DynamicMetadataRequest) + 252
7 swift-frontend 0x00000001064bc668 swift::irgen::IRGenFunction::emitTypeMetadataRef(swift::CanType, swift::irgen::DynamicMetadataRequest) + 292
8 swift-frontend 0x00000001064bda08 swift::irgen::IRGenFunction::emitTypeMetadataRefForLayout(swift::SILType, swift::irgen::DynamicMetadataRequest) + 296
9 swift-frontend 0x00000001057a5d14 swift::irgen::IRGenFunction::emitValueWitnessTableRef(swift::SILType, swift::irgen::DynamicMetadataRequest, llvm::Value**) + 136
10 swift-frontend 0x0000000108bb56e4 swift::irgen::emitLoadOfSize(swift::irgen::IRGenFunction&, swift::SILType) + 96
11 swift-frontend 0x00000001070ee92c swift::irgen::WitnessSizedTypeInfo<(anonymous namespace)::OpaqueArchetypeTypeInfo>::allocateStack(swift::irgen::IRGenFunction&, swift::SILType, llvm::Twine const&) const + 52
12 swift-frontend 0x000000010770ef40 (anonymous namespace)::IRGenSILFunction::visitSILBasicBlock(swift::SILBasicBlock*) + 22292
13 swift-frontend 0x0000000109e9dfdc swift::irgen::IRGenModule::emitSILFunction(swift::SILFunction*) + 11680
14 swift-frontend 0x0000000107a9c9c8 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
15 swift-frontend 0x00000001061419d0 swift::IRGenRequest::evaluate(swift::Evaluator&, swift::IRGenDescriptor) const + 6532
16 swift-frontend 0x0000000105a14adc swift::SimpleRequest<swift::IRGenRequest, swift::GeneratedModule (swift::IRGenDescriptor), (swift::RequestFlags)9>::evaluateRequest(swift::IRGenRequest const&, swift::Evaluator&) + 176
17 swift-frontend 0x00000001073e5f64 llvm::Expected<swift::IRGenRequest::OutputType> swift::Evaluator::getResultUncached<swift::IRGenRequest>(swift::IRGenRequest const&) + 1480
18 swift-frontend 0x000000010968cfb8 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
19 swift-frontend 0x000000010a05999c 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
20 swift-frontend 0x000000010a0616d4 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
21 swift-frontend 0x000000010a05ca08 performCompile(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 1748
22 swift-frontend 0x000000010a060854 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 4568
23 swift-frontend 0x000000010a0c7d44 swift::mainEntry(int, char const**) + 4408
24 dyld 0x000000018d5110e0 start + 2360
Expected behavior
I would not expect a crash but instead a warning the same as the near-workaround. It would be nice to avoid writing explicit type erasure for Foo
- but understand this may not be possible in the language yet.
Environment
swift-driver version: 1.87.3 Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5)
Target: arm64-apple-macosx14.0
Additional information
No response