Skip to content

Commit b80618f

Browse files
committed
Replace materializeForSet with the modify coroutine.
Most of this patch is just removing special cases for materializeForSet or other fairly mechanical replacements. Unfortunately, the rest is still a fairly big change, and not one that can be easily split apart because of the quite reasonable reliance on metaprogramming throughout the compiler. And, of course, there are a bunch of test updates that have to be sync'ed with the actual change to code-generation. This is SR-7134.
1 parent 7eb703b commit b80618f

File tree

100 files changed

+2045
-3330
lines changed

Some content is hidden

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

100 files changed

+2045
-3330
lines changed

include/swift/ABI/MetadataValues.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,8 @@ class MethodDescriptorFlags {
322322
Init,
323323
Getter,
324324
Setter,
325-
MaterializeForSet,
325+
ModifyCoroutine,
326+
ReadCoroutine,
326327
};
327328

328329
private:
@@ -542,7 +543,8 @@ class ProtocolRequirementFlags {
542543
Init,
543544
Getter,
544545
Setter,
545-
MaterializeForSet,
546+
ReadCoroutine,
547+
ModifyCoroutine,
546548
AssociatedTypeAccessFunction,
547549
AssociatedConformanceAccessFunction,
548550
};

include/swift/AST/AccessorKinds.def

Lines changed: 19 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,9 @@
6868
/// COROUTINE_ACCESSOR(ID, KEYWORD)
6969
/// The given accessor is a coroutine accessor, i.e. a reader or modifier.
7070
///
71-
/// Defaults to SINGLETON_ACCESSOR(ID, KEYWORD).
71+
/// Defaults to OPAQUE_ACCESSOR(ID, KEYWORD).
7272
#ifndef COROUTINE_ACCESSOR
73-
#define COROUTINE_ACCESSOR(ID, KEYWORD) SINGLETON_ACCESSOR(ID, KEYWORD)
73+
#define COROUTINE_ACCESSOR(ID, KEYWORD) OPAQUE_ACCESSOR(ID, KEYWORD)
7474
#endif
7575

7676
/// ANY_ADDRESSOR(ACCESSOR_ID, ADDRESSOR_ID, KEYWORD)
@@ -127,18 +127,21 @@ OBJC_ACCESSOR(Get, get)
127127
/// always be synthesized if the storage is mutable at all.
128128
OBJC_ACCESSOR(Set, set)
129129

130-
/// This is a materializeForSet accessor: a function which is called
131-
/// when a combined read-modify operation is performed on the storage,
132-
/// such as passing it as an inout argument (which includes calling
133-
/// a mutating function on it). It is essentially a SILGen-lowered
134-
/// coroutine that yields a pointer to a mutable value of the storage
135-
/// type.
136-
///
137-
/// We do not allow users to provide materializeForSet. It can always
138-
/// be synthesized if the storage is mutable at all.
139-
#if !(SUPPRESS_ARTIFICIAL_ACCESSORS)
140-
OPAQUE_ACCESSOR(MaterializeForSet, materializeForSet)
141-
#endif
130+
/// This is a read accessor: a yield-once coroutine which is called when a
131+
/// value is loaded from the storage, like a getter, but which works
132+
/// by yielding a borrowed value of the storage type.
133+
///
134+
/// If the storage is not implemented with a read accessor then
135+
/// one can always be synthesized (even if the storage type is move-only).
136+
COROUTINE_ACCESSOR(Read, _read)
137+
138+
/// This is a modify accessor: a yield-once coroutine which is called when a
139+
/// the storage is modified which works by yielding an inout value
140+
/// of the storage type.
141+
///
142+
/// If the storage is not implemented with a modify accessor then
143+
/// one can be synthesized if the storage is mutable at all.
144+
COROUTINE_ACCESSOR(Modify, _modify)
142145

143146
/// This is a willSet observer: a function which "decorates" an
144147
/// underlying assignment operation by being called prior to the
@@ -156,24 +159,6 @@ OBSERVING_ACCESSOR(WillSet, willSet)
156159
/// setter idiom.
157160
OBSERVING_ACCESSOR(DidSet, didSet)
158161

