Skip to content

Commit 140ee56

Browse files
authored
Merge pull request #18840 from rjmccall/dematerializeForSet
Replace materializeForSet with the modify coroutine
2 parents 2412376 + b80618f commit 140ee56

File tree

108 files changed

+2497
-3563
lines changed

Some content is hidden

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

108 files changed

+2497
-3563
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: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -796,23 +796,17 @@ class TypeConverter {
796796
return ti.getLoweredType();
797797
}
798798

799-
AbstractionPattern getAbstractionPattern(AbstractStorageDecl *storage);
800-
AbstractionPattern getAbstractionPattern(VarDecl *var);
801-
AbstractionPattern getAbstractionPattern(SubscriptDecl *subscript);
799+
AbstractionPattern getAbstractionPattern(AbstractStorageDecl *storage,
800+
bool isNonObjC = false);
801+
AbstractionPattern getAbstractionPattern(VarDecl *var,
802+
bool isNonObjC = false);
803+
AbstractionPattern getAbstractionPattern(SubscriptDecl *subscript,
804+
bool isNonObjC = false);
802805
AbstractionPattern getIndicesAbstractionPattern(SubscriptDecl *subscript);
803806
AbstractionPattern getAbstractionPattern(EnumElementDecl *element);
804807

805808
SILType getLoweredTypeOfGlobal(VarDecl *var);
806809

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

0 commit comments

Comments
 (0)