Skip to content

Commit 98a2e6a

Browse files
committed
[CoroutineAccessors] Added modify.
The name is a placeholder for the mutating single-yield coroutine accessor.
1 parent 66e6c59 commit 98a2e6a

Some content is hidden

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

49 files changed

+793
-28
lines changed

docs/ABI/Mangling.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,10 +388,11 @@ Entities
388388
ACCESSOR ::= 'w' // willSet
389389
ACCESSOR ::= 'W' // didSet
390390
ACCESSOR ::= 'r' // read
391-
ACCESSOR ::= 'M' // modify (temporary)
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
@@ -372,6 +372,7 @@ class MethodDescriptorFlags {
372372
Setter,
373373
ModifyCoroutine,
374374
ReadCoroutine,
375+
Modify2Coroutine,
375376
};
376377

377378
private:
@@ -594,6 +595,7 @@ class ProtocolRequirementFlags {
594595
ModifyCoroutine,
595596
AssociatedTypeAccessFunction,
596597
AssociatedConformanceAccessFunction,
598+
Modify2Coroutine,
597599
};
598600

599601
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: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ class raw_ostream;
2828

2929
namespace swift {
3030

31+
class ASTContext;
32+
3133
enum StorageIsMutable_t : bool {
3234
StorageIsNotMutable = false,
3335
StorageIsMutable = true
@@ -57,6 +59,8 @@ enum class AccessorKind {
5759

5860
inline bool requiresFeatureCoroutineAccessors(AccessorKind kind) {
5961
switch (kind) {
62+
case AccessorKind::Modify2:
63+
return true;
6064
case AccessorKind::Get:
6165
case AccessorKind::DistributedGet:
6266
case AccessorKind::Set:
@@ -75,6 +79,7 @@ inline bool isYieldingAccessor(AccessorKind kind) {
7579
switch (kind) {
7680
case AccessorKind::Read:
7781
case AccessorKind::Modify:
82+
case AccessorKind::Modify2:
7883
return true;
7984
case AccessorKind::Get:
8085
case AccessorKind::DistributedGet:
@@ -96,6 +101,7 @@ inline bool isYieldingDefaultNonmutatingAccessor(AccessorKind kind) {
96101
case AccessorKind::DistributedGet:
97102
case AccessorKind::Set:
98103
case AccessorKind::Modify:
104+
case AccessorKind::Modify2:
99105
case AccessorKind::WillSet:
100106
case AccessorKind::DidSet:
101107
case AccessorKind::Address:
@@ -108,6 +114,7 @@ inline bool isYieldingDefaultNonmutatingAccessor(AccessorKind kind) {
108114
inline bool isYieldingDefaultMutatingAccessor(AccessorKind kind) {
109115
switch (kind) {
110116
case AccessorKind::Modify:
117+
case AccessorKind::Modify2:
111118
return true;
112119
case AccessorKind::Get:
113120
case AccessorKind::DistributedGet:
@@ -297,8 +304,11 @@ enum class WriteImplKind {
297304
/// There's a mutable addressor.
298305
MutableAddress,
299306

300-
/// There's a modify coroutine.
307+
/// There's a _modify coroutine.
301308
Modify,
309+
310+
/// There's a modify coroutine.
311+
Modify2,
302312
};
303313
enum { NumWriteImplKindBits = 4 };
304314

@@ -316,9 +326,12 @@ enum class ReadWriteImplKind {
316326
/// Do a read into a temporary and then a write back.
317327
MaterializeToTemporary,
318328

319-
/// There's a modify coroutine.
329+
/// There's a _modify coroutine.
320330
Modify,
321331

332+
/// There's a modify coroutine.
333+
Modify2,
334+
322335
/// We have a didSet, so we're either going to use
323336
/// MaterializeOrTemporary or the "simple didSet"
324337
// access pattern.
@@ -391,6 +404,13 @@ class StorageImplInfo {
391404
assert(readWriteImpl == ReadWriteImplKind::Modify);
392405
return;
393406

407+
case WriteImplKind::Modify2:
408+
assert(readImpl == ReadImplKind::Get ||
409+
readImpl == ReadImplKind::Address ||
410+
readImpl == ReadImplKind::Read);
411+
assert(readWriteImpl == ReadWriteImplKind::Modify2);
412+
return;
413+
394414
case WriteImplKind::MutableAddress:
395415
assert(readImpl == ReadImplKind::Get ||
396416
readImpl == ReadImplKind::Address ||
@@ -411,8 +431,9 @@ class StorageImplInfo {
411431
}
412432

413433
static StorageImplInfo getOpaque(StorageIsMutable_t isMutable,
414-
OpaqueReadOwnership ownership) {
415-
return (isMutable ? getMutableOpaque(ownership)
434+
OpaqueReadOwnership ownership,
435+
const ASTContext &ctx) {
436+
return (isMutable ? getMutableOpaque(ownership, ctx)
416437
: getImmutableOpaque(ownership));
417438
}
418439

@@ -422,7 +443,8 @@ class StorageImplInfo {
422443
}
423444

424445
/// Describe the implementation of a mutable property implemented opaquely.
425-
static StorageImplInfo getMutableOpaque(OpaqueReadOwnership ownership);
446+
static StorageImplInfo getMutableOpaque(OpaqueReadOwnership ownership,
447+
const ASTContext &ctx);
426448

427449
static StorageImplInfo getComputed(StorageIsMutable_t isMutable) {
428450
return (isMutable ? getMutableComputed()

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/ASTDumper.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,8 @@ static StringRef getDumpString(WriteImplKind kind) {
248248
return "mutable_addressor";
249249
case WriteImplKind::Modify:
250250
return "modify_coroutine";
251+
case WriteImplKind::Modify2:
252+
return "modify2_coroutine";
251253
}
252254
llvm_unreachable("bad kind");
253255
}
@@ -264,6 +266,8 @@ static StringRef getDumpString(ReadWriteImplKind kind) {
264266
return "materialize_to_temporary";
265267
case ReadWriteImplKind::Modify:
266268
return "modify_coroutine";
269+
case ReadWriteImplKind::Modify2:
270+
return "modify2_coroutine";
267271
case ReadWriteImplKind::StoredWithDidSet:
268272
return "stored_with_didset";
269273
case ReadWriteImplKind::InheritedWithDidSet:

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: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2359,6 +2359,12 @@ void PrintAST::printSelfAccessKindModifiersIfNeeded(const FuncDecl *FD) {
23592359
}
23602360
}
23612361

2362+
static bool
2363+
shouldPrintUnderscoredCoroutineAccessors(const AbstractStorageDecl *ASD) {
2364+
// TODO: CoroutineAccessors: Print only when necessary.
2365+
return true;
2366+
}
2367+
23622368
void PrintAST::printAccessors(const AbstractStorageDecl *ASD) {
23632369
if (isa<VarDecl>(ASD) && !Options.PrintPropertyAccessors)
23642370
return;
@@ -2501,8 +2507,13 @@ void PrintAST::printAccessors(const AbstractStorageDecl *ASD) {
25012507
// Collect the accessor declarations that we should print.
25022508
SmallVector<AccessorDecl *, 4> accessorsToPrint;
25032509
auto AddAccessorToPrint = [&](AccessorKind kind) {
2510+
if (Options.SuppressCoroutineAccessors &&
2511+
requiresFeatureCoroutineAccessors(kind))
2512+
return;
25042513
auto *Accessor = ASD->getAccessor(kind);
2505-
if (Accessor && shouldPrint(Accessor))
2514+
if (!Accessor)
2515+
return;
2516+
if (shouldPrint(Accessor))
25062517
accessorsToPrint.push_back(Accessor);
25072518
};
25082519

@@ -2542,8 +2553,10 @@ void PrintAST::printAccessors(const AbstractStorageDecl *ASD) {
25422553
}
25432554
case WriteImplKind::Set:
25442555
AddAccessorToPrint(AccessorKind::Set);
2545-
if (!shouldHideModifyAccessor())
2556+
if (!shouldHideModifyAccessor()) {
25462557
AddAccessorToPrint(AccessorKind::Modify);
2558+
AddAccessorToPrint(AccessorKind::Modify2);
2559+
}
25472560
break;
25482561
case WriteImplKind::MutableAddress:
25492562
AddAccessorToPrint(AccessorKind::MutableAddress);
@@ -2553,6 +2566,13 @@ void PrintAST::printAccessors(const AbstractStorageDecl *ASD) {
25532566
case WriteImplKind::Modify:
25542567
AddAccessorToPrint(AccessorKind::Modify);
25552568
break;
2569+
case WriteImplKind::Modify2:
2570+
if (ASD->getAccessor(AccessorKind::Modify) &&
2571+
shouldPrintUnderscoredCoroutineAccessors(ASD)) {
2572+
AddAccessorToPrint(AccessorKind::Modify);
2573+
}
2574+
AddAccessorToPrint(AccessorKind::Modify2);
2575+
break;
25562576
}
25572577
}
25582578

@@ -4060,6 +4080,7 @@ void PrintAST::visitAccessorDecl(AccessorDecl *decl) {
40604080
case AccessorKind::Address:
40614081
case AccessorKind::Read:
40624082
case AccessorKind::Modify:
4083+
case AccessorKind::Modify2:
40634084
case AccessorKind::DidSet:
40644085
case AccessorKind::MutableAddress:
40654086
recordDeclLoc(decl,

lib/AST/ASTVerifier.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3411,10 +3411,11 @@ class Verifier : public ASTWalker {
34113411
abort();
34123412
}
34133413
if (FD->isDynamic() != storageDecl->isDynamic() &&
3414-
// We allow a non dynamic setter if there is a dynamic modify,
3415-
// observer, or mutable addressor.
3414+
// We allow a non dynamic setter if there is a dynamic
3415+
// _modify/modify, observer, or mutable addressor.
34163416
!(FD->isSetter() &&
34173417
(storageDecl->getWriteImpl() == WriteImplKind::Modify ||
3418+
storageDecl->getWriteImpl() == WriteImplKind::Modify2 ||
34183419
storageDecl->getWriteImpl() ==
34193420
WriteImplKind::StoredWithObservers ||
34203421
storageDecl->getWriteImpl() == WriteImplKind::MutableAddress) &&

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: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ DescriptiveDeclKind Decl::getDescriptiveKind() const {
266266
return DescriptiveDeclKind::ReadAccessor;
267267

268268
case AccessorKind::Modify:
269+
case AccessorKind::Modify2:
269270
return DescriptiveDeclKind::ModifyAccessor;
270271

271272
case AccessorKind::Init:
@@ -2722,6 +2723,9 @@ getDirectWriteAccessStrategy(const AbstractStorageDecl *storage) {
27222723
case WriteImplKind::Modify:
27232724
return AccessStrategy::getAccessor(AccessorKind::Modify,
27242725
/*dispatch*/ false);
2726+
case WriteImplKind::Modify2:
2727+
return AccessStrategy::getAccessor(AccessorKind::Modify2,
2728+
/*dispatch*/ false);
27252729
}
27262730
llvm_unreachable("bad impl kind");
27272731
}
@@ -2752,6 +2756,9 @@ getDirectReadWriteAccessStrategy(const AbstractStorageDecl *storage) {
27522756
case ReadWriteImplKind::Modify:
27532757
return AccessStrategy::getAccessor(AccessorKind::Modify,
27542758
/*dispatch*/ false);
2759+
case ReadWriteImplKind::Modify2:
2760+
return AccessStrategy::getAccessor(AccessorKind::Modify2,
2761+
/*dispatch*/ false);
27552762
case ReadWriteImplKind::StoredWithDidSet:
27562763
case ReadWriteImplKind::InheritedWithDidSet:
27572764
if (storage->requiresOpaqueModifyCoroutine() &&
@@ -2897,6 +2904,7 @@ bool AbstractStorageDecl::requiresOpaqueAccessor(AccessorKind kind) const {
28972904
case AccessorKind::Read:
28982905
return requiresOpaqueReadCoroutine();
28992906
case AccessorKind::Modify:
2907+
case AccessorKind::Modify2:
29002908
return requiresOpaqueModifyCoroutine();
29012909

29022910
// Other accessors are never part of the opaque-accessors set.
@@ -6759,6 +6767,7 @@ StringRef swift::getAccessorNameForDiagnostic(AccessorKind accessorKind,
67596767
case AccessorKind::Read:
67606768
return article ? "a 'read' accessor" : "'read' accessor";
67616769
case AccessorKind::Modify:
6770+
case AccessorKind::Modify2:
67626771
return article ? "a 'modify' accessor" : "'modify' accessor";
67636772
case AccessorKind::WillSet:
67646773
return "'willSet'";
@@ -8999,6 +9008,7 @@ DeclName AbstractFunctionDecl::getEffectiveFullName() const {
89999008
case AccessorKind::DistributedGet:
90009009
case AccessorKind::Read:
90019010
case AccessorKind::Modify:
9011+
case AccessorKind::Modify2:
90029012
return subscript ? subscript->getName()
90039013
: DeclName(ctx, storage->getBaseName(),
90049014
ArrayRef<Identifier>());
@@ -10307,6 +10317,7 @@ StringRef AccessorDecl::implicitParameterNameFor(AccessorKind kind) {
1030710317
case AccessorKind::DistributedGet:
1030810318
case AccessorKind::Read:
1030910319
case AccessorKind::Modify:
10320+
case AccessorKind::Modify2:
1031010321
case AccessorKind::Address:
1031110322
case AccessorKind::MutableAddress:
1031210323
return StringRef();
@@ -10326,6 +10337,7 @@ bool AccessorDecl::isAssumedNonMutating() const {
1032610337
case AccessorKind::DidSet:
1032710338
case AccessorKind::MutableAddress:
1032810339
case AccessorKind::Modify:
10340+
case AccessorKind::Modify2:
1032910341
case AccessorKind::Init:
1033010342
return false;
1033110343
}

lib/AST/FeatureSet.cpp

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

313313
static bool usesFeatureCoroutineAccessors(Decl *decl) {
314-
auto *accessor = dyn_cast<AccessorDecl>(decl);
315-
if (!accessor) {
314+
auto accessorDeclUsesFeatureCoroutineAccessors = [](AccessorDecl *accessor) {
315+
return requiresFeatureCoroutineAccessors(accessor->getAccessorKind());
316+
};
317+
switch (decl->getKind()) {
318+
case DeclKind::Var: {
319+
auto *var = cast<VarDecl>(decl);
320+
return llvm::any_of(var->getAllAccessors(),
321+
accessorDeclUsesFeatureCoroutineAccessors);
322+
}
323+
case DeclKind::Accessor: {
324+
auto *accessor = cast<AccessorDecl>(decl);
325+
return accessorDeclUsesFeatureCoroutineAccessors(accessor);
326+
}
327+
default:
316328
return false;
317329
}
318-
return requiresFeatureCoroutineAccessors(accessor->getAccessorKind());
319330
}
320331

321332
// ----------------------------------------------------------------------------

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();

0 commit comments

Comments
 (0)