# Is it ok to have an unfinished borrow in a basic block terminated with \`unreachable\` instruction?

**URL:** <https://forums.swift.org/t/is-it-ok-to-have-an-unfinished-borrow-in-a-basic-block-terminated-with-unreachable-instruction/89147>\
**Category:** Compiler\
**Tags:** lifetime\
**Created:** [August 24, 2026, 1:54pm UTC](https://forums.swift.org/t/is-it-ok-to-have-an-unfinished-borrow-in-a-basic-block-terminated-with-unreachable-instruction/89147 "2026-08-24T13:54:44Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nickolas\_Pohilets](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nickolas_pohilets/32/10659_2.png) [@Nickolas\_Pohilets](https://forums.swift.org/u/Nickolas_Pohilets)\
**Post date:** [August 24, 2026, 1:54pm UTC](https://forums.swift.org/t/is-it-ok-to-have-an-unfinished-borrow-in-a-basic-block-terminated-with-unreachable-instruction/89147/1 "2026-08-24T13:54:44Z")

</div>

I've added some unit tests in my PR, and they are triggering `LinearLifetimeChecker`. This seems to be an existing issue, not related to my changes, but reproducible by newly added tests. Reported as [A leak due to a consuming post-dominance failure · Issue #91645 · swiftlang/swift · GitHub](https://github.com/swiftlang/swift/issues/91645).

When running tests with `--param swift_test_mode=optimize_none_with_opaque_values` function `convertDirectToIndirectFunctionArgs()` inserts a `load_borrow` in the beginning of the function, and `end_borrow` in all function-existing blocks. But unreachable block does not count as function-exiting, and non `end_borrow` is inserted, which `LinearLifetimeChecker` complains about.

What would be the best way to fix it?

1. Teach `LinearLifetimeChecker` to ignore unreachable blocks.
2. Insert `end_borrow` by maintaining separate list of program-ending blocks (don't change `pass.exitingInsts`).
3. Insert `end_borrow` by inserting `unreachable`-terminated blocks into `pass.exitingInsts`, update `OpaqueValueVisitor::canonicalizeReturnValues()`, `ReturnRewriter::rewriteReturns()` and `ReturnRewriter::rewriteThrows()` to expect `UnreachableInst`.
4. Return true from `isFunctionExiting()` for `UnreachableInst`, update even more code.

So far, I'm leaning towards 2.

WDYT?

---

<div class="post-metadata">

**Author:** ![Nickolas\_Pohilets](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nickolas_pohilets/32/10659_2.png) [@Nickolas\_Pohilets](https://forums.swift.org/u/Nickolas_Pohilets)\
**Post date:** [August 24, 2026, 2:57pm UTC](https://forums.swift.org/t/is-it-ok-to-have-an-unfinished-borrow-in-a-basic-block-terminated-with-unreachable-instruction/89147/2 "2026-08-24T14:57:08Z")

</div>

The fix using #2 - [Fix 91645 by nickolas-pohilets · Pull Request #91678 · swiftlang/swift · GitHub](https://github.com/swiftlang/swift/pull/91678)

---

<div class="post-metadata">

**Author:** ![Andrew\_Trick](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/andrew_trick/32/323_2.png) [@Andrew\_Trick](https://forums.swift.org/u/Andrew_Trick)\
**Post date:** [August 24, 2026, 5:08pm UTC](https://forums.swift.org/t/is-it-ok-to-have-an-unfinished-borrow-in-a-basic-block-terminated-with-unreachable-instruction/89147/3 "2026-08-24T17:08:07Z")

</div>

I agree. The "complete lifetimes" property of OSSA requires an end\_borrow on all paths including `unreachable`-terminated blocks (aka dead-end blocks). @Erik_Eckstein recently enabled complete lifetimes but `AddressLowering` probably needed to be updated.
