@@ -3424,26 +3424,29 @@ void SILGenFunction::emitSwitchStmt(SwitchStmt *S) {
3424
3424
3425
3425
case ValueOwnership::Shared:
3426
3426
emission.setNoncopyableBorrowingOwnership ();
3427
- if (!subjectMV.isPlusZero ()) {
3428
- subjectMV = subjectMV.borrow (*this , S);
3429
- }
3430
3427
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 );
3431
3437
if (subjectMV.getType ().isLoadable (F)) {
3432
3438
// Load a borrow if the type is loadable.
3433
3439
subjectMV = subjectUndergoesFormalAccess
3434
3440
? B.createFormalAccessLoadBorrow (S, subjectMV)
3435
3441
: 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 );
3446
3442
}
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 );
3447
3450
}
3448
3451
return {subjectMV, CastConsumptionKind::BorrowAlways};
3449
3452
@@ -3466,8 +3469,19 @@ void SILGenFunction::emitSwitchStmt(SwitchStmt *S) {
3466
3469
Cleanups.getCleanupsDepth (),
3467
3470
subjectMV);
3468
3471
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
+ }
3471
3485
return {subjectMV, CastConsumptionKind::BorrowAlways};
3472
3486
}
3473
3487
llvm_unreachable (" unhandled value ownership" );
0 commit comments