Skip to content

Commit 00729ad

Browse files
authored
Merge pull request #67107 from xedin/setterless-init-accessor-properties
[SILGen/DI] Add support for init accessor properties without setters
2 parents b3cdcda + a3e8bb6 commit 00729ad

File tree

11 files changed

+481
-165
lines changed

11 files changed

+481
-165
lines changed

include/swift/SIL/SILInstruction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4873,6 +4873,7 @@ class AssignOrInitInst
48734873
ArrayRef<Operand> getAllOperands() const { return Operands.asArray(); }
48744874
MutableArrayRef<Operand> getAllOperands() { return Operands.asArray(); }
48754875

4876+
StringRef getPropertyName() const;
48764877
AccessorDecl *getReferencedInitAccessor() const;
48774878
};
48784879

lib/AST/Decl.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2413,10 +2413,15 @@ getDirectReadAccessStrategy(const AbstractStorageDecl *storage) {
24132413
static AccessStrategy
24142414
getDirectWriteAccessStrategy(const AbstractStorageDecl *storage) {
24152415
switch (storage->getWriteImpl()) {
2416-
case WriteImplKind::Immutable:
2416+
case WriteImplKind::Immutable: {
2417+
if (storage->hasInitAccessor())
2418+
return AccessStrategy::getAccessor(AccessorKind::Init,
2419+
/*dispatch=*/false);
2420+
24172421
assert(isa<VarDecl>(storage) && cast<VarDecl>(storage)->isLet() &&
24182422
"mutation of a immutable variable that isn't a let");
24192423
return AccessStrategy::getStorage();
2424+
}
24202425
case WriteImplKind::Stored:
24212426
return AccessStrategy::getStorage();
24222427
case WriteImplKind::StoredWithObservers:
@@ -2493,7 +2498,9 @@ getOpaqueReadAccessStrategy(const AbstractStorageDecl *storage, bool dispatch) {
24932498
}
24942499

24952500
static AccessStrategy
2496-
getOpaqueWriteAccessStrategy(const AbstractStorageDecl *storage, bool dispatch){
2501+
getOpaqueWriteAccessStrategy(const AbstractStorageDecl *storage, bool dispatch) {
2502+
if (storage->hasInitAccessor() && !storage->getAccessor(AccessorKind::Set))
2503+
return AccessStrategy::getAccessor(AccessorKind::Init, dispatch);
24972504
return AccessStrategy::getAccessor(AccessorKind::Set, dispatch);
24982505
}
24992506

@@ -6827,8 +6834,17 @@ bool VarDecl::isSettable(const DeclContext *UseDC,
68276834

68286835
// If this is a 'var' decl, then we're settable if we have storage or a
68296836
// setter.
6830-
if (!isLet())
6837+
if (!isLet()) {
6838+
if (hasInitAccessor()) {
6839+
if (auto *ctor = dyn_cast_or_null<ConstructorDecl>(UseDC)) {
6840+
if (base && ctor->getImplicitSelfDecl() != base->getDecl())
6841+
return supportsMutation();
6842+
return true;
6843+
}
6844+
}
6845+
68316846
return supportsMutation();
6847+
}
68326848

68336849
// Static 'let's are always immutable.
68346850
if (isStatic()) {

lib/SIL/IR/SILInstructions.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,6 +1290,12 @@ bool AssignOrInitInst::isPropertyAlreadyInitialized(unsigned propertyIdx) {
12901290
return Assignments.test(propertyIdx);
12911291
}
12921292

1293+
StringRef AssignOrInitInst::getPropertyName() const {
1294+
auto *accessor = getReferencedInitAccessor();
1295+
assert(accessor);
1296+
return cast<VarDecl>(accessor->getStorage())->getNameStr();
1297+
}
1298+
12931299
AccessorDecl *AssignOrInitInst::getReferencedInitAccessor() const {
12941300
SILValue initRef = getInitializer();
12951301
SILFunction *accessorFn = nullptr;

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2736,6 +2736,9 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
27362736
checkAssigOrInitInstAccessorArgs(Src->getType(), initConv);
27372737
}
27382738

2739+
if (isa<SILUndef>(setterFn))
2740+
return;
2741+
27392742
// Check setter - it's a partially applied reference which takes
27402743
// `initialValue`.
27412744
CanSILFunctionType setterTy = setterFn->getType().castTo<SILFunctionType>();

lib/SILGen/LValue.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ class PathComponent {
115115
WritebackPseudoKind, // a fake component to customize writeback
116116
OpenNonOpaqueExistentialKind, // opened class or metatype existential
117117
LogicalKeyPathApplicationKind, // applying a key path
118+
InitAccessorKind, // init accessor
118119

119120
// Translation LValue kinds (a subtype of logical)
120121
OrigToSubstKind, // generic type substitution

0 commit comments

Comments
 (0)