Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiler crash when mixing opaque result types, variadic types, and conditional conformances #70429

Closed
dehesa opened this issue Dec 13, 2023 · 1 comment
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler itself conditional conformances Feature → protocol → conformances: conditional conformances conformances Feature → protocol: protocol conformances crash Bug: A crash, i.e., an abnormal termination of software generics Feature: generic declarations and types mangling Area → compiler: Mangling opaque result types Feature → types → opaque types: opaque result types opaque types Feature → types: opaque types parameter packs Feature → generics: Parameter packs swift 5.9

Comments

@dehesa
Copy link

dehesa commented Dec 13, 2023

Description

I am building a small ProseMirror-like library in Swift. I decide to make heavy usage of variadic types, result builders, and opaque result types to make text definition as easy as possible to the user.

However, I have been confronting multiple issues when building even the smallest project. I've already raised a couple of issues:

This crash doesn't, however, have a simple reproduction, so I have attached the SPM project here (the package is still very small). Also, the project serves for the issues previously raised.

Reproduction

You can find the SPM package here:
textNodes.zip

I have managed to put all the affected code in the following block. I recommend to open the SPM package better. In any case, if you prefer the code Snippet below, you will find that the compiler crashes just by building the code. You can successfully build by commenting lines 85 and 87.

public protocol Node: Sendable {}
public protocol BlockNode: Node {}
public protocol InlineNode: Node {}

// MARK: - Block nodes

public struct Paragraph: BlockNode {
  public init() {}
}

// MARK: - NodeGroup

/// Intermediate aggregate for nodes.
///
/// Its intended usage is for building node groups through result builders.
public struct NodeGroup<each N: Node>: Sendable {
  @usableFromInline let nodes: (repeat each N)

  @usableFromInline init(nodes: repeat each N) {
    self.nodes = (repeat each nodes)
  }

  @usableFromInline func merging<each M>(_ group: NodeGroup<repeat each M>) -> NodeGroup<repeat each N, repeat each M> {
    NodeGroup<repeat each N, repeat each M>(nodes: repeat each self.nodes, repeat each group.nodes)
  }
}

@resultBuilder public enum GroupBuilder {
  public static func buildExpression<N: Node>(_ expression: N) -> NodeGroup<N> {
    NodeGroup(nodes: expression)
  }

  public static func buildPartialBlock<each N: Node>(first: consuming NodeGroup<repeat each N>) -> NodeGroup<repeat each N> {
    first
  }

  public static func buildPartialBlock<each A, each N>(accumulated: consuming NodeGroup<repeat each A>, next: consuming NodeGroup<repeat each N>) -> NodeGroup<repeat each A, repeat each N> {
    let tmp = accumulated.merging(next)
    return tmp
  }
}

// MARK: - Zero or More

/// Group defining a bunch of children nodes, which can occur zero or more times in a non-sequential order.
public struct ZeroOrMore<each N: Node>: Node {
  /// All nodes hold by this group.
  public let nodes: (repeat each N)

  public init(nodes: repeat each N) where repeat each N: InlineNode {
    self.nodes = (repeat each nodes)
  }

  public init(nodes: repeat each N) where repeat each N: BlockNode {
    self.nodes = (repeat each nodes)
  }

  public init(@GroupBuilder group: () -> NodeGroup<repeat each N>) where repeat each N: InlineNode {
    self.nodes = group().nodes
  }

  public init(@GroupBuilder group: () -> NodeGroup<repeat each N>) where repeat each N: BlockNode {
    self.nodes = group().nodes
  }
}

// When all children blocks are block nodes, the group is a block node itself.
extension ZeroOrMore: BlockNode where repeat each N: BlockNode {}
// When all children blocks are inline nodes, the group is an inline node itself.
extension ZeroOrMore: InlineNode where repeat each N: InlineNode {}

// MARK: - Schema

/// A ``Schema`` defines what a text document can contain/display.
public protocol Schema: Sendable {
  associatedtype Document: BlockNode

  var document: Document { get }
}

public struct MarkdownSchema: Schema {
  public init() {}

  public var document: some BlockNode {
    ZeroOrMore {
      Paragraph()
    }
  }
}

Stack dump

0.	Program arguments: /Applications/Xcode-15.1.0-Release.Candidate.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-frontend -frontend -c "/Users/marcos/Downloads/Raycast/TextKit/Raycast - Text/raycast-text/Sources/Models/Nodes/Block/Blocks.swift" "/Users/marcos/Downloads/Raycast/TextKit/Raycast - Text/raycast-text/Sources/Models/Nodes/Inline/Inlines.swift" "/Users/marcos/Downloads/Raycast/TextKit/Raycast - Text/raycast-text/Sources/Models/Nodes/Node.swift" "/Users/marcos/Downloads/Raycast/TextKit/Raycast - Text/raycast-text/Sources/Models/Nodes/NodeGroup.swift" "/Users/marcos/Downloads/Raycast/TextKit/Raycast - Text/raycast-text/Sources/Models/Nodes/ZeroOrMore.swift" "/Users/marcos/Downloads/Raycast/TextKit/Raycast - Text/raycast-text/Sources/Models/Schemas/MarkdownSchema.swift" -primary-file "/Users/marcos/Downloads/Raycast/TextKit/Raycast - Text/raycast-text/Sources/Models/Schemas/Schema.swift" -emit-dependencies-path /Users/marcos/Library/Developer/Xcode/DerivedData/raycast-text-aoodlsmfgfgmkdhiglrxoqwrzymk/Build/Intermediates.noindex/raycast-text.build/Debug/RaycastTextModels.build/Objects-normal/arm64/Schema.d -emit-const-values-path /Users/marcos/Library/Developer/Xcode/DerivedData/raycast-text-aoodlsmfgfgmkdhiglrxoqwrzymk/Build/Intermediates.noindex/raycast-text.build/Debug/RaycastTextModels.build/Objects-normal/arm64/Schema.swiftconstvalues -emit-reference-dependencies-path /Users/marcos/Library/Developer/Xcode/DerivedData/raycast-text-aoodlsmfgfgmkdhiglrxoqwrzymk/Build/Intermediates.noindex/raycast-text.build/Debug/RaycastTextModels.build/Objects-normal/arm64/Schema.swiftdeps -serialize-diagnostics-path /Users/marcos/Library/Developer/Xcode/DerivedData/raycast-text-aoodlsmfgfgmkdhiglrxoqwrzymk/Build/Intermediates.noindex/raycast-text.build/Debug/RaycastTextModels.build/Objects-normal/arm64/Schema.dia -target arm64-apple-macos14.0 -Xllvm -aarch64-use-tbi -enable-objc-interop -stack-check -sdk /Applications/Xcode-15.1.0-Release.Candidate.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk -I /Users/marcos/Library/Developer/Xcode/DerivedData/raycast-text-aoodlsmfgfgmkdhiglrxoqwrzymk/Build/Products/Debug -I /Applications/Xcode-15.1.0-Release.Candidate.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/lib -F /Users/marcos/Library/Developer/Xcode/DerivedData/raycast-text-aoodlsmfgfgmkdhiglrxoqwrzymk/Build/Products/Debug -F /Applications/Xcode-15.1.0-Release.Candidate.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks -no-color-diagnostics -enable-testing -g -module-cache-path /Users/marcos/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 raycast_text -const-gather-protocols-file /Users/marcos/Library/Developer/Xcode/DerivedData/raycast-text-aoodlsmfgfgmkdhiglrxoqwrzymk/Build/Intermediates.noindex/raycast-text.build/Debug/RaycastTextModels.build/Objects-normal/arm64/RaycastTextModels_const_extract_protocols.json -empty-abi-descriptor -validate-clang-modules-once -clang-build-session-file /Users/marcos/Library/Developer/Xcode/DerivedData/ModuleCache.noindex/Session.modulevalidation -Xcc -working-directory -Xcc "/Users/marcos/Downloads/Raycast/TextKit/Raycast - Text/raycast-text" -resource-dir /Applications/Xcode-15.1.0-Release.Candidate.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift -enable-anonymous-context-mangled-names -Xcc -ivfsstatcache -Xcc /Users/marcos/Library/Developer/Xcode/DerivedData/SDKStatCaches.noindex/macosx14.2-23C53-a7d2c1c4c10238a89df904f163170da0.sdkstatcache -Xcc -I/Users/marcos/Library/Developer/Xcode/DerivedData/raycast-text-aoodlsmfgfgmkdhiglrxoqwrzymk/Build/Intermediates.noindex/raycast-text.build/Debug/RaycastTextModels.build/swift-overrides.hmap -Xcc -I/Users/marcos/Library/Developer/Xcode/DerivedData/raycast-text-aoodlsmfgfgmkdhiglrxoqwrzymk/Build/Products/Debug/include -Xcc -I/Users/marcos/Library/Developer/Xcode/DerivedData/raycast-text-aoodlsmfgfgmkdhiglrxoqwrzymk/Build/Intermediates.noindex/raycast-text.build/Debug/RaycastTextModels.build/DerivedSources-normal/arm64 -Xcc -I/Users/marcos/Library/Developer/Xcode/DerivedData/raycast-text-aoodlsmfgfgmkdhiglrxoqwrzymk/Build/Intermediates.noindex/raycast-text.build/Debug/RaycastTextModels.build/DerivedSources/arm64 -Xcc -I/Users/marcos/Library/Developer/Xcode/DerivedData/raycast-text-aoodlsmfgfgmkdhiglrxoqwrzymk/Build/Intermediates.noindex/raycast-text.build/Debug/RaycastTextModels.build/DerivedSources -Xcc -DSWIFT_PACKAGE -Xcc -DDEBUG=1 -module-name RaycastTextModels -frontend-parseable-output -disable-clang-spi -target-sdk-version 14.2 -target-sdk-name macosx14.2 -external-plugin-path /Applications/Xcode-15.1.0-Release.Candidate.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk/usr/lib/swift/host/plugins#/Applications/Xcode-15.1.0-Release.Candidate.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk/usr/bin/swift-plugin-server -external-plugin-path /Applications/Xcode-15.1.0-Release.Candidate.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk/usr/local/lib/swift/host/plugins#/Applications/Xcode-15.1.0-Release.Candidate.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk/usr/bin/swift-plugin-server -external-plugin-path /Applications/Xcode-15.1.0-Release.Candidate.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/lib/swift/host/plugins#/Applications/Xcode-15.1.0-Release.Candidate.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/bin/swift-plugin-server -external-plugin-path /Applications/Xcode-15.1.0-Release.Candidate.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/local/lib/swift/host/plugins#/Applications/Xcode-15.1.0-Release.Candidate.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/bin/swift-plugin-server -plugin-path /Applications/Xcode-15.1.0-Release.Candidate.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/host/plugins -plugin-path /Applications/Xcode-15.1.0-Release.Candidate.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/local/lib/swift/host/plugins -o /Users/marcos/Library/Developer/Xcode/DerivedData/raycast-text-aoodlsmfgfgmkdhiglrxoqwrzymk/Build/Intermediates.noindex/raycast-text.build/Debug/RaycastTextModels.build/Objects-normal/arm64/Schema.o -index-unit-output-path /raycast-text.build/Debug/RaycastTextModels.build/Objects-normal/arm64/Schema.o -index-store-path /Users/marcos/Library/Developer/Xcode/DerivedData/raycast-text-aoodlsmfgfgmkdhiglrxoqwrzymk/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/marcos/Downloads/Raycast/TextKit/Raycast - Text/raycast-text/Sources/Models/Schemas/Schema.swift")
4.	While emitting IR for source file /Users/marcos/Downloads/Raycast/TextKit/Raycast - Text/raycast-text/Sources/Models/Schemas/Schema.swift
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           0x0000000102c71abc llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1  swift-frontend           0x00000001058d7cb0 llvm::sys::RunSignalHandlers() + 112
2  swift-frontend           0x0000000105641054 SignalHandler(int) + 352
3  libsystem_platform.dylib 0x0000000184c49a24 _sigtramp + 56
4  swift-frontend           0x000000010309fee0 swift::Mangle::ASTMangler::appendConcreteProtocolConformance(swift::ProtocolConformance const*, swift::GenericSignature) + 52
5  swift-frontend           0x000000010309fee0 swift::Mangle::ASTMangler::appendConcreteProtocolConformance(swift::ProtocolConformance const*, swift::GenericSignature) + 52
6  swift-frontend           0x00000001030a0680 swift::Mangle::ASTMangler::appendConcreteProtocolConformance(swift::ProtocolConformance const*, swift::GenericSignature) + 2004
7  swift-frontend           0x00000001013a094c swift::irgen::IRGenMangler::mangleSymbolNameForMangledConformanceAccessorString(char const*, swift::CanGenericSignature, swift::CanType, swift::ProtocolConformanceRef) + 212
8  swift-frontend           0x00000001010ed41c swift::irgen::IRGenModule::emitWitnessTableRefString(swift::CanType, swift::ProtocolConformanceRef, swift::GenericSignature, bool) + 432
9  swift-frontend           0x00000001039f3234 swift::irgen::IRGenModule::emitOpaqueTypeDecl(swift::OpaqueTypeDecl*) + 4884
10 swift-frontend           0x0000000102bafd54 swift::irgen::IRGenModule::emitSourceFile(swift::SourceFile&) + 440
11 swift-frontend           0x0000000101299b10 swift::IRGenRequest::evaluate(swift::Evaluator&, swift::IRGenDescriptor) const + 6852
12 swift-frontend           0x0000000100b6cadc swift::SimpleRequest<swift::IRGenRequest, swift::GeneratedModule (swift::IRGenDescriptor), (swift::RequestFlags)9>::evaluateRequest(swift::IRGenRequest const&, swift::Evaluator&) + 176
13 swift-frontend           0x000000010253df64 llvm::Expected<swift::IRGenRequest::OutputType> swift::Evaluator::getResultUncached<swift::IRGenRequest>(swift::IRGenRequest const&) + 1480
14 swift-frontend           0x00000001047e4fb8 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
15 swift-frontend           0x00000001051b199c 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
16 swift-frontend           0x00000001051b96d4 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
17 swift-frontend           0x00000001051b4a08 performCompile(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 1748
18 swift-frontend           0x00000001051b8854 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 4568
19 swift-frontend           0x000000010521fd44 swift::mainEntry(int, char const**) + 4408
20 dyld                     0x00000001848990e0 start + 2360

Expected behavior

Be able to use opaque return types in the MarkdownSchema and obviously not having the crash. I want to be able to write something like:

let schema = MarkdownSchema()
let document = schema.document

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

@dehesa dehesa added bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. crash Bug: A crash, i.e., an abnormal termination of software triage needed This issue needs more specific labels labels Dec 13, 2023
@slavapestov slavapestov self-assigned this Dec 13, 2023
@hborla hborla added generics Feature: generic declarations and types and removed triage needed This issue needs more specific labels labels Jul 14, 2024
@slavapestov
Copy link
Contributor

No longer crashes in Swift 6. I'll add a regression test.

@AnthonyLatsis AnthonyLatsis added opaque types Feature → types: opaque types parameter packs Feature → generics: Parameter packs opaque result types Feature → types → opaque types: opaque result types swift 5.9 compiler The Swift compiler itself conformances Feature → protocol: protocol conformances conditional conformances Feature → protocol → conformances: conditional conformances mangling Area → compiler: Mangling labels Aug 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler itself conditional conformances Feature → protocol → conformances: conditional conformances conformances Feature → protocol: protocol conformances crash Bug: A crash, i.e., an abnormal termination of software generics Feature: generic declarations and types mangling Area → compiler: Mangling opaque result types Feature → types → opaque types: opaque result types opaque types Feature → types: opaque types parameter packs Feature → generics: Parameter packs swift 5.9
Projects
None yet
Development

No branches or pull requests

4 participants