Skip to content

SIL verifier crash: _read yielding ~Escapable value with @_lifetime(borrow) #87029

@coenttb

Description

@coenttb

Description

The compiler crashes (signal 6) during SIL verification when a _read coroutine yields a ~Copyable & ~Escapable value whose initializer has a @_lifetime(borrow) lifetime dependency. The SIL verifier detects a double-consume: mark_dependence [nonescaping] and destroy_value both consume the yielded value.

This crash only occurs with the swift.org open-source toolchain (+assertions build). The Xcode-bundled toolchain (same version, no assertions) compiles successfully.

Environment

  • Swift version (crashes): Apple Swift version 6.2.3 (swift-6.2.3-RELEASE), Build config: +assertions
  • Swift version (also crashes): Apple Swift version 6.3-dev (main-snapshot-2026-02-05), Build config: +assertions
  • Swift version (works): Apple Swift version 6.2.3 (swiftlang-6.2.3.3.21 clang-1700.6.3.2)
  • Target: arm64-apple-macosx26.0
  • Crash location: SIL verifier, function @$s24SILVerifierReadEscapable1PPAARi_zrlE7wrapperAA7WrapperVyxGvr

Minimal Reproduction (20 lines)

public struct Wrapper<Base: ~Copyable>: ~Copyable, ~Escapable {
    @usableFromInline
    var _base: UnsafeMutablePointer<Base>

    @inlinable
    @_lifetime(borrow base)
    public init(_ base: UnsafeMutablePointer<Base>) {
        unsafe _base = base
    }
}

public protocol P: ~Copyable {}

extension P where Self: ~Copyable {
    public var wrapper: Wrapper<Self> {
        mutating _read {
            yield unsafe Wrapper<Self>(&self)  // CRASHES
        }
    }
}

Reproduction repo: https://github.com/coenttb/swift-issue-sil-verifier-read-escapable-lifetime

git clone https://github.com/coenttb/swift-issue-sil-verifier-read-escapable-lifetime
cd swift-issue-sil-verifier-read-escapable-lifetime
swift build  # Using swift.org 6.2.3-RELEASE toolchain (+assertions)

Crash Output

Begin Error in Function: '$s24SILVerifierReadEscapable1PPAARi_zrlE7wrapperAA7WrapperVyxGvr'
Found over consume?!
Value:   %7 = apply ... Wrapper<Self>
User:   %8 = mark_dependence [nonescaping] %7 : $Wrapper<Self> on %5 : $UnsafeMutablePointer<Self>
Block: bb0
Consuming Users:
  destroy_value %7 : $Wrapper<Self>
  %8 = mark_dependence [nonescaping] %7 : $Wrapper<Self> on %5 : $UnsafeMutablePointer<Self>

End Error in Function: '$s24SILVerifierReadEscapable1PPAARi_zrlE7wrapperAA7WrapperVyxGvr'
Found ownership error?!
<unknown>:0: error: fatal error encountered during compilation; please submit a bug report
<unknown>:0: note: triggering standard assertion failure routine

Conditions Required

All 5 conditions must be present to trigger the crash:

# Condition Description
1 ~Copyable & ~Escapable struct The yielded type must be both non-copyable and non-escapable
2 @_lifetime(borrow) init The struct's initializer must have a lifetime dependency
3 _read coroutine accessor The property must use _read to yield the value
4 where Self: ~Copyable The protocol extension must constrain Self as ~Copyable
5 +assertions toolchain Only swift.org open-source builds with assertions enabled

Workaround

Use the Xcode-bundled Swift 6.2.3 toolchain instead of the swift.org open-source toolchain:

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift build

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