@@ -230,7 +230,7 @@ class GettablePropertyProjector : public ComponentProjector {
230
230
auto addr = builder.createAllocStack (loc, type);
231
231
232
232
assertHasNoContext ();
233
- assert (getter->getArguments ().size () == 2 );
233
+ assert (getter->getConventions ().getNumSILArguments () );
234
234
235
235
auto ref = builder.createFunctionRef (loc, getter);
236
236
builder.createApply (loc, ref, subs, {addr, parentValue});
@@ -308,8 +308,8 @@ class SettablePropertyProjector : public GettablePropertyProjector {
308
308
auto addr = builder.createAllocStack (loc, type);
309
309
310
310
assertHasNoContext ();
311
- assert (getter->getArguments ().size () == 2 );
312
- assert (setter->getArguments ().size () == 2 );
311
+ assert (getter->getConventions ().getNumSILArguments () );
312
+ assert (setter->getConventions ().getNumSILArguments () );
313
313
314
314
// If this is a modify, we need to call the getter and
315
315
// store the result in the writeback buffer.
@@ -468,10 +468,11 @@ class OptionalChainProjector : public ComponentProjector {
468
468
public:
469
469
OptionalChainProjector (const KeyPathPatternComponent &component,
470
470
std::unique_ptr<KeyPathProjector> parent,
471
+ BeginAccessInst *&beginAccess,
471
472
SILValue optionalChainResult,
472
473
SILLocation loc, SILBuilder &builder)
473
474
: ComponentProjector(component, std::move(parent), loc, builder),
474
- optionalChainResult (optionalChainResult) {}
475
+ optionalChainResult (optionalChainResult), beginAccess(beginAccess) {}
475
476
476
477
void project (AccessType accessType,
477
478
std::function<void (SILValue addr)> callback) override {
@@ -506,6 +507,7 @@ class OptionalChainProjector : public ComponentProjector {
506
507
507
508
// Unwrap the optional.
508
509
auto objAddr = builder.createUncheckedTakeEnumDataAddr (loc, tempAddr, someDecl, objType);
510
+ BeginAccessInst *origBeginAccess = beginAccess;
509
511
510
512
// at the end of the projection, callback will store a value in optionalChainResult
511
513
callback (objAddr);
@@ -516,6 +518,12 @@ class OptionalChainProjector : public ComponentProjector {
516
518
builder.createBranch (loc, continuation);
517
519
// else, store nil in the result
518
520
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
+
519
527
builder.createInjectEnumAddr (loc, optionalChainResult, noneDecl);
520
528
521
529
builder.createBranch (loc, continuation);
@@ -526,6 +534,7 @@ class OptionalChainProjector : public ComponentProjector {
526
534
527
535
private:
528
536
SILValue optionalChainResult;
537
+ BeginAccessInst *&beginAccess;
529
538
};
530
539
531
540
// / A projector to handle a complete key path.
@@ -646,7 +655,8 @@ class CompleteKeyPathProjector : public KeyPathProjector {
646
655
break ;
647
656
case KeyPathPatternComponent::Kind::OptionalChain:
648
657
projector = std::make_unique<OptionalChainProjector>
649
- (comp, std::move (parent), optionalChainResult, loc, builder);
658
+ (comp, std::move (parent), beginAccess, optionalChainResult, loc,
659
+ builder);
650
660
break ;
651
661
}
652
662
0 commit comments