swiftlang / swift

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

[SR-14641] Recursive definition of protocol conformance with result builders crashes compiler #56993

Open darknoon opened 3 years ago

darknoon commented 3 years ago
Previous ID SR-14641
Radar rdar://problem/78224325
Original Reporter @darknoon
Type Bug

Attachment: Download

Environment Xcode Version 12.5 (12E262) $ swift --version Apple Swift version 5.4 (swiftlang-1205.0.26.9 clang-1205.0.19.55) Target: arm64-apple-darwin20.4.0
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Bug | |Assignee | None | |Priority | Medium | md5: 1b9e750c1b6110b2664a69e44ef92e27

Issue Description:

This issue happened in the larger context of a vaguely SwiftUI-like situation where `Never` is supposed to stop the recursion of parent with body -> body and I was able to reduce it to just this code:

#!/usr/bin/swift
protocol Scene {
 associatedtype Body
 @SceneBuilder var body: Body { get }
}

@resultBuilder struct SceneBuilder {
static func buildBlock<A>(_ a: A) -> some Scene where A : Scene, A.Body : Scene
{ a.body }
}

extension Never : Scene {
 var body: some Scene { fatalError("Never asked for body") }
}

This code crashes my compiler like this (in larger example crashed both main 5.5 snapshot and built-in 5.4 compiler:

swift SwiftCompilerCrash.swift  Illegal instruction: 4
typesanitizer commented 3 years ago

Triggers a stack overflow.

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   swift-frontend                  0x0000000102a978bf swift::Type::transformRec(llvm::function_ref<llvm::Optional<swift::Type> (swift::TypeBase*)>) const + 63
1   swift-frontend                  0x0000000102a959d9 substType(swift::Type, llvm::function_ref<swift::Type (swift::SubstitutableType*)>, llvm::function_ref<swift::ProtocolConformanceRef (swift::CanType, swift::Type, swift::ProtocolDecl*)>, swift::SubstOptions) + 297
2   swift-frontend                  0x0000000102a9efe2 llvm::Optional<swift::Type> llvm::function_ref<llvm::Optional<swift::Type> (swift::TypeBase*)>::callback_fn<substType(swift::Type, llvm::function_ref<swift::Type (swift::SubstitutableType*)>, llvm::function_ref<swift::ProtocolConformanceRef (swift::CanType, swift::Type, swift::ProtocolDecl*)>, swift::SubstOptions)::$_26>(long, swift::TypeBase*) + 2002
3   swift-frontend                  0x0000000102a978c2 swift::Type::transformRec(llvm::function_ref<llvm::Optional<swift::Type> (swift::TypeBase*)>) const + 66
4   swift-frontend                  0x0000000102a959d9 substType(swift::Type, llvm::function_ref<swift::Type (swift::SubstitutableType*)>, llvm::function_ref<swift::ProtocolConformanceRef (swift::CanType, swift::Type, swift::ProtocolDecl*)>, swift::SubstOptions) + 297
5   swift-frontend                  0x0000000102a92f5b swift::ReplaceOpaqueTypesWithUnderlyingTypes::operator()(swift::SubstitutableType*) const + 411
6   swift-frontend                  0x0000000102a9ef63 llvm::Optional<swift::Type> llvm::function_ref<llvm::Optional<swift::Type> (swift::TypeBase*)>::callback_fn<substType(swift::Type, llvm::function_ref<swift::Type (swift::SubstitutableType*)>, llvm::function_ref<swift::ProtocolConformanceRef (swift::CanType, swift::Type, swift::ProtocolDecl*)>, swift::SubstOptions)::$_26>(long, swift::TypeBase*) + 1875
7   swift-frontend                  0x0000000102a978c2 swift::Type::transformRec(llvm::function_ref<llvm::Optional<swift::Type> (swift::TypeBase*)>) const + 66
8   swift-frontend                  0x0000000102a959d9 substType(swift::Type, llvm::function_ref<swift::Type (swift::SubstitutableType*)>, llvm::function_ref<swift::ProtocolConformanceRef (swift::CanType, swift::Type, swift::ProtocolDecl*)>, swift::SubstOptions) + 297
9   swift-frontend                  0x0000000102a93016 swift::ReplaceOpaqueTypesWithUnderlyingTypes::operator()(swift::SubstitutableType*) const + 598
10  swift-frontend                  0x0000000102a9ef63 llvm::Optional<swift::Type> llvm::function_ref<llvm::Optional<swift::Type> (swift::TypeBase*)>::callback_fn<substType(swift::Type, llvm::function_ref<swift::Type (swift::SubstitutableType*)>, llvm::function_ref<swift::ProtocolConformanceRef (swift::CanType, swift::Type, swift::ProtocolDecl*)>, swift::SubstOptions)::$_26>(long, swift::TypeBase*) + 1875
11  swift-frontend                  0x0000000102a978c2 swift::Type::transformRec(llvm::function_ref<llvm::Optional<swift::Type> (swift::TypeBase*)>) const + 66
12  swift-frontend                  0x0000000102a959d9 substType(swift::Type, llvm::function_ref<swift::Type (swift::SubstitutableType*)>, llvm::function_ref<swift::ProtocolConformanceRef (swift::CanType, swift::Type, swift::ProtocolDecl*)>, swift::SubstOptions) + 297
13  swift-frontend                  0x0000000102a93016 swift::ReplaceOpaqueTypesWithUnderlyingTypes::operator()(swift::SubstitutableType*) const + 598
14  swift-frontend                  0x0000000102a9ef63 llvm::Optional<swift::Type> llvm::function_ref<llvm::Optional<swift::Type> (swift::TypeBase*)>::callback_fn<substType(swift::Type, llvm::function_ref<swift::Type (swift::SubstitutableType*)>, llvm::function_ref<swift::ProtocolConformanceRef (swift::CanType, swift::Type, swift::ProtocolDecl*)>, swift::SubstOptions)::$_26>(long, swift::TypeBase*) + 1875
15  swift-frontend                  0x0000000102a978c2 swift::Type::transformRec(llvm::function_ref<llvm::Optional<swift::Type> (swift::TypeBase*)>) const + 66
16  swift-frontend                  0x0000000102a959d9 substType(swift::Type, llvm::function_ref<swift::Type (swift::SubstitutableType*)>, llvm::function_ref<swift::ProtocolConformanceRef (swift::CanType, swift::Type, swift::ProtocolDecl*)>, swift::SubstOptions) + 297
17  swift-frontend                  0x0000000102a93016 swift::ReplaceOpaqueTypesWithUnderlyingTypes::operator()(swift::SubstitutableType*) const + 598
18  swift-frontend                  0x0000000102a9ef63 llvm::Optional<swift::Type> llvm::function_ref<llvm::Optional<swift::Type> (swift::TypeBase*)>::callback_fn<substType(swift::Type, llvm::function_ref<swift::Type (swift::SubstitutableType*)>, llvm::function_ref<swift::ProtocolConformanceRef (swift::CanType, swift::Type, swift::ProtocolDecl*)>, swift::SubstOptions)::$_26>(long, swift::TypeBase*) + 1875

@swift-ci create