@@ -634,7 +634,8 @@ static SILValue enterAccessScope(SILGenFunction &SGF, SILLocation loc,
634634 LValueTypeData typeData,
635635 SGFAccessKind accessKind,
636636 SILAccessEnforcement enforcement,
637- std::optional<ActorIsolation> actorIso) {
637+ std::optional<ActorIsolation> actorIso,
638+ bool noNestedConflict = false ) {
638639 auto silAccessKind = SILAccessKind::Modify;
639640 if (isReadAccess (accessKind))
640641 silAccessKind = SILAccessKind::Read;
@@ -649,7 +650,7 @@ static SILValue enterAccessScope(SILGenFunction &SGF, SILLocation loc,
649650
650651 // Enter the access.
651652 addr = SGF.B .createBeginAccess (loc, addr, silAccessKind, enforcement,
652- /* hasNoNestedConflict= */ false ,
653+ noNestedConflict ,
653654 /* fromBuiltin=*/ false );
654655
655656 // Push a writeback to end it.
@@ -667,10 +668,11 @@ static ManagedValue enterAccessScope(SILGenFunction &SGF, SILLocation loc,
667668 LValueTypeData typeData,
668669 SGFAccessKind accessKind,
669670 SILAccessEnforcement enforcement,
670- std::optional<ActorIsolation> actorIso) {
671+ std::optional<ActorIsolation> actorIso,
672+ bool noNestedConflict = false ) {
671673 return ManagedValue::forLValue (
672- enterAccessScope (SGF, loc, base, addr.getLValueAddress (), typeData,
673- accessKind, enforcement, actorIso));
674+ enterAccessScope (SGF, loc, base, addr.getValue (), typeData,
675+ accessKind, enforcement, actorIso, noNestedConflict ));
674676}
675677
676678// Find the base of the formal access at `address`. If the base requires an
@@ -4373,22 +4375,27 @@ LValue SILGenLValue::visitBindOptionalExpr(BindOptionalExpr *e,
43734375 // Do formal evaluation of the base l-value.
43744376 LValue optLV = visitRec (e->getSubExpr (), baseAccessKind,
43754377 options.forComputedBaseLValue ());
4376-
4378+ // For move-checking purposes, the binding is also treated as an opaque use
4379+ // of the entire value, since we can't leave the value partially initialized
4380+ // across multiple optional binding expressions.
43774381 LValueTypeData optTypeData = optLV.getTypeData ();
43784382 LValueTypeData valueTypeData =
43794383 getOptionalObjectTypeData (SGF, accessKind, optTypeData);
43804384
43814385 // The chaining operator immediately evaluates the base.
4382- // For move-checking purposes, the binding is also treated as an opaque use
4383- // of the entire value, since we can't leave the value partially initialized
4384- // across multiple optional binding expressions.
4386+
43854387 ManagedValue optBase;
43864388 if (isBorrowAccess (baseAccessKind)) {
43874389 optBase = SGF.emitBorrowedLValue (e, std::move (optLV));
43884390
43894391 if (optBase.getType ().isMoveOnly ()) {
43904392 if (optBase.getType ().isAddress ()) {
4391- optBase = SGF.B .createFormalAccessOpaqueBorrowBeginAccess (e, optBase);
4393+ optBase = enterAccessScope (SGF, e, ManagedValue (),
4394+ optBase, optTypeData,
4395+ baseAccessKind,
4396+ SILAccessEnforcement::Static,
4397+ std::nullopt ,
4398+ /* no nested conflict*/ true );
43924399 if (optBase.getType ().isLoadable (SGF.F )) {
43934400 optBase = SGF.B .createFormalAccessLoadBorrow (e, optBase);
43944401 }
@@ -4400,9 +4407,14 @@ LValue SILGenLValue::visitBindOptionalExpr(BindOptionalExpr *e,
44004407 } else {
44014408 optBase = SGF.emitAddressOfLValue (e, std::move (optLV));
44024409
4403- if (isConsumeAccess (accessKind )) {
4410+ if (isConsumeAccess (baseAccessKind )) {
44044411 if (optBase.getType ().isMoveOnly ()) {
4405- optBase = SGF.B .createFormalAccessOpaqueConsumeBeginAccess (e, optBase);
4412+ optBase = enterAccessScope (SGF, e, ManagedValue (),
4413+ optBase, optTypeData,
4414+ baseAccessKind,
4415+ SILAccessEnforcement::Static,
4416+ std::nullopt ,
4417+ /* no nested conflict*/ true );
44064418 } else {
44074419 // Take ownership of the base.
44084420 optBase = SGF.emitFormalAccessManagedRValueWithCleanup (e,
0 commit comments