@@ -255,6 +255,9 @@ struct BorrowedValue;
255255// / borrowed and thus the incoming value must implicitly be borrowed until the
256256// / user's corresponding end scope instruction.
257257// /
258+ // / Invariant: For a given operand, BorrowingOperand is valid iff
259+ // / it has OperandOwnership::Borrow or OperandOwnership::Reborrow.
260+ // /
258261// / NOTE: We do not require that the guaranteed scope be represented by a
259262// / guaranteed value in the same function: see begin_apply. In such cases, we
260263// / require instead an end_* instruction to mark the end of the scope's region.
@@ -264,10 +267,14 @@ struct BorrowingOperand {
264267
265268 BorrowingOperand (Operand *op)
266269 : op(op), kind(BorrowingOperandKind::get(op->getUser ()->getKind())) {
267- if (kind == BorrowingOperandKind::Branch
268- && op->get ().getOwnershipKind () != OwnershipKind::Guaranteed) {
270+ auto ownership = op->getOperandOwnership ();
271+ if (ownership != OperandOwnership::Borrow
272+ && ownership != OperandOwnership::Reborrow) {
273+ // consuming applies and branch arguments are not borrowing operands.
269274 kind = BorrowingOperandKind::Invalid;
275+ return ;
270276 }
277+ assert (kind != BorrowingOperandKind::Invalid && " missing case" );
271278 }
272279 BorrowingOperand (const BorrowingOperand &other)
273280 : op(other.op), kind(other.kind) {}
@@ -284,28 +291,7 @@ struct BorrowingOperand {
284291 const Operand *operator ->() const { return op; }
285292 Operand *operator ->() { return op; }
286293
287- operator bool () const { return kind != BorrowingOperandKind::Invalid && op; }
288-
289- // / If \p op is a borrow introducing operand return it after doing some
290- // / checks.
291- static BorrowingOperand get (Operand *op) {
292- auto *user = op->getUser ();
293- auto kind = BorrowingOperandKind::get (user->getKind ());
294- if (!kind)
295- return {nullptr , kind};
296-
297- if (kind == BorrowingOperandKind::Branch
298- && op->get ().getOwnershipKind () != OwnershipKind::Guaranteed) {
299- return {nullptr , BorrowingOperandKind::Invalid};
300- }
301- return {op, kind};
302- }
303-
304- // / If \p op is a borrow introducing operand return it after doing some
305- // / checks.
306- static BorrowingOperand get (const Operand *op) {
307- return get (const_cast <Operand *>(op));
308- }
294+ operator bool () const { return kind != BorrowingOperandKind::Invalid; }
309295
310296 // / If this borrowing operand results in the underlying value being borrowed
311297 // / over a region of code instead of just for a single instruction, visit
@@ -347,8 +333,14 @@ struct BorrowingOperand {
347333 llvm_unreachable (" Covered switch isn't covered?!" );
348334 }
349335
350- // / Return true if the user instruction introduces a borrow scope? This is
351- // / true for both reborrows and nested borrows.
336+ // / Return true if the user instruction defines a borrowed value that
337+ // / introduces a borrow scope and therefore may be reborrowed. This is true
338+ // / for both reborrows and nested borrows.
339+ // /
340+ // / Note that begin_apply does create a borrow scope, and may define
341+ // / guaranteed value within that scope. The difference is that those yielded
342+ // / values do not themselves introduce a borrow scope. In other words, they
343+ // / cannot be reborrowed.
352344 // /
353345 // / If true, the visitBorrowIntroducingUserResults() can be called to acquire
354346 // / each BorrowedValue that introduces a new borrow scopes.
@@ -599,7 +591,7 @@ struct BorrowedValue {
599591 &foundReborrows) const {
600592 bool foundAnyReborrows = false ;
601593 for (auto *op : value->getUses ()) {
602- if (auto borrowingOperand = BorrowingOperand::get (op)) {
594+ if (auto borrowingOperand = BorrowingOperand (op)) {
603595 if (borrowingOperand.isReborrow ()) {
604596 foundReborrows.push_back (
605597 {value->getParentBlock (), op->getOperandNumber ()});
0 commit comments