@@ -1654,8 +1654,8 @@ struct CopiedLoadBorrowEliminationVisitor
1654
1654
1655
1655
// / Whether an error should be emitted in response to a partial consumption.
1656
1656
static llvm::Optional<PartialMutationError>
1657
- shouldEmitPartialMutationError (UseState &useState, SILInstruction *user ,
1658
- SILType useType,
1657
+ shouldEmitPartialMutationError (UseState &useState, PartialMutation::Kind kind ,
1658
+ SILInstruction *user, SILType useType,
1659
1659
TypeTreeLeafTypeRange usedBits) {
1660
1660
SILFunction *fn = useState.getFunction ();
1661
1661
@@ -1672,18 +1672,19 @@ shouldEmitPartialMutationError(UseState &useState, SILInstruction *user,
1672
1672
LLVM_DEBUG (llvm::dbgs () << " Iter Type: " << iterType << ' \n '
1673
1673
<< " Target Type: " << targetType << ' \n ' );
1674
1674
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
+ }
1684
1680
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.
1685
1686
// Emit the error.
1686
- return {PartialMutationError::featureDisabled (iterType)};
1687
+ return {PartialMutationError::featureDisabled (iterType, kind )};
1687
1688
}
1688
1689
1689
1690
LLVM_DEBUG (llvm::dbgs () << " MoveOnlyPartialConsumption enabled!\n " );
@@ -1715,13 +1716,14 @@ shouldEmitPartialMutationError(UseState &useState, SILInstruction *user,
1715
1716
1716
1717
static bool checkForPartialMutation (UseState &useState,
1717
1718
DiagnosticEmitter &diagnosticEmitter,
1719
+ PartialMutation::Kind kind,
1718
1720
SILInstruction *user, SILType useType,
1719
1721
TypeTreeLeafTypeRange usedBits,
1720
1722
PartialMutation partialMutateKind) {
1721
1723
// We walk down from our ancestor to our projection, emitting an error if
1722
1724
// any of our types have a deinit.
1723
1725
auto error =
1724
- shouldEmitPartialMutationError (useState, user, useType, usedBits);
1726
+ shouldEmitPartialMutationError (useState, kind, user, useType, usedBits);
1725
1727
if (!error)
1726
1728
return false ;
1727
1729
@@ -1762,8 +1764,9 @@ void PartialReinitChecker::performPartialReinitChecking(
1762
1764
initToValues.first , index,
1763
1765
[&](SILInstruction *consumingInst) -> bool {
1764
1766
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 ),
1767
1770
PartialMutation::reinit (*consumingInst));
1768
1771
});
1769
1772
@@ -1797,8 +1800,9 @@ void PartialReinitChecker::performPartialReinitChecking(
1797
1800
reinitToValues.first , index,
1798
1801
[&](SILInstruction *consumingInst) -> bool {
1799
1802
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 ),
1802
1806
PartialMutation::reinit (*consumingInst));
1803
1807
});
1804
1808
if (emittedError)
@@ -2028,7 +2032,8 @@ bool GatherUsesVisitor::visitUse(Operand *op) {
2028
2032
// If we have a copy_addr, we are either going to have a take or a
2029
2033
// copy... in either case, this copy_addr /is/ going to be a consuming
2030
2034
// 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 (),
2032
2037
op->get ()->getType (), *leafRange,
2033
2038
PartialMutation::consume ());
2034
2039
@@ -2223,7 +2228,8 @@ bool GatherUsesVisitor::visitUse(Operand *op) {
2223
2228
} else {
2224
2229
// Now that we know that we are going to perform a take, perform a
2225
2230
// checkForDestructure.
2226
- checkForPartialMutation (useState, diagnosticEmitter, op->getUser (),
2231
+ checkForPartialMutation (useState, diagnosticEmitter,
2232
+ PartialMutation::Kind::Consume, op->getUser (),
2227
2233
op->get ()->getType (), *leafRange,
2228
2234
PartialMutation::consume ());
2229
2235
@@ -2280,7 +2286,8 @@ bool GatherUsesVisitor::visitUse(Operand *op) {
2280
2286
// error.
2281
2287
unsigned numDiagnostics =
2282
2288
moveChecker.diagnosticEmitter .getDiagnosticCount ();
2283
- checkForPartialMutation (useState, diagnosticEmitter, op->getUser (),
2289
+ checkForPartialMutation (useState, diagnosticEmitter,
2290
+ PartialMutation::Kind::Consume, op->getUser (),
2284
2291
op->get ()->getType (), *leafRange,
2285
2292
PartialMutation::consume ());
2286
2293
if (numDiagnostics != moveChecker.diagnosticEmitter .getDiagnosticCount ()) {
0 commit comments