Skip to content

Commit 527c67a

Browse files
committed
[CoroutineAccessors] Added modify.
The name is a placeholder for the mutating single-yield coroutine accessor.
1 parent c14e920 commit 527c67a

40 files changed

+359
-7
lines changed

docs/ABI/Mangling.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,11 +387,12 @@ Entities
387387
ACCESSOR ::= 'G' // global getter
388388
ACCESSOR ::= 'w' // willSet
389389
ACCESSOR ::= 'W' // didSet
390-
ACCESSOR ::= 'r' // read
391-
ACCESSOR ::= 'M' // modify (temporary)
390+
ACCESSOR ::= 'r' // _read
391+
ACCESSOR ::= 'M' // _modify (temporary)
392392
ACCESSOR ::= 'a' ADDRESSOR-KIND // mutable addressor
393393
ACCESSOR ::= 'l' ADDRESSOR-KIND // non-mutable addressor
394394
ACCESSOR ::= 'p' // pseudo accessor referring to the storage itself
395+
ACCESSOR ::= 'x' // modify
395396

396397
ADDRESSOR-KIND ::= 'u' // unsafe addressor (no owner)
397398
ADDRESSOR-KIND ::= 'O' // owning addressor (non-native owner), not used anymore

include/swift/ABI/MetadataValues.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ class MethodDescriptorFlags {
350350
Setter,
351351
ModifyCoroutine,
352352
ReadCoroutine,
353+
Modify2Coroutine,
353354
};
354355

355356
private:
@@ -572,6 +573,7 @@ class ProtocolRequirementFlags {
572573
ModifyCoroutine,
573574
AssociatedTypeAccessFunction,
574575
AssociatedConformanceAccessFunction,
576+
Modify2Coroutine,
575577
};
576578

577579
private:

include/swift/AST/AccessorKinds.def

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,14 @@ COROUTINE_ACCESSOR(Read, _read)
161161
/// one can be synthesized if the storage is mutable at all.
162162
COROUTINE_ACCESSOR(Modify, _modify)
163163

164+
/// This is a modify accessor: a yield-once coroutine which is called when a
165+
/// the storage is modified which works by yielding an inout value
166+
/// of the storage type.
167+
///
168+
/// If the storage is not implemented with a modify accessor then
169+
/// one can be synthesized if the storage is mutable at all.
170+
EXPERIMENTAL_COROUTINE_ACCESSOR(Modify2, modify, CoroutineAccessors)
171+
164172
/// This is a willSet observer: a function which "decorates" an
165173
/// underlying assignment operation by being called prior to the
166174
/// operation when a value is assigned to the storage.

include/swift/AST/DiagnosticsParse.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,9 @@ ERROR(observing_accessor_in_subscript,none,
305305
"%select{'willSet'|'didSet'}0 is not allowed in subscripts", (unsigned))
306306
ERROR(getset_cannot_be_implied,none,
307307
"variable with implied type cannot have implied getter/setter", ())
308+
ERROR(accessor_requires_coroutine_accessors,none,
309+
"%0 is only valid when experimental feature coroutine accessors is enabled",
310+
(StringRef))
308311

309312
// Import
310313
ERROR(decl_expected_module_name,none,

include/swift/AST/StorageImpl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ enum class AccessorKind {
5151

5252
inline bool requiresFeatureCoroutineAccessors(AccessorKind kind) {
5353
switch (kind) {
54+
case AccessorKind::Modify2:
55+
return true;
5456
case AccessorKind::Get:
5557
case AccessorKind::DistributedGet:
5658
case AccessorKind::Set:
@@ -69,6 +71,7 @@ inline bool isYieldingAccessor(AccessorKind kind) {
6971
switch (kind) {
7072
case AccessorKind::Read:
7173
case AccessorKind::Modify:
74+
case AccessorKind::Modify2:
7275
return true;
7376
case AccessorKind::Get:
7477
case AccessorKind::DistributedGet:
@@ -90,6 +93,7 @@ inline bool isYieldingDefaultNonmutatingAccessor(AccessorKind kind) {
9093
case AccessorKind::DistributedGet:
9194
case AccessorKind::Set:
9295
case AccessorKind::Modify:
96+
case AccessorKind::Modify2:
9397
case AccessorKind::WillSet:
9498
case AccessorKind::DidSet:
9599
case AccessorKind::Address:
@@ -102,6 +106,7 @@ inline bool isYieldingDefaultNonmutatingAccessor(AccessorKind kind) {
102106
inline bool isYieldingDefaultMutatingAccessor(AccessorKind kind) {
103107
switch (kind) {
104108
case AccessorKind::Modify:
109+
case AccessorKind::Modify2:
105110
return true;
106111
case AccessorKind::Get:
107112
case AccessorKind::DistributedGet:

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ NODE(ObjCMetadataUpdateFunction)
178178
NODE(ObjCResilientClassStub)
179179
NODE(FullObjCResilientClassStub)
180180
CONTEXT_NODE(ModifyAccessor)
181+
CONTEXT_NODE(Modify2Accessor)
181182
CONTEXT_NODE(Module)
182183
CONTEXT_NODE(NativeOwningAddressor)
183184
CONTEXT_NODE(NativeOwningMutableAddressor)

lib/AST/ASTMangler.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ static StringRef getCodeForAccessorKind(AccessorKind kind) {
107107
return "au";
108108
case AccessorKind::Init:
109109
return "i";
110+
case AccessorKind::Modify2:
111+
return "x";
110112
}
111113
llvm_unreachable("bad accessor kind");
112114
}

lib/AST/ASTPrinter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4012,6 +4012,7 @@ void PrintAST::visitAccessorDecl(AccessorDecl *decl) {
40124012
case AccessorKind::Address:
40134013
case AccessorKind::Read:
40144014
case AccessorKind::Modify:
4015+
case AccessorKind::Modify2:
40154016
case AccessorKind::DidSet:
40164017
case AccessorKind::MutableAddress:
40174018
recordDeclLoc(decl,

lib/AST/AccessRequests.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ AccessLevelRequest::evaluate(Evaluator &evaluator, ValueDecl *D) const {
6060
case AccessorKind::Set:
6161
case AccessorKind::MutableAddress:
6262
case AccessorKind::Modify:
63+
case AccessorKind::Modify2:
6364
return storage->getSetterFormalAccess();
6465
case AccessorKind::WillSet:
6566
case AccessorKind::DidSet:

lib/AST/Decl.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ DescriptiveDeclKind Decl::getDescriptiveKind() const {
267267
return DescriptiveDeclKind::ReadAccessor;
268268

269269
case AccessorKind::Modify:
270+
case AccessorKind::Modify2:
270271
return DescriptiveDeclKind::ModifyAccessor;
271272

272273
case AccessorKind::Init:
@@ -2904,6 +2905,7 @@ bool AbstractStorageDecl::requiresOpaqueAccessor(AccessorKind kind) const {
29042905
case AccessorKind::Read:
29052906
return requiresOpaqueReadCoroutine();
29062907
case AccessorKind::Modify:
2908+
case AccessorKind::Modify2:
29072909
return requiresOpaqueModifyCoroutine();
29082910

29092911
// Other accessors are never part of the opaque-accessors set.
@@ -6768,6 +6770,7 @@ StringRef swift::getAccessorNameForDiagnostic(AccessorKind accessorKind,
67686770
case AccessorKind::Read:
67696771
return article ? "a 'read' accessor" : "'read' accessor";
67706772
case AccessorKind::Modify:
6773+
case AccessorKind::Modify2:
67716774
return article ? "a 'modify' accessor" : "'modify' accessor";
67726775
case AccessorKind::WillSet:
67736776
return "'willSet'";
@@ -9008,6 +9011,7 @@ DeclName AbstractFunctionDecl::getEffectiveFullName() const {
90089011
case AccessorKind::DistributedGet:
90099012
case AccessorKind::Read:
90109013
case AccessorKind::Modify:
9014+
case AccessorKind::Modify2:
90119015
return subscript ? subscript->getName()
90129016
: DeclName(ctx, storage->getBaseName(),
90139017
ArrayRef<Identifier>());
@@ -10316,6 +10320,7 @@ StringRef AccessorDecl::implicitParameterNameFor(AccessorKind kind) {
1031610320
case AccessorKind::DistributedGet:
1031710321
case AccessorKind::Read:
1031810322
case AccessorKind::Modify:
10323+
case AccessorKind::Modify2:
1031910324
case AccessorKind::Address:
1032010325
case AccessorKind::MutableAddress:
1032110326
return StringRef();
@@ -10335,6 +10340,7 @@ bool AccessorDecl::isAssumedNonMutating() const {
1033510340
case AccessorKind::DidSet:
1033610341
case AccessorKind::MutableAddress:
1033710342
case AccessorKind::Modify:
10343+
case AccessorKind::Modify2:
1033810344
case AccessorKind::Init:
1033910345
return false;
1034010346
}

lib/AST/PrettyStackTrace.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ void swift::printDeclDescription(llvm::raw_ostream &out, const Decl *D,
9494
case AccessorKind::Init:
9595
out << "init";
9696
break;
97+
case AccessorKind::Modify2:
98+
out << "modify2";
99+
break;
97100
}
98101

99102
out << " for " << ASD->getName();

lib/Demangling/Demangler.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3914,6 +3914,7 @@ NodePointer Demangler::demangleAccessor(NodePointer ChildNode) {
39143914
case 'W': Kind = Node::Kind::DidSet; break;
39153915
case 'r': Kind = Node::Kind::ReadAccessor; break;
39163916
case 'M': Kind = Node::Kind::ModifyAccessor; break;
3917+
case 'x': Kind = Node::Kind::Modify2Accessor; break;
39173918
case 'i': Kind = Node::Kind::InitAccessor; break;
39183919
case 'a':
39193920
switch (nextChar()) {

lib/Demangling/NodePrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,7 @@ class NodePrinter {
469469
case Node::Kind::MethodDescriptor:
470470
case Node::Kind::MethodLookupFunction:
471471
case Node::Kind::ModifyAccessor:
472+
case Node::Kind::Modify2Accessor:
472473
case Node::Kind::NativeOwningAddressor:
473474
case Node::Kind::NativeOwningMutableAddressor:
474475
case Node::Kind::NativePinningAddressor:
@@ -2723,6 +2724,9 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
27232724
case Node::Kind::ModifyAccessor:
27242725
return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext,
27252726
"modify");
2727+
case Node::Kind::Modify2Accessor:
2728+
return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext,
2729+
"modify2");
27262730
case Node::Kind::InitAccessor:
27272731
return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext,
27282732
"init");

lib/Demangling/OldRemangler.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,6 +1313,11 @@ ManglingError Remangler::mangleModifyAccessor(Node *node, EntityContext &ctx,
13131313
return mangleAccessor(node->getFirstChild(), "M", ctx, depth + 1);
13141314
}
13151315

1316+
ManglingError Remangler::mangleModify2Accessor(Node *node, EntityContext &ctx,
1317+
unsigned depth) {
1318+
return mangleAccessor(node->getFirstChild(), "x", ctx, depth + 1);
1319+
}
1320+
13161321
ManglingError Remangler::mangleExplicitClosure(Node *node, EntityContext &ctx,
13171322
unsigned depth) {
13181323
return mangleNamedAndTypedEntity(node, 'F', "U", ctx,

lib/Demangling/Remangler.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2343,6 +2343,10 @@ ManglingError Remangler::mangleModifyAccessor(Node *node, unsigned depth) {
23432343
return mangleAbstractStorage(node->getFirstChild(), "M", depth + 1);
23442344
}
23452345

2346+
ManglingError Remangler::mangleModify2Accessor(Node *node, unsigned depth) {
2347+
return mangleAbstractStorage(node->getFirstChild(), "x", depth + 1);
2348+
}
2349+
23462350
ManglingError Remangler::mangleModule(Node *node, unsigned depth) {
23472351
auto text = node->getText();
23482352
if (text == STDLIB_NAME) {

lib/IRGen/GenMeta.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,8 @@ static Flags getMethodDescriptorFlags(ValueDecl *fn) {
265265
return Flags::Kind::ReadCoroutine;
266266
case AccessorKind::Modify:
267267
return Flags::Kind::ModifyCoroutine;
268+
case AccessorKind::Modify2:
269+
return Flags::Kind::Modify2Coroutine;
268270
#define OPAQUE_ACCESSOR(ID, KEYWORD)
269271
#define ACCESSOR(ID) \
270272
case AccessorKind::ID:

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,9 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
636636
case AccessorKind::Init:
637637
Kind = ".init";
638638
break;
639+
case AccessorKind::Modify2:
640+
Kind = ".modify2";
641+
break;
639642
}
640643

641644
SmallVector<char, 64> Buf;

lib/Index/Index.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ printArtificialName(const swift::AbstractStorageDecl *ASD, AccessorKind AK, llvm
6868
case AccessorKind::MutableAddress:
6969
case AccessorKind::Read:
7070
case AccessorKind::Modify:
71+
case AccessorKind::Modify2:
7172
return true;
7273
}
7374

lib/Index/IndexSymbol.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ SymbolSubKind index::getSubKindForAccessor(AccessorKind AK) {
277277
return SymbolSubKind::SwiftAccessorMutableAddressor;
278278
case AccessorKind::Read: return SymbolSubKind::SwiftAccessorRead;
279279
case AccessorKind::Modify: return SymbolSubKind::SwiftAccessorModify;
280+
case AccessorKind::Modify2: return SymbolSubKind::SwiftAccessorModify;
280281
case AccessorKind::Init: return SymbolSubKind::SwiftAccessorInit;
281282
}
282283

lib/Parse/ParseDecl.cpp

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7871,6 +7871,7 @@ static bool isAllowedWhenParsingLimitedSyntax(AccessorKind kind, bool forSIL) {
78717871
case AccessorKind::DidSet:
78727872
case AccessorKind::Read:
78737873
case AccessorKind::Modify:
7874+
case AccessorKind::Modify2:
78747875
return false;
78757876

78767877
case AccessorKind::Init:
@@ -7906,6 +7907,7 @@ struct Parser::ParsedAccessors {
79067907
if (Init) return Init;
79077908
if (Set) return Set;
79087909
if (Modify) return Modify;
7910+
if (Modify2) return Modify2;
79097911
if (MutableAddress) return MutableAddress;
79107912
return nullptr;
79117913
}
@@ -7955,6 +7957,23 @@ static ParserStatus parseAccessorIntroducer(Parser &P,
79557957
return Status;
79567958
}
79577959
#define ACCESSOR_KEYWORD(KEYWORD)
7960+
// Existing source code may have an implicit getter whose first expression is a
7961+
// call to a function named experimental_accessor passing a trailing closure.
7962+
// To maintain compatibility, if the feature corresponding to
7963+
// experimental_accessor is not enabled, do not parse the token as an
7964+
// introducer, so that it can be parsed as such a function call.
7965+
#define EXPERIMENTAL_COROUTINE_ACCESSOR(ID, KEYWORD, FEATURE) \
7966+
else if (P.Tok.getRawText() == #KEYWORD) { \
7967+
if (!P.Context.LangOpts.hasFeature(Feature::FEATURE)) { \
7968+
if (featureUnavailable) \
7969+
*featureUnavailable = true; \
7970+
if (isFirstAccessor) { \
7971+
Status.setIsParseError(); \
7972+
return Status; \
7973+
} \
7974+
} \
7975+
Kind = AccessorKind::ID; \
7976+
}
79587977
#define SINGLETON_ACCESSOR(ID, KEYWORD) \
79597978
else if (P.Tok.getRawText() == #KEYWORD) { \
79607979
Kind = AccessorKind::ID; \
@@ -8066,6 +8085,12 @@ bool Parser::parseAccessorAfterIntroducer(
80668085
existingAccessor);
80678086
}
80688087

8088+
if (requiresFeatureCoroutineAccessors(Kind) &&
8089+
!Context.LangOpts.hasFeature(Feature::CoroutineAccessors)) {
8090+
diagnose(Tok, diag::accessor_requires_coroutine_accessors,
8091+
getAccessorNameForDiagnostic(Kind, /*article*/ false));
8092+
}
8093+
80698094
// There should be no body in the limited syntax; diagnose unexpected
80708095
// accessor implementations.
80718096
if (parsingLimitedSyntax) {
@@ -8551,9 +8576,9 @@ void Parser::ParsedAccessors::classify(Parser &P, AbstractStorageDecl *storage,
85518576
P.diagnose(mutator->getLoc(),
85528577
// Don't mention the more advanced accessors if the user
85538578
// only provided a setter without a getter.
8554-
(MutableAddress || Modify)
8555-
? diag::missing_reading_accessor
8556-
: diag::missing_getter,
8579+
(MutableAddress || Modify || Modify2)
8580+
? diag::missing_reading_accessor
8581+
: diag::missing_getter,
85578582
isa<SubscriptDecl>(storage),
85588583
getAccessorNameForDiagnostic(mutator, /*article*/ true));
85598584
}

lib/SIL/IR/SILPrinter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,9 @@ void SILDeclRef::print(raw_ostream &OS) const {
347347
case AccessorKind::Init:
348348
OS << "!init";
349349
break;
350+
case AccessorKind::Modify2:
351+
OS << "!modify2";
352+
break;
350353
}
351354
break;
352355
}

lib/SILGen/SILGenLValue.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3252,7 +3252,8 @@ namespace {
32523252
}
32533253

32543254
case AccessorKind::Read:
3255-
case AccessorKind::Modify: {
3255+
case AccessorKind::Modify:
3256+
case AccessorKind::Modify2: {
32563257
auto typeData =
32573258
getPhysicalStorageTypeData(SGF.getTypeExpansionContext(), SGF.SGM,
32583259
AccessKind, Storage, Subs,

lib/SILGen/SILGenPattern.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3336,6 +3336,7 @@ static bool isBorrowableSubject(SILGenFunction &SGF,
33363336
return false;
33373337
case AccessorKind::Read:
33383338
case AccessorKind::Modify:
3339+
case AccessorKind::Modify2:
33393340
case AccessorKind::Address:
33403341
case AccessorKind::MutableAddress:
33413342
// Read, modify, and addressors yield a borrowable reference.

lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1775,6 +1775,7 @@ void LifetimeChecker::handleInOutUse(const DIMemoryUse &Use) {
17751775
return false;
17761776
case AccessorKind::Set:
17771777
case AccessorKind::Modify:
1778+
case AccessorKind::Modify2:
17781779
case AccessorKind::MutableAddress:
17791780
case AccessorKind::DidSet:
17801781
case AccessorKind::WillSet:

lib/Sema/CSDiagnostics.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4702,6 +4702,7 @@ bool InvalidMemberRefOnExistential::diagnoseAsError() {
47024702
case AccessorKind::DistributedGet:
47034703
case AccessorKind::Read:
47044704
case AccessorKind::Modify:
4705+
case AccessorKind::Modify2:
47054706
case AccessorKind::Address:
47064707
case AccessorKind::MutableAddress:
47074708
PD = SD->getIndices()->get(idx);

lib/Sema/MiscDiagnostics.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4912,6 +4912,7 @@ class ObjCSelectorWalker : public ASTWalker {
49124912
case AccessorKind::MutableAddress:
49134913
case AccessorKind::Read:
49144914
case AccessorKind::Modify:
4915+
case AccessorKind::Modify2:
49154916
case AccessorKind::Init:
49164917
llvm_unreachable("cannot be @objc");
49174918
}

lib/Sema/TypeCheckAttr.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5365,6 +5365,7 @@ static DescriptiveDeclKind getAccessorDescriptiveDeclKind(AccessorKind kind) {
53655365
case AccessorKind::Read:
53665366
return DescriptiveDeclKind::ReadAccessor;
53675367
case AccessorKind::Modify:
5368+
case AccessorKind::Modify2:
53685369
return DescriptiveDeclKind::ModifyAccessor;
53695370
case AccessorKind::WillSet:
53705371
return DescriptiveDeclKind::WillSet;

0 commit comments

Comments
 (0)