@@ -1654,8 +1654,8 @@ struct CopiedLoadBorrowEliminationVisitor
16541654
16551655// / Whether an error should be emitted in response to a partial consumption.
16561656static llvm::Optional<PartialMutationError>
1657- shouldEmitPartialMutationError (UseState &useState, SILInstruction *user ,
1658- SILType useType,
1657+ shouldEmitPartialMutationError (UseState &useState, PartialMutation::Kind kind ,
1658+ SILInstruction *user, SILType useType,
16591659 TypeTreeLeafTypeRange usedBits) {
16601660 SILFunction *fn = useState.getFunction ();
16611661
@@ -1672,18 +1672,19 @@ shouldEmitPartialMutationError(UseState &useState, SILInstruction *user,
16721672 LLVM_DEBUG (llvm::dbgs () << " Iter Type: " << iterType << ' \n '
16731673 << " Target Type: " << targetType << ' \n ' );
16741674
1675- if (!fn->getModule ().getASTContext ().LangOpts .hasFeature (
1676- Feature::MoveOnlyPartialConsumption)) {
1677- LLVM_DEBUG (llvm::dbgs () << " MoveOnlyPartialConsumption disabled!\n " );
1678- // If the types equal, just bail early.
1679- if (iterType == targetType) {
1680- LLVM_DEBUG (llvm::dbgs () << " IterType is TargetType! Exiting early "
1681- " without emitting error!\n " );
1682- return {};
1683- }
1675+ if (iterType == targetType) {
1676+ LLVM_DEBUG (llvm::dbgs () << " IterType is TargetType! Exiting early "
1677+ " without emitting error!\n " );
1678+ return {};
1679+ }
16841680
1681+ auto feature = partialMutationFeature (kind);
1682+ if (!fn->getModule ().getASTContext ().LangOpts .hasFeature (feature)) {
1683+ LLVM_DEBUG (llvm::dbgs ()
1684+ << " " << getFeatureName (feature) << " disabled!\n " );
1685+ // If the types equal, just bail early.
16851686 // Emit the error.
1686- return {PartialMutationError::featureDisabled (iterType)};
1687+ return {PartialMutationError::featureDisabled (iterType, kind )};
16871688 }
16881689
16891690 LLVM_DEBUG (llvm::dbgs () << " MoveOnlyPartialConsumption enabled!\n " );
@@ -1715,13 +1716,14 @@ shouldEmitPartialMutationError(UseState &useState, SILInstruction *user,
17151716
17161717static bool checkForPartialMutation (UseState &useState,
17171718 DiagnosticEmitter &diagnosticEmitter,
1719+ PartialMutation::Kind kind,
17181720 SILInstruction *user, SILType useType,
17191721 TypeTreeLeafTypeRange usedBits,
17201722 PartialMutation partialMutateKind) {
17211723 // We walk down from our ancestor to our projection, emitting an error if
17221724 // any of our types have a deinit.
17231725 auto error =
1724- shouldEmitPartialMutationError (useState, user, useType, usedBits);
1726+ shouldEmitPartialMutationError (useState, kind, user, useType, usedBits);
17251727 if (!error)
17261728 return false ;
17271729
@@ -1762,8 +1764,9 @@ void PartialReinitChecker::performPartialReinitChecking(
17621764 initToValues.first , index,
17631765 [&](SILInstruction *consumingInst) -> bool {
17641766 return !checkForPartialMutation (
1765- useState, diagnosticEmitter, initToValues.first ,
1766- value->getType (), TypeTreeLeafTypeRange (index, index + 1 ),
1767+ useState, diagnosticEmitter, PartialMutation::Kind::Reinit,
1768+ initToValues.first , value->getType (),
1769+ TypeTreeLeafTypeRange (index, index + 1 ),
17671770 PartialMutation::reinit (*consumingInst));
17681771 });
17691772
@@ -1797,8 +1800,9 @@ void PartialReinitChecker::performPartialReinitChecking(
17971800 reinitToValues.first , index,
17981801 [&](SILInstruction *consumingInst) -> bool {
17991802 return !checkForPartialMutation (
1800- useState, diagnosticEmitter, reinitToValues.first ,
1801- value->getType (), TypeTreeLeafTypeRange (index, index + 1 ),
1803+ useState, diagnosticEmitter, PartialMutation::Kind::Reinit,
1804+ reinitToValues.first , value->getType (),
1805+ TypeTreeLeafTypeRange (index, index + 1 ),
18021806 PartialMutation::reinit (*consumingInst));
18031807 });
18041808 if (emittedError)
@@ -2028,7 +2032,8 @@ bool GatherUsesVisitor::visitUse(Operand *op) {
20282032 // If we have a copy_addr, we are either going to have a take or a
20292033 // copy... in either case, this copy_addr /is/ going to be a consuming
20302034 // operation. Make sure to check if we semantically destructure.
2031- checkForPartialMutation (useState, diagnosticEmitter, op->getUser (),
2035+ checkForPartialMutation (useState, diagnosticEmitter,
2036+ PartialMutation::Kind::Consume, op->getUser (),
20322037 op->get ()->getType (), *leafRange,
20332038 PartialMutation::consume ());
20342039
@@ -2223,7 +2228,8 @@ bool GatherUsesVisitor::visitUse(Operand *op) {
22232228 } else {
22242229 // Now that we know that we are going to perform a take, perform a
22252230 // checkForDestructure.
2226- checkForPartialMutation (useState, diagnosticEmitter, op->getUser (),
2231+ checkForPartialMutation (useState, diagnosticEmitter,
2232+ PartialMutation::Kind::Consume, op->getUser (),
22272233 op->get ()->getType (), *leafRange,
22282234 PartialMutation::consume ());
22292235
@@ -2280,7 +2286,8 @@ bool GatherUsesVisitor::visitUse(Operand *op) {
22802286 // error.
22812287 unsigned numDiagnostics =
22822288 moveChecker.diagnosticEmitter .getDiagnosticCount ();
2283- checkForPartialMutation (useState, diagnosticEmitter, op->getUser (),
2289+ checkForPartialMutation (useState, diagnosticEmitter,
2290+ PartialMutation::Kind::Consume, op->getUser (),
22842291 op->get ()->getType (), *leafRange,
22852292 PartialMutation::consume ());
22862293 if (numDiagnostics != moveChecker.diagnosticEmitter .getDiagnosticCount ()) {
0 commit comments