@@ -3425,26 +3425,29 @@ void SILGenFunction::emitSwitchStmt(SwitchStmt *S) {
34253425
34263426 case ValueOwnership::Shared:
34273427 emission.setNoncopyableBorrowingOwnership ();
3428- if (!subjectMV.isPlusZero ()) {
3429- subjectMV = subjectMV.borrow (*this , S);
3430- }
34313428 if (subjectMV.getType ().isAddress ()) {
3429+ // Initiate a read access on the memory, to ensure that even
3430+ // if the underlying memory is mutable or consumable, the pattern
3431+ // match is not allowed to modify it.
3432+ auto access = B.createBeginAccess (S, subjectMV.getValue (),
3433+ SILAccessKind::Read,
3434+ SILAccessEnforcement::Static,
3435+ /* no nested conflict*/ true , false );
3436+ Cleanups.pushCleanup <EndAccessCleanup>(access);
3437+ subjectMV = ManagedValue::forBorrowedAddressRValue (access);
34323438 if (subjectMV.getType ().isLoadable (F)) {
34333439 // Load a borrow if the type is loadable.
34343440 subjectMV = subjectUndergoesFormalAccess
34353441 ? B.createFormalAccessLoadBorrow (S, subjectMV)
34363442 : B.createLoadBorrow (S, subjectMV);
3437- } else {
3438- // Initiate a read access on the memory, to ensure that even
3439- // if the underlying memory is mutable or consumable, the pattern
3440- // match is not allowed to modify it.
3441- auto access = B.createBeginAccess (S, subjectMV.getValue (),
3442- SILAccessKind::Read,
3443- SILAccessEnforcement::Static,
3444- /* no nested conflict*/ true , false );
3445- Cleanups.pushCleanup <EndAccessCleanup>(access);
3446- subjectMV = ManagedValue::forBorrowedAddressRValue (access);
34473443 }
3444+ } else {
3445+ // Initiate a fixed borrow on the subject, so that it's treated as
3446+ // opaque by the move checker.
3447+ subjectMV = subjectUndergoesFormalAccess
3448+ ? B.createFormalAccessBeginBorrow (S, subjectMV,
3449+ false , /* fixed*/ true )
3450+ : B.createBeginBorrow (S, subjectMV, false , /* fixed*/ true );
34483451 }
34493452 return {subjectMV, CastConsumptionKind::BorrowAlways};
34503453
@@ -3467,8 +3470,19 @@ void SILGenFunction::emitSwitchStmt(SwitchStmt *S) {
34673470 Cleanups.getCleanupsDepth (),
34683471 subjectMV);
34693472
3470- // Perform the pattern match on a borrow of the subject.
3471- subjectMV = subjectMV.borrow (*this , S);
3473+ // Perform the pattern match on an opaque borrow or read access of the
3474+ // subject.
3475+ if (subjectMV.getType ().isAddress ()) {
3476+ auto access = B.createBeginAccess (S, subjectMV.getValue (),
3477+ SILAccessKind::Read,
3478+ SILAccessEnforcement::Static,
3479+ /* no nested conflict*/ true , false );
3480+ Cleanups.pushCleanup <EndAccessCleanup>(access);
3481+ subjectMV = ManagedValue::forBorrowedAddressRValue (access);
3482+ } else {
3483+ subjectMV = B.createBeginBorrow (S, subjectMV,
3484+ false , /* fixed*/ true );
3485+ }
34723486 return {subjectMV, CastConsumptionKind::BorrowAlways};
34733487 }
34743488 llvm_unreachable (" unhandled value ownership" );
0 commit comments