Skip to content

Commit ff44ccc

Browse files
authored
Merge pull request #25645 from jckarter/external-keypath-override-5.1
[5.1] Judge the need for an external key path reference by the overridden base.
2 parents 1b13705 + f73cd75 commit ff44ccc

File tree

2 files changed

+27
-10
lines changed

2 files changed

+27
-10
lines changed

lib/SILGen/SILGenExpr.cpp

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3419,23 +3419,32 @@ SILGenModule::emitKeyPathComponentForDecl(SILLocation loc,
34193419
ArrayRef<ProtocolConformanceRef> indexHashables,
34203420
CanType baseTy,
34213421
bool forPropertyDescriptor) {
3422+
auto baseDecl = storage;
3423+
3424+
// ABI-compatible overrides do not have property descriptors, so we need
3425+
// to reference the overridden declaration instead.
3426+
if (isa<ClassDecl>(baseDecl->getDeclContext())) {
3427+
while (!baseDecl->isValidKeyPathComponent())
3428+
baseDecl = baseDecl->getOverriddenDecl();
3429+
}
3430+
34223431
/// Returns true if a key path component for the given property or
34233432
/// subscript should be externally referenced.
34243433
auto shouldUseExternalKeyPathComponent = [&]() -> bool {
34253434
return (!forPropertyDescriptor &&
3426-
(storage->getModuleContext() != SwiftModule ||
3427-
storage->isResilient(SwiftModule, expansion)) &&
3435+
(baseDecl->getModuleContext() != SwiftModule ||
3436+
baseDecl->isResilient(SwiftModule, expansion)) &&
34283437
// Protocol requirements don't have nor need property descriptors.
3429-
!isa<ProtocolDecl>(storage->getDeclContext()) &&
3438+
!isa<ProtocolDecl>(baseDecl->getDeclContext()) &&
34303439
// Properties that only dispatch via ObjC lookup do not have nor
34313440
// need property descriptors, since the selector identifies the
34323441
// storage.
34333442
// Properties that are not public don't need property descriptors
34343443
// either.
3435-
(!storage->hasAnyAccessors() ||
3436-
(!getAccessorDeclRef(getRepresentativeAccessorForKeyPath(storage))
3444+
(!baseDecl->hasAnyAccessors() ||
3445+
(!getAccessorDeclRef(getRepresentativeAccessorForKeyPath(baseDecl))
34373446
.isForeign &&
3438-
getAccessorDeclRef(getRepresentativeAccessorForKeyPath(storage))
3447+
getAccessorDeclRef(getRepresentativeAccessorForKeyPath(baseDecl))
34393448
.getLinkage(ForDefinition) <= SILLinkage::PublicNonABI)));
34403449
};
34413450

@@ -3465,10 +3474,7 @@ SILGenModule::emitKeyPathComponentForDecl(SILLocation loc,
34653474

34663475
// ABI-compatible overrides do not have property descriptors, so we need
34673476
// to reference the overridden declaration instead.
3468-
auto *baseDecl = externalDecl;
3469-
if (isa<ClassDecl>(baseDecl->getDeclContext())) {
3470-
while (!baseDecl->isValidKeyPathComponent())
3471-
baseDecl = baseDecl->getOverriddenDecl();
3477+
if (baseDecl != externalDecl) {
34723478
externalSubs = SubstitutionMap::getOverrideSubstitutions(baseDecl,
34733479
externalDecl,
34743480
externalSubs);

test/SILGen/keypaths_objc.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,14 @@ func sharedCProperty() {
102102
// CHECK-NOT: external #c_union.some_field
103103
let dataKeyPath: WritableKeyPath<c_union, some_struct>? = \c_union.some_field
104104
}
105+
106+
class OverrideFrameworkObjCProperty: A {
107+
override var counter: Int32 {
108+
get { return 0 }
109+
set { }
110+
}
111+
}
112+
113+
func overrideFrameworkObjCProperty() {
114+
let _ = \OverrideFrameworkObjCProperty.counter
115+
}

0 commit comments

Comments
 (0)