@@ -178,10 +178,17 @@ bool swift::findInnerTransitiveGuaranteedUses(
178178 break ;
179179 }
180180 case OperandOwnership::Borrow:
181- BorrowingOperand (use).visitExtendedScopeEndingUses ([&](Operand *endUse) {
182- leafUse (endUse);
183- return true ;
184- });
181+ // FIXME: visitExtendedScopeEndingUses can't return false here once dead
182+ // borrows are disallowed.
183+ if (!BorrowingOperand (use).visitExtendedScopeEndingUses (
184+ [&](Operand *endUse) {
185+ leafUse (endUse);
186+ return true ;
187+ })) {
188+ // Special case for dead borrows. This is dangerous because clients
189+ // don't expect a begin_borrow to be in the use list.
190+ leafUse (use);
191+ }
185192 break ;
186193 }
187194 }
@@ -275,10 +282,17 @@ bool swift::findInnerTransitiveGuaranteedUsesOfBorrowedValue(
275282 break ;
276283 }
277284 case OperandOwnership::Borrow:
278- BorrowingOperand (use).visitExtendedScopeEndingUses ([&](Operand *endUse) {
279- recordUse (endUse);
280- return true ;
281- });
285+ // FIXME: visitExtendedScopeEndingUses can't return false here once dead
286+ // borrows are disallowed.
287+ if (!BorrowingOperand (use).visitExtendedScopeEndingUses (
288+ [&](Operand *endUse) {
289+ recordUse (endUse);
290+ return true ;
291+ })) {
292+ // Special case for dead borrows. This is dangerous because clients
293+ // don't expect a begin_borrow to be in the use list.
294+ recordUse (use);
295+ }
282296 break ;
283297 }
284298 }
@@ -427,21 +441,29 @@ bool BorrowingOperand::visitScopeEndingUses(
427441 switch (kind) {
428442 case BorrowingOperandKind::Invalid:
429443 llvm_unreachable (" Using invalid case" );
430- case BorrowingOperandKind::BeginBorrow:
444+ case BorrowingOperandKind::BeginBorrow: {
445+ bool deadBorrow = true ;
431446 for (auto *use : cast<BeginBorrowInst>(op->getUser ())->getUses ()) {
432447 if (use->isLifetimeEnding ()) {
448+ deadBorrow = false ;
433449 if (!func (use))
434450 return false ;
435451 }
436452 }
437- return true ;
453+ // FIXME: special case for dead borrows. This is dangerous because clients
454+ // only expect visitScopeEndingUses to return false if the visitor returned
455+ // false.
456+ return !deadBorrow;
457+ }
438458 case BorrowingOperandKind::BeginApply: {
459+ bool deadApply = true ;
439460 auto *user = cast<BeginApplyInst>(op->getUser ());
440461 for (auto *use : user->getTokenResult ()->getUses ()) {
462+ deadApply = false ;
441463 if (!func (use))
442464 return false ;
443465 }
444- return true ;
466+ return !deadApply ;
445467 }
446468 // These are instantaneous borrow scopes so there aren't any special end
447469 // scope instructions.
@@ -450,12 +472,16 @@ bool BorrowingOperand::visitScopeEndingUses(
450472 case BorrowingOperandKind::Yield:
451473 return true ;
452474 case BorrowingOperandKind::Branch: {
475+ bool deadBranch = true ;
453476 auto *br = cast<BranchInst>(op->getUser ());
454- for (auto *use : br->getArgForOperand (op)->getUses ())
455- if (use->isLifetimeEnding ())
477+ for (auto *use : br->getArgForOperand (op)->getUses ()) {
478+ if (use->isLifetimeEnding ()) {
479+ deadBranch = false ;
456480 if (!func (use))
457481 return false ;
458- return true ;
482+ }
483+ }
484+ return !deadBranch;
459485 }
460486 }
461487 llvm_unreachable (" Covered switch isn't covered" );
@@ -522,10 +548,15 @@ BorrowedValue BorrowingOperand::getBorrowIntroducingUserResult() {
522548void BorrowingOperand::getImplicitUses (
523549 SmallVectorImpl<Operand *> &foundUses,
524550 std::function<void (Operand *)> *errorFunction) const {
525- visitScopeEndingUses ([&](Operand *op) {
526- foundUses.push_back (op);
551+ // FIXME: this visitScopeEndingUses should never return false once dead
552+ // borrows are disallowed.
553+ if (!visitScopeEndingUses ([&](Operand *endOp) {
554+ foundUses.push_back (endOp);
527555 return true ;
528- });
556+ })) {
557+ // Special-case for dead borrows.
558+ foundUses.push_back (op);
559+ }
529560}
530561
531562// ===----------------------------------------------------------------------===//
0 commit comments