159-
/// This is a read accessor: a coroutine which is called when a
160-
/// value is loaded from the storage, like a getter, but which works
161-
/// by yielding a borrowed value of the storage type.
162-
///
163-
/// If the storage is not implemented with a read accessor then
164-
/// one can always be synthesized (even if the storage type is move-only).
165-
COROUTINE_ACCESSOR(Read, _read)
166-
167-
/// This is a modify accessor: a coroutine which is called when a
168-
/// the storage is assigned to (like a setter) or read-modified
169-
/// (like materializeForSet), but which works by yielding an inout
170-
/// value of the storage type.
171-
///
172-
/// If the storage is not implemented with a modify accessor then
173-
/// one can be synthesized if the storage is mutable at all.
174-
/// Modify accessors are intended to eventually replace materializeForSet.
175-
COROUTINE_ACCESSOR(Modify, _modify)
176-
177162
/// This is an address-family accessor: a function that is called when
178163
/// a value is loaded from the storage, like a getter, but which works
179164
/// by returning a pointer to an immutable value of the storage type.
@@ -189,9 +174,8 @@ IMMUTABLE_ADDRESSOR(Owning, addressWithOwner)
189174
IMMUTABLE_ADDRESSOR(NativeOwning, addressWithNativeOwner)
190175

191176
/// This is a mutableAddress-family accessor: a function that is
192-
/// called when the storage is assigned to (like a setter) or
193-
/// read-modified (like materializeForSet), but which works by
194-
/// returning a pointer to a mutable value of the storage type.
177+
/// called when the storage is modified and which works by returning
178+
/// a pointer to a mutable value of the storage type.
195179
/// This kind of accessor also has an addressor kind.
196180
///
197181
/// Addressors are a way of proving more efficient access to storage

include/swift/AST/AnyFunctionRef.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,8 @@ class AnyFunctionRef {
190190
if (auto *AFD = TheFunction.dyn_cast<AbstractFunctionDecl *>()) {
191191
if (auto *AD = dyn_cast<AccessorDecl>(AFD)) {
192192
if (AD->isCoroutine()) {
193-
auto valueTy = AD->getStorage()->getValueInterfaceType();
193+
auto valueTy = AD->getStorage()->getValueInterfaceType()
194+
->getReferenceStorageReferent();
194195
if (mapIntoContext)
195196
valueTy = AD->mapTypeIntoContext(valueTy);
196197
YieldTypeFlags flags(AD->getAccessorKind() == AccessorKind::Modify

include/swift/AST/Decl.h

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,6 @@ enum class DescriptiveDeclKind : uint8_t {
147147
ClassMethod,
148148
Getter,
149149
Setter,
150-
MaterializeForSet,
151150
Addressor,
152151
MutableAddressor,
153152
ReadAccessor,
@@ -325,7 +324,7 @@ class alignas(1 << DeclAlignInBits) Decl {
325324
IsUserAccessible : 1
326325
);
327326

328-
SWIFT_INLINE_BITFIELD(AbstractStorageDecl, ValueDecl, 1+1+1+1,
327+
SWIFT_INLINE_BITFIELD(AbstractStorageDecl, ValueDecl, 1+1+1+1+2,
329328
/// Whether the getter is mutating.
330329
IsGetterMutating : 1,
331330

@@ -336,7 +335,10 @@ class alignas(1 << DeclAlignInBits) Decl {
336335
HasStorage : 1,
337336

338337
/// Whether this storage supports semantic mutation in some way.
339-
SupportsMutation : 1
338+
SupportsMutation : 1,
339+
340+
/// Whether an opaque read of this storage produces an owned value.
341+
OpaqueReadOwnership : 2
340342
);
341343

342344
SWIFT_INLINE_BITFIELD(VarDecl, AbstractStorageDecl, 1+4+1+1+1+1,
@@ -4142,6 +4144,8 @@ class AbstractStorageDecl : public ValueDecl {
41424144
Bits.AbstractStorageDecl.SupportsMutation = supportsMutation;
41434145
Bits.AbstractStorageDecl.IsGetterMutating = false;
41444146
Bits.AbstractStorageDecl.IsSetterMutating = true;
4147+
Bits.AbstractStorageDecl.OpaqueReadOwnership =
4148+
unsigned(OpaqueReadOwnership::Owned);
41454149
}
41464150

41474151
void setSupportsMutationIfStillStored(StorageIsMutable_t supportsMutation) {
@@ -4211,7 +4215,15 @@ class AbstractStorageDecl : public ValueDecl {
42114215
bool hasAnyAccessors() const {
42124216
return !getAllAccessors().empty();
42134217
}
4214-
4218+
4219+
/// \brief Return the ownership of values opaquely read from this storage.
4220+
OpaqueReadOwnership getOpaqueReadOwnership() const {
4221+
return OpaqueReadOwnership(Bits.AbstractStorageDecl.OpaqueReadOwnership);
4222+
}
4223+
void setOpaqueReadOwnership(OpaqueReadOwnership ownership) {
4224+
Bits.AbstractStorageDecl.OpaqueReadOwnership = unsigned(ownership);
4225+
}
4226+
42154227
/// \brief Return true if reading this storage requires the ability to
42164228
/// modify the base value.
42174229
bool isGetterMutating() const {
@@ -4267,11 +4279,30 @@ class AbstractStorageDecl : public ValueDecl {
42674279
/// \brief Add a synthesized setter.
42684280
void setSynthesizedSetter(AccessorDecl *setter);
42694281

4270-
/// \brief Add a synthesized materializeForSet accessor.
4271-
void setSynthesizedMaterializeForSet(AccessorDecl *materializeForSet);
4282+
/// \brief Add a synthesized read coroutine.
4283+
void setSynthesizedReadCoroutine(AccessorDecl *read);
4284+
4285+
/// \brief Add a synthesized modify coroutine.
4286+
void setSynthesizedModifyCoroutine(AccessorDecl *modify);
4287+
4288+
/// Does this storage require an opaque accessor of the given kind?
4289+
bool requiresOpaqueAccessor(AccessorKind kind) const;
42724290

4273-
/// Does this storage require a materializeForSet accessor?
4274-
bool requiresMaterializeForSet() const;
4291+
/// Does this storage require a 'get' accessor in its opaque-accessors set?
4292+
bool requiresOpaqueGetter() const {
4293+
return getOpaqueReadOwnership() != OpaqueReadOwnership::Borrowed;
4294+
}
4295+
4296+
/// Does this storage require a 'read' accessor in its opaque-accessors set?
4297+
bool requiresOpaqueReadCoroutine() const {
4298+
return getOpaqueReadOwnership() != OpaqueReadOwnership::Owned;
4299+
}
4300+
4301+
/// Does this storage require a 'set' accessor in its opaque-accessors set?
4302+
bool requiresOpaqueSetter() const { return supportsMutation(); }
4303+
4304+
/// Does this storage require a 'modify' accessor in its opaque-accessors set?
4305+
bool requiresOpaqueModifyCoroutine() const;
42754306

42764307
SourceRange getBracesRange() const {
42774308
if (auto info = Accessors.getPointer())
@@ -4298,12 +4329,6 @@ class AbstractStorageDecl : public ValueDecl {
42984329

42994330
void overwriteSetterAccess(AccessLevel accessLevel);
43004331

4301-
/// \brief Retrieve the materializeForSet function, if this
4302-
/// declaration has one.
4303-
AccessorDecl *getMaterializeForSetFunc() const {
4304-
return getAccessor(AccessorKind::MaterializeForSet);
4305-
}
4306-
43074332
/// \brief Return the decl for the immutable addressor if it exists.
43084333
AccessorDecl *getAddressor() const {
43094334
return getAccessor(AccessorKind::Address);
@@ -5571,9 +5596,6 @@ class AccessorDecl final : public FuncDecl {
55715596

55725597
bool isGetter() const { return getAccessorKind() == AccessorKind::Get; }
55735598
bool isSetter() const { return getAccessorKind() == AccessorKind::Set; }
5574-
bool isMaterializeForSet() const {
5575-
return getAccessorKind() == AccessorKind::MaterializeForSet;
5576-
}
55775599
bool isAnyAddressor() const {
55785600
auto kind = getAccessorKind();
55795601
return kind == AccessorKind::Address
@@ -6471,8 +6493,6 @@ AbstractStorageDecl::overwriteSetterAccess(AccessLevel accessLevel) {
64716493
Accessors.setInt(accessLevel);
64726494
if (auto setter = getSetter())
64736495
setter->overwriteAccess(accessLevel);
6474-
if (auto materializeForSet = getMaterializeForSetFunc())
6475-
materializeForSet->overwriteAccess(accessLevel);
64766496
if (auto modify = getModifyCoroutine())
64776497
modify->overwriteAccess(accessLevel);
64786498
if (auto mutableAddressor = getMutableAddressor())

include/swift/AST/DiagnosticsParse.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,8 +262,8 @@ ERROR(conflicting_accessor,none,
262262
(unsigned, StringRef, StringRef))
263263
NOTE(previous_accessor,none,
264264
"%select{|previous definition of }1%0 %select{defined |}1here", (StringRef, bool))
265-
ERROR(expected_accessor_name,none,
266-
"expected %select{%error|setter|%error|willSet|didSet}0 parameter name",
265+
ERROR(expected_accessor_parameter_name,none,
266+
"expected %select{setter|willSet|didSet}0 parameter name",
267267
(unsigned))
268268
ERROR(expected_rparen_set_name,none,
269269
"expected ')' after setter parameter name",())

include/swift/AST/DiagnosticsSIL.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ ERROR(inout_argument_alias,none,
8989
NOTE(previous_inout_alias,none,
9090
"previous aliasing argument", ())
9191

92+
ERROR(unimplemented_generator_witnesses,none,
93+
"protocol conformance emission for generator coroutines is unimplemented",
94+
())
95+
9296
WARNING(exclusivity_access_required_warn,none,
9397
"overlapping accesses to %0, but "
9498
"%select{initialization|read|modification|deinitialization}1 requires "

include/swift/AST/Stmt.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,8 @@ class YieldStmt final
237237

238238
public:
239239
static YieldStmt *create(const ASTContext &ctx, SourceLoc yieldLoc,
240-
SourceLoc lp, ArrayRef<Expr*> yields, SourceLoc rp);
240+
SourceLoc lp, ArrayRef<Expr*> yields, SourceLoc rp,
241+
Optional<bool> implicit = None);
241242

242243
SourceLoc getYieldLoc() const { return YieldLoc; }
243244
SourceLoc getLParenLoc() const { return LPLoc; }

include/swift/AST/StorageImpl.h

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,18 @@ enum StorageIsMutable_t : bool {
2727
StorageIsMutable = true
2828
};
2929

30+
enum class OpaqueReadOwnership : uint8_t {
31+
/// An opaque read produces an owned value.
32+
Owned,
33+
34+
/// An opaque read produces a borrowed value.
35+
Borrowed,
36+
37+
/// An opaque read can be either owned or borrowed, depending on the
38+
/// preference of the caller.
39+
OwnedOrBorrowed
40+
};
41+
3042
// Note that the values of these enums line up with %select values in
3143
// diagnostics.
3244
enum class AccessorKind {
@@ -220,10 +232,6 @@ enum class ReadWriteImplKind {
220232
/// There's storage.
221233
Stored,
222234

223-
/// There's a materializeForSet. (This is currently only used for opaque
224-
/// declarations.)
225-
MaterializeForSet,
226-
227235
/// There's a mutable addressor.
228236
MutableAddress,
229237

@@ -289,7 +297,6 @@ class StorageImplInfo {
289297
readImpl == ReadImplKind::Address ||
290298
readImpl == ReadImplKind::Read);
291299
assert(readWriteImpl == ReadWriteImplKind::MaterializeToTemporary ||
292-
readWriteImpl == ReadWriteImplKind::MaterializeForSet ||
293300
readWriteImpl == ReadWriteImplKind::Modify);
294301
return;
295302

@@ -319,20 +326,21 @@ class StorageImplInfo {
319326
: ReadWriteImplKind::Immutable };
320327
}
321328

322-
static StorageImplInfo getOpaque(StorageIsMutable_t isMutable) {
323-
return (isMutable ? getMutableOpaque()
324-
: getImmutableOpaque());
329+
static StorageImplInfo getOpaque(StorageIsMutable_t isMutable,
330+
OpaqueReadOwnership ownership) {
331+
return (isMutable ? getMutableOpaque(ownership)
332+
: getImmutableOpaque(ownership));
325333
}
326334

327335
/// Describe the implementation of a immutable property implemented opaquely.
328-
static StorageImplInfo getImmutableOpaque() {
329-
return { ReadImplKind::Get };
336+
static StorageImplInfo getImmutableOpaque(OpaqueReadOwnership ownership) {
337+
return { getOpaqueReadImpl(ownership) };
330338
}
331339

332340
/// Describe the implementation of a mutable property implemented opaquely.
333-
static StorageImplInfo getMutableOpaque() {
334-
return { ReadImplKind::Get, WriteImplKind::Set,
335-
ReadWriteImplKind::MaterializeForSet };
341+
static StorageImplInfo getMutableOpaque(OpaqueReadOwnership ownership) {
342+
return { getOpaqueReadImpl(ownership), WriteImplKind::Set,
343+
ReadWriteImplKind::Modify };
336344
}
337345

338346
static StorageImplInfo getComputed(StorageIsMutable_t isMutable) {
@@ -379,6 +387,18 @@ class StorageImplInfo {
379387
ReadWriteImplKind getReadWriteImpl() const {
380388
return ReadWriteImplKind(ReadWrite);
381389
}
390+
391+
private:
392+
static ReadImplKind getOpaqueReadImpl(OpaqueReadOwnership ownership) {
393+
switch (ownership) {
394+
case OpaqueReadOwnership::Owned:
395+
return ReadImplKind::Get;
396+
case OpaqueReadOwnership::OwnedOrBorrowed:
397+
case OpaqueReadOwnership::Borrowed:
398+
return ReadImplKind::Read;
399+
}
400+
llvm_unreachable("bad read-ownership kind");
401+
}
382402
};
383403

384404
} // end namespace swift

include/swift/SIL/SILType.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,10 @@ NON_SIL_TYPE(LValue)
563563

564564
CanSILFunctionType getNativeSILFunctionType(
565565
SILModule &M, Lowering::AbstractionPattern origType,
566-
CanAnyFunctionType substType, Optional<SILDeclRef> constant = None,
566+
CanAnyFunctionType substType,
567+
Optional<SILDeclRef> origConstant = None,
568+
Optional<SILDeclRef> constant = None,
569+
Optional<SubstitutionMap> reqtSubs = None,
567570
Optional<ProtocolConformanceRef> witnessMethodConformance = None);
568571

569572
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, SILType T) {

include/swift/SIL/TypeLowering.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -807,15 +807,6 @@ class TypeConverter {
807807

808808
SILType getLoweredTypeOfGlobal(VarDecl *var);
809809

810-
/// The return type of a materializeForSet contains a callback
811-
/// whose type cannot be represented in the AST because it is
812-
/// a polymorphic function value. This function returns the
813-
/// unsubstituted lowered type of this callback.
814-
CanSILFunctionType getMaterializeForSetCallbackType(
815-
AbstractStorageDecl *storage, CanGenericSignature genericSig,
816-
Type selfType, SILFunctionTypeRepresentation rep,
817-
Optional<ProtocolConformanceRef> witnessMethodConformance);
818-
819810
/// Return the SILFunctionType for a native function value of the
820811
/// given type.
821812
CanSILFunctionType getSILFunctionType(AbstractionPattern origType,

include/swift/Serialization/ModuleFile.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,7 @@ class ModuleFile
574574

575575
/// Sets the accessors for \p storage based on \p rawStorageKind.
576576
void configureStorage(AbstractStorageDecl *storage,
577+
uint8_t rawOpaqueReadOwnership,
577578
uint8_t rawReadImpl,
578579
uint8_t rawWriteImpl,
579580
uint8_t rawReadWriteImpl,

0 commit comments

Comments
 (0)