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