Skip to content

IRGen crash: async function with typed throws and nested error type under generic #86347

@coenttb

Description

@coenttb

Description

The Swift compiler crashes with signal 11 during IR generation when an async function uses typed throws with a nested error type under any generic type.

Environment

  • Swift version: 6.2.3 (swiftlang-6.2.3.3.21 clang-1700.6.3.2)
  • Target: arm64-apple-macosx26.0
  • Crash location: swift::irgen::emitAsyncReturn

Minimal Reproduction (4 lines)

public enum Box<T> {
    public enum Error: Swift.Error { case fail }
    public static func go() async throws(Error) {}  // CRASHES
}

Full reproduction repository: https://github.com/coenttb/swift-issue-irgen-async-typed-throws-noncopyable

To Reproduce

echo 'public enum Box<T> { public enum Error: Swift.Error { case fail }; public static func go() async throws(Error) {} }' > /tmp/crash.swift
swiftc -parse-as-library -emit-ir /tmp/crash.swift

Stack Trace

error: compile command failed due to signal 11 (use -v to see invocation)
Stack dump:
0.  Program arguments: swift-frontend -frontend -emit-ir ...
1.  Apple Swift version 6.2.3 (swiftlang-6.2.3.3.21 clang-1700.6.3.2)
2.  Compiling with effective version 5.10
3.  While evaluating request IRGenRequest(IR Generation for file "...")
4.  While emitting IR SIL function "@$s6test103BoxO2goyyYaAC5ErrorOyx_GYKFZ".
 for 'go()' (at /tmp/crash.swift:1:...)
...
4  swift-frontend  swift::irgen::emitAsyncReturn(...) + 904

Conditions Required

All three conditions must be present:

  1. Generic type - any generic parameter (e.g., Box<T>)
  2. Nested error type - error type defined inside the generic
  3. Async + typed throws - async throws(NestedError)

Verified Test Results

Test Description Result
Sync function throws(Error) without async ✅ Compiles
Untyped throws async throws (not typed) ✅ Compiles
Non-generic Box without generic parameter ✅ Compiles
Top-level error throws(TopLevelError) ✅ Compiles
Nested return only Nested return type, top-level error ✅ Compiles
Typealias workaround typealias Error = HoistedError ✅ Compiles
With ~Copyable Box<T: ~Copyable> ❌ Crashes
Minimal generic Box<T> with nested error ❌ Crashes

Key finding: The crash is specifically triggered by nested error type in typed throws under any generic. ~Copyable is not required.

Workaround

Hoist error types to top-level and re-export via typealiases:

public enum BoxError: Swift.Error { case fail }

public enum Box<T> {
    public typealias Error = BoxError
    public static func go() async throws(Error) {}  // Works
}

Related Issues

Impact

This blocks adoption of typed throws in libraries using generics with nested error types and async APIs - a common pattern in I/O, networking, and resource management libraries.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions