Skip to content

Commit 973c672

Browse files
committed
Fix synthesis of get/set protocol constraints when borrow/mutate accessors are present
1 parent f44d7e5 commit 973c672

File tree

4 files changed

+507
-22
lines changed

4 files changed

+507
-22
lines changed

lib/AST/Decl.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3264,6 +3264,10 @@ static AccessStrategy getOpaqueReadAccessStrategy(
32643264
return AccessStrategy::getAccessor(AccessorKind::Read2, dispatch);
32653265
if (storage->requiresOpaqueReadCoroutine())
32663266
return AccessStrategy::getAccessor(AccessorKind::Read, dispatch);
3267+
3268+
if (storage->getParsedAccessor(AccessorKind::Borrow)) {
3269+
return AccessStrategy::getAccessor(AccessorKind::Borrow, dispatch);
3270+
}
32673271
return AccessStrategy::getAccessor(AccessorKind::Get, dispatch);
32683272
}
32693273

@@ -3435,11 +3439,6 @@ bool AbstractStorageDecl::requiresOpaqueSetter() const {
34353439
if (!supportsMutation()) {
34363440
return false;
34373441
}
3438-
3439-
// If a mutate accessor is present, we don't need a setter.
3440-
if (getAccessor(AccessorKind::Mutate)) {
3441-
return false;
3442-
}
34433442
return true;
34443443
}
34453444

@@ -3450,7 +3449,7 @@ bool AbstractStorageDecl::requiresOpaqueReadCoroutine() const {
34503449
AccessorKind::Read2);
34513450

34523451
// If a borrow accessor is present, we don't need a read coroutine.
3453-
if (getAccessor(AccessorKind::Borrow)) {
3452+
if (getParsedAccessor(AccessorKind::Borrow)) {
34543453
return false;
34553454
}
34563455
return getOpaqueReadOwnership() != OpaqueReadOwnership::Owned;
@@ -3462,7 +3461,7 @@ bool AbstractStorageDecl::requiresOpaqueRead2Coroutine() const {
34623461
return false;
34633462

34643463
// If a borrow accessor is present, we don't need a read coroutine.
3465-
if (getAccessor(AccessorKind::Borrow)) {
3464+
if (getParsedAccessor(AccessorKind::Borrow)) {
34663465
return false;
34673466
}
34683467
return getOpaqueReadOwnership() != OpaqueReadOwnership::Owned;

lib/Sema/TypeCheckStorage.cpp

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1875,6 +1875,13 @@ synthesizeModify2CoroutineSetterBody(AccessorDecl *setter, ASTContext &ctx) {
18751875
setter, TargetImpl::Implementation, setter->getStorage(), ctx);
18761876
}
18771877

1878+
static std::pair<BraceStmt *, bool>
1879+
synthesizeMutateSetterBody(AccessorDecl *setter, ASTContext &ctx) {
1880+
// This should call the mutate accessor.
1881+
return synthesizeTrivialSetterBodyWithStorage(
1882+
setter, TargetImpl::Implementation, setter->getStorage(), ctx);
1883+
}
1884+
18781885
static Expr *maybeWrapInOutExpr(Expr *expr, ASTContext &ctx) {
18791886
if (auto lvalueType = expr->getType()->getAs<LValueType>()) {
18801887
auto type = lvalueType->getObjectType();
@@ -2071,7 +2078,7 @@ synthesizeSetterBody(AccessorDecl *setter, ASTContext &ctx) {
20712078
return synthesizeModify2CoroutineSetterBody(setter, ctx);
20722079

20732080
case WriteImplKind::Mutate:
2074-
llvm_unreachable("synthesizing setter from mutate");
2081+
return synthesizeMutateSetterBody(setter, ctx);
20752082
}
20762083
llvm_unreachable("bad WriteImplKind");
20772084
}
@@ -2476,7 +2483,9 @@ static AccessorDecl *createSetterPrototype(AbstractStorageDecl *storage,
24762483
}
24772484
break;
24782485
case WriteImplKind::Mutate:
2479-
llvm_unreachable("mutate accessor is not yet implemented");
2486+
if (auto mutate = storage->getOpaqueAccessor(AccessorKind::Mutate)) {
2487+
asAvailableAs.push_back(mutate);
2488+
}
24802489
}
24812490

24822491
if (!asAvailableAs.empty()) {
@@ -2804,11 +2813,6 @@ bool RequiresOpaqueModifyCoroutineRequest::evaluate(
28042813
if (protoDecl->isObjC())
28052814
return false;
28062815

2807-
// If a mutate accessor is present, we don't need a modify coroutine
2808-
if (storage->getAccessor(AccessorKind::Mutate)) {
2809-
return false;
2810-
}
2811-
28122816
return true;
28132817
}
28142818

@@ -2937,9 +2941,8 @@ IsAccessorTransparentRequest::evaluate(Evaluator &evaluator,
29372941
case WriteImplKind::MutableAddress:
29382942
case WriteImplKind::Modify:
29392943
case WriteImplKind::Modify2:
2940-
break;
29412944
case WriteImplKind::Mutate:
2942-
llvm_unreachable("mutate accessor is not yet implemented");
2945+
break;
29432946
}
29442947
break;
29452948

@@ -2950,14 +2953,12 @@ IsAccessorTransparentRequest::evaluate(Evaluator &evaluator,
29502953
case AccessorKind::Init:
29512954
break;
29522955
case AccessorKind::Borrow:
2953-
llvm_unreachable("borrow accessor is not yet implemented");
29542956
case AccessorKind::WillSet:
29552957
case AccessorKind::DidSet:
29562958
case AccessorKind::Address:
29572959
case AccessorKind::MutableAddress:
2958-
llvm_unreachable("bad synthesized function kind");
29592960
case AccessorKind::Mutate:
2960-
llvm_unreachable("mutate accessor is not yet implemented");
2961+
llvm_unreachable("bad synthesized function kind");
29612962
}
29622963

29632964
switch (storage->getReadWriteImpl()) {

test/Parse/borrow_and_mutate_accessors.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,23 @@ struct Wrapper {
1515
}
1616
}
1717
var k2: Klass {
18-
borrow { // expected-error{{variable cannot provide both a 'borrow' accessor and a getter}}
18+
borrow { // expected-error{{variable cannot provide both a 'borrow' accessor and a getter}}
1919
return _k
2020
}
2121
get { // expected-note{{getter defined here}}
2222
return _k
2323
}
2424
}
2525
var k3: Klass {
26-
borrow { // expected-error{{variable cannot provide both a 'borrow' accessor and a '_read' accessor}}
26+
borrow { // expected-error{{variable cannot provide both a 'borrow' accessor and a '_read' accessor}}
2727
return _k
2828
}
2929
_read { // expected-note{{'_read' accessor defined here}}
3030
yield _k
3131
}
3232
}
3333
var k4: Klass {
34-
borrow { // expected-error{{variable cannot provide both a 'borrow' accessor and a 'read' accessor}}
34+
borrow { // expected-error{{variable cannot provide both a 'borrow' accessor and a 'read' accessor}}
3535
return _k
3636
}
3737
read { // expected-note{{'read' accessor defined here}}

0 commit comments

Comments
 (0)