@@ -1511,6 +1511,19 @@ bool GatherUsesVisitor::visitUse(Operand *op) {
15111511 assert (op->getOperandNumber () == CopyAddrInst::Src &&
15121512 " Should have dest above in memInstMust{Rei,I}nitialize" );
15131513
1514+ auto leafRange = TypeTreeLeafTypeRange::get (op->get (), getRootAddress ());
1515+ if (!leafRange)
1516+ return false ;
1517+
1518+ // If we have a non-move only type, just treat this as a liveness use.
1519+ if (!copyAddr->getSrc ()->getType ().isMoveOnly ()) {
1520+ LLVM_DEBUG (llvm::dbgs ()
1521+ << " Found copy of copyable type. Treating as liveness use! "
1522+ << *user);
1523+ useState.livenessUses .insert ({user, *leafRange});
1524+ return true ;
1525+ }
1526+
15141527 if (markedValue->getCheckKind () ==
15151528 MarkMustCheckInst::CheckKind::NoConsumeOrAssign) {
15161529 LLVM_DEBUG (llvm::dbgs ()
@@ -1520,17 +1533,11 @@ bool GatherUsesVisitor::visitUse(Operand *op) {
15201533 return true ;
15211534 }
15221535
1523- auto leafRange = TypeTreeLeafTypeRange::get (op->get (), getRootAddress ());
1524- if (!leafRange)
1525- return false ;
1526-
15271536 // TODO: Add borrow checking here like below.
15281537
15291538 // TODO: Add destructure deinit checking here once address only checking is
15301539 // completely brought up.
15311540
1532- // TODO: Add check here that we don't error on trivial/copyable types.
1533-
15341541 if (copyAddr->isTakeOfSrc ()) {
15351542 LLVM_DEBUG (llvm::dbgs () << " Found take: " << *user);
15361543 useState.takeInsts .insert ({user, *leafRange});
@@ -1721,9 +1728,30 @@ bool GatherUsesVisitor::visitUse(Operand *op) {
17211728 // Now that we have handled or loadTakeOrCopy, we need to now track our
17221729 // additional pure takes.
17231730 if (::memInstMustConsume (op)) {
1731+ // If we don't have a consumeable and assignable check kind, then we can't
1732+ // consume. Emit an error.
1733+ //
1734+ // NOTE: Since SILGen eagerly loads loadable types from memory, this
1735+ // generally will only handle address only types.
1736+ if (markedValue->getCheckKind () !=
1737+ MarkMustCheckInst::CheckKind::ConsumableAndAssignable) {
1738+ auto *fArg = dyn_cast<SILFunctionArgument>(
1739+ stripAccessMarkers (markedValue->getOperand ()));
1740+ if (fArg && fArg ->isClosureCapture () && fArg ->getType ().isAddress ()) {
1741+ moveChecker.diagnosticEmitter .emitPromotedBoxArgumentError (markedValue,
1742+ fArg );
1743+ } else {
1744+ moveChecker.diagnosticEmitter
1745+ .emitAddressEscapingClosureCaptureLoadedAndConsumed (markedValue);
1746+ }
1747+ emittedEarlyDiagnostic = true ;
1748+ return true ;
1749+ }
1750+
17241751 auto leafRange = TypeTreeLeafTypeRange::get (op->get (), getRootAddress ());
17251752 if (!leafRange)
17261753 return false ;
1754+
17271755 LLVM_DEBUG (llvm::dbgs () << " Pure consuming use: " << *user);
17281756 useState.takeInsts .insert ({user, *leafRange});
17291757 return true ;
@@ -2423,7 +2451,6 @@ bool MoveOnlyAddressCheckerPImpl::performSingleCheck(
24232451 LLVM_DEBUG (llvm::dbgs () << " Failed access path visit: " << *markedAddress);
24242452 return false ;
24252453 }
2426- addressUseState.initializeInOutTermUsers ();
24272454
24282455 // If we found a load [copy] or copy_addr that requires multiple copies or an
24292456 // exclusivity error, then we emitted an early error. Bail now and allow the
@@ -2438,9 +2465,14 @@ bool MoveOnlyAddressCheckerPImpl::performSingleCheck(
24382465 if (diagCount != diagnosticEmitter.getDiagnosticCount ())
24392466 return true ;
24402467
2441- // Then check if we emitted an error. If we did not, return true.
2442- if (diagCount != diagnosticEmitter.getDiagnosticCount ())
2443- return true ;
2468+ // Now that we know that we have run our visitor and did not emit any errors
2469+ // and successfully visited everything, see if have any
2470+ // assignable_but_not_consumable of address only types that are consumed.
2471+ //
2472+ // DISCUSSION: For non address only types, this is not an issue since we
2473+ // eagerly load
2474+
2475+ addressUseState.initializeInOutTermUsers ();
24442476
24452477 // ===---
24462478 // Liveness Checking
0 commit comments