@@ -1289,8 +1289,8 @@ void PatternMatchEmission::bindIrrefutablePatterns(const ClauseRow &row,
12891289
12901290void PatternMatchEmission::bindIrrefutableBorrows (const ClauseRow &row,
12911291 ArgArray args,
1292- bool forIrrefutableRow,
1293- bool hasMultipleItems) {
1292+ bool forIrrefutableRow,
1293+ bool hasMultipleItems) {
12941294 assert (row.columns () == args.size ());
12951295 for (unsigned i = 0 , e = args.size (); i != e; ++i) {
12961296 if (!row[i]) // We use null patterns to mean artificial AnyPatterns
@@ -1446,7 +1446,7 @@ void PatternMatchEmission::bindBorrow(Pattern *pattern, VarDecl *var,
14461446 auto access = SGF.B .createBeginAccess (pattern, bindValue.getValue (),
14471447 SILAccessKind::Read,
14481448 SILAccessEnforcement::Static,
1449- false , false );
1449+ /* no nested conflict */ true , false );
14501450 SGF.Cleanups .pushCleanup <EndAccessCleanup>(access);
14511451 bindValue = ManagedValue::forBorrowedAddressRValue (access);
14521452 }
@@ -2797,11 +2797,23 @@ void PatternMatchEmission::emitDestructiveCaseBlocks() {
27972797 // Create a scope to break down the subject value.
27982798 Scope caseScope (SGF, pattern);
27992799
2800+ // If the subject value is in memory, enter a deinit access for the memory.
2801+ // This saves the move-only-checker from trying to analyze the payload
2802+ // decomposition as a potential partial consume. We always fully consume
2803+ // the subject on this path.
2804+ auto origSubject = NoncopyableConsumableValue.forward (SGF);
2805+ if (origSubject->getType ().isAddress ()) {
2806+ origSubject = SGF.B .createBeginAccess (pattern, origSubject,
2807+ SILAccessKind::Deinit,
2808+ SILAccessEnforcement::Static,
2809+ /* no nested conflict*/ true , false );
2810+ SGF.Cleanups .pushCleanup <EndAccessCleanup>(origSubject);
2811+ }
2812+
28002813 // Clone the original subject's cleanup state so that it will be reliably
28012814 // consumed in this scope, while leaving the original for other case
28022815 // blocks to re-consume.
2803- ManagedValue subject = SGF.emitManagedRValueWithCleanup (
2804- NoncopyableConsumableValue.forward (SGF));
2816+ ManagedValue subject = SGF.emitManagedRValueWithCleanup (origSubject);
28052817
28062818 // TODO: handle fallthroughs and multiple cases bindings
28072819 // In those cases we'd need to forward bindings through the shared case
@@ -3428,7 +3440,8 @@ void SILGenFunction::emitSwitchStmt(SwitchStmt *S) {
34283440 // match is not allowed to modify it.
34293441 auto access = B.createBeginAccess (S, subjectMV.getValue (),
34303442 SILAccessKind::Read,
3431- SILAccessEnforcement::Static, false , false );
3443+ SILAccessEnforcement::Static,
3444+ /* no nested conflict*/ true , false );
34323445 Cleanups.pushCleanup <EndAccessCleanup>(access);
34333446 subjectMV = ManagedValue::forBorrowedAddressRValue (access);
34343447 }
0 commit comments