Skip to content

Commit d77ed36

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

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+416
-12
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: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2495,8 +2495,13 @@ void PrintAST::printAccessors(const AbstractStorageDecl *ASD) {
24952495
// Collect the accessor declarations that we should print.
24962496
SmallVector<AccessorDecl *, 4> accessorsToPrint;
24972497
auto AddAccessorToPrint = [&](AccessorKind kind) {
2498+
if (Options.SuppressCoroutineAccessors &&
2499+
requiresFeatureCoroutineAccessors(kind))
2500+
return;
24982501
auto *Accessor = ASD->getAccessor(kind);
2499-
if (Accessor && shouldPrint(Accessor))
2502+
if (!Accessor)
2503+
return;
2504+
if (shouldPrint(Accessor))
25002505
accessorsToPrint.push_back(Accessor);
25012506
};
25022507

@@ -2536,8 +2541,10 @@ void PrintAST::printAccessors(const AbstractStorageDecl *ASD) {
25362541
}
25372542
case WriteImplKind::Set:
25382543
AddAccessorToPrint(AccessorKind::Set);
2539-
if (!shouldHideModifyAccessor())
2544+
if (!shouldHideModifyAccessor()) {
25402545
AddAccessorToPrint(AccessorKind::Modify);
2546+
AddAccessorToPrint(AccessorKind::Modify2);
2547+
}
25412548
break;
25422549
case WriteImplKind::MutableAddress:
25432550
AddAccessorToPrint(AccessorKind::MutableAddress);
@@ -2546,6 +2553,7 @@ void PrintAST::printAccessors(const AbstractStorageDecl *ASD) {
25462553
break;
25472554
case WriteImplKind::Modify:
25482555
AddAccessorToPrint(AccessorKind::Modify);
2556+
AddAccessorToPrint(AccessorKind::Modify2);
25492557
break;
25502558
}
25512559
}
@@ -4012,6 +4020,7 @@ void PrintAST::visitAccessorDecl(AccessorDecl *decl) {
40124020
case AccessorKind::Address:
40134021
case AccessorKind::Read:
40144022
case AccessorKind::Modify:
4023+
case AccessorKind::Modify2:
40154024
case AccessorKind::DidSet:
40164025
case AccessorKind::MutableAddress:
40174026
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/FeatureSet.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -320,11 +320,22 @@ static bool usesFeatureValueGenerics(Decl *decl) {
320320
}
321321

322322
static bool usesFeatureCoroutineAccessors(Decl *decl) {
323-
auto *accessor = dyn_cast<AccessorDecl>(decl);
324-
if (!accessor) {
323+
auto accessorDeclUsesFeatureCoroutineAccessors = [](AccessorDecl *accessor) {
324+
return requiresFeatureCoroutineAccessors(accessor->getAccessorKind());
325+
};
326+
switch (decl->getKind()) {
327+
case DeclKind::Var: {
328+
auto *var = cast<VarDecl>(decl);
329+
return llvm::any_of(var->getAllAccessors(),
330+
accessorDeclUsesFeatureCoroutineAccessors);
331+
}
332+
case DeclKind::Accessor: {
333+
auto *accessor = cast<AccessorDecl>(decl);
334+
return accessorDeclUsesFeatureCoroutineAccessors(accessor);
335+
}
336+
default:
325337
return false;
326338
}
327-
return requiresFeatureCoroutineAccessors(accessor->getAccessorKind());
328339
}
329340

330341
// ----------------------------------------------------------------------------

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
@@ -3933,6 +3933,7 @@ NodePointer Demangler::demangleAccessor(NodePointer ChildNode) {
39333933
case 'W': Kind = Node::Kind::DidSet; break;
39343934
case 'r': Kind = Node::Kind::ReadAccessor; break;
39353935
case 'M': Kind = Node::Kind::ModifyAccessor; break;
3936+
case 'x': Kind = Node::Kind::Modify2Accessor; break;
39363937
case 'i': Kind = Node::Kind::InitAccessor; break;
39373938
case 'a':
39383939
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
@@ -7862,6 +7862,7 @@ static bool isAllowedWhenParsingLimitedSyntax(AccessorKind kind, bool forSIL) {
78627862
case AccessorKind::DidSet:
78637863
case AccessorKind::Read:
78647864
case AccessorKind::Modify:
7865+
case AccessorKind::Modify2:
78657866
return false;
78667867

78677868
case AccessorKind::Init:
@@ -7897,6 +7898,7 @@ struct Parser::ParsedAccessors {
78977898
if (Init) return Init;
78987899
if (Set) return Set;
78997900
if (Modify) return Modify;
7901+
if (Modify2) return Modify2;
79007902
if (MutableAddress) return MutableAddress;
79017903
return nullptr;
79027904
}
@@ -7946,6 +7948,23 @@ static ParserStatus parseAccessorIntroducer(Parser &P,
79467948
return Status;
79477949
}
79487950
#define ACCESSOR_KEYWORD(KEYWORD)
7951+
// Existing source code may have an implicit getter whose first expression is a
7952+
// call to a function named experimental_accessor passing a trailing closure.
7953+
// To maintain compatibility, if the feature corresponding to
7954+
// experimental_accessor is not enabled, do not parse the token as an
7955+
// introducer, so that it can be parsed as such a function call.
7956+
#define EXPERIMENTAL_COROUTINE_ACCESSOR(ID, KEYWORD, FEATURE) \
7957+
else if (P.Tok.getRawText() == #KEYWORD) { \
7958+
if (!P.Context.LangOpts.hasFeature(Feature::FEATURE)) { \
7959+
if (featureUnavailable) \
7960+
*featureUnavailable = true; \
7961+
if (isFirstAccessor) { \
7962+
Status.setIsParseError(); \
7963+
return Status; \
7964+
} \
7965+
} \
7966+
Kind = AccessorKind::ID; \
7967+
}
79497968
#define SINGLETON_ACCESSOR(ID, KEYWORD) \
79507969
else if (P.Tok.getRawText() == #KEYWORD) { \
79517970
Kind = AccessorKind::ID; \
@@ -8057,6 +8076,12 @@ bool Parser::parseAccessorAfterIntroducer(
80578076
existingAccessor);
80588077
}
80598078

8079+
if (requiresFeatureCoroutineAccessors(Kind) &&
8080+
!Context.LangOpts.hasFeature(Feature::CoroutineAccessors)) {
8081+
diagnose(Tok, diag::accessor_requires_coroutine_accessors,
8082+
getAccessorNameForDiagnostic(Kind, /*article*/ false));
8083+
}
8084+
80608085
// There should be no body in the limited syntax; diagnose unexpected
80618086
// accessor implementations.
80628087
if (parsingLimitedSyntax) {
@@ -8542,9 +8567,9 @@ void Parser::ParsedAccessors::classify(Parser &P, AbstractStorageDecl *storage,
85428567
P.diagnose(mutator->getLoc(),
85438568
// Don't mention the more advanced accessors if the user
85448569
// only provided a setter without a getter.
8545-
(MutableAddress || Modify)
8546-
? diag::missing_reading_accessor
8547-
: diag::missing_getter,
8570+
(MutableAddress || Modify || Modify2)
8571+
? diag::missing_reading_accessor
8572+
: diag::missing_getter,
85488573
isa<SubscriptDecl>(storage),
85498574
getAccessorNameForDiagnostic(mutator, /*article*/ true));
85508575
}

0 commit comments

Comments
 (0)