@@ -230,7 +230,7 @@ class GettablePropertyProjector : public ComponentProjector {
230230 auto addr = builder.createAllocStack (loc, type);
231231
232232 assertHasNoContext ();
233- assert (getter->getArguments ().size () == 2 );
233+ assert (getter->getConventions ().getNumSILArguments () );
234234
235235 auto ref = builder.createFunctionRef (loc, getter);
236236 builder.createApply (loc, ref, subs, {addr, parentValue});
@@ -308,8 +308,8 @@ class SettablePropertyProjector : public GettablePropertyProjector {
308308 auto addr = builder.createAllocStack (loc, type);
309309
310310 assertHasNoContext ();
311- assert (getter->getArguments ().size () == 2 );
312- assert (setter->getArguments ().size () == 2 );
311+ assert (getter->getConventions ().getNumSILArguments () );
312+ assert (setter->getConventions ().getNumSILArguments () );
313313
314314 // If this is a modify, we need to call the getter and
315315 // store the result in the writeback buffer.
@@ -468,10 +468,11 @@ class OptionalChainProjector : public ComponentProjector {
468468public:
469469 OptionalChainProjector (const KeyPathPatternComponent &component,
470470 std::unique_ptr<KeyPathProjector> parent,
471+ BeginAccessInst *&beginAccess,
471472 SILValue optionalChainResult,
472473 SILLocation loc, SILBuilder &builder)
473474 : ComponentProjector(component, std::move(parent), loc, builder),
474- optionalChainResult (optionalChainResult) {}
475+ optionalChainResult (optionalChainResult), beginAccess(beginAccess) {}
475476
476477 void project (AccessType accessType,
477478 std::function<void (SILValue addr)> callback) override {
@@ -506,6 +507,7 @@ class OptionalChainProjector : public ComponentProjector {
506507
507508 // Unwrap the optional.
508509 auto objAddr = builder.createUncheckedTakeEnumDataAddr (loc, tempAddr, someDecl, objType);
510+ BeginAccessInst *origBeginAccess = beginAccess;
509511
510512 // at the end of the projection, callback will store a value in optionalChainResult
511513 callback (objAddr);
@@ -516,6 +518,12 @@ class OptionalChainProjector : public ComponentProjector {
516518 builder.createBranch (loc, continuation);
517519 // else, store nil in the result
518520 builder.setInsertionPoint (ifNone);
521+
522+ // If the sub-projection ended the access in the some-branch, we also
523+ // have to end the access in the none-branch.
524+ if (origBeginAccess && origBeginAccess != beginAccess)
525+ builder.createEndAccess (loc, origBeginAccess, /* aborted*/ false );
526+
519527 builder.createInjectEnumAddr (loc, optionalChainResult, noneDecl);
520528
521529 builder.createBranch (loc, continuation);
@@ -526,6 +534,7 @@ class OptionalChainProjector : public ComponentProjector {
526534
527535private:
528536 SILValue optionalChainResult;
537+ BeginAccessInst *&beginAccess;
529538};
530539
531540// / A projector to handle a complete key path.
@@ -646,7 +655,8 @@ class CompleteKeyPathProjector : public KeyPathProjector {
646655 break ;
647656 case KeyPathPatternComponent::Kind::OptionalChain:
648657 projector = std::make_unique<OptionalChainProjector>
649- (comp, std::move (parent), optionalChainResult, loc, builder);
658+ (comp, std::move (parent), beginAccess, optionalChainResult, loc,
659+ builder);
650660 break ;
651661 }
652662
0 commit comments