@@ -3583,21 +3583,47 @@ SILGenModule::emitKeyPathComponentForDecl(SILLocation loc,
35833583 // / Returns true if a key path component for the given property or
35843584 // / subscript should be externally referenced.
35853585 auto shouldUseExternalKeyPathComponent = [&]() -> bool {
3586- return (!forPropertyDescriptor &&
3587- (baseDecl->getModuleContext () != SwiftModule ||
3588- baseDecl->isResilient (SwiftModule, expansion)) &&
3589- // Protocol requirements don't have nor need property descriptors.
3590- !isa<ProtocolDecl>(baseDecl->getDeclContext ()) &&
3591- // Properties that only dispatch via ObjC lookup do not have nor
3592- // need property descriptors, since the selector identifies the
3593- // storage.
3594- // Properties that are not public don't need property descriptors
3595- // either.
3596- (!baseDecl->requiresOpaqueAccessors () ||
3597- (!getAccessorDeclRef (getRepresentativeAccessorForKeyPath (baseDecl))
3598- .isForeign &&
3599- getAccessorDeclRef (getRepresentativeAccessorForKeyPath (baseDecl))
3600- .getLinkage (ForDefinition) <= SILLinkage::PublicNonABI)));
3586+ // The property descriptor has the canonical key path component information
3587+ // so doesn't have to refer to another external descriptor.
3588+ if (forPropertyDescriptor) {
3589+ return false ;
3590+ }
3591+
3592+ // Don't need to use the external component if we're inside the resilience
3593+ // domain of its defining module.
3594+ if (baseDecl->getModuleContext () == SwiftModule
3595+ && !baseDecl->isResilient (SwiftModule, expansion)) {
3596+ return false ;
3597+ }
3598+
3599+ // Protocol requirements don't have nor need property descriptors.
3600+ if (isa<ProtocolDecl>(baseDecl->getDeclContext ())) {
3601+ return false ;
3602+ }
3603+
3604+ // Always-emit-into-client properties can't reliably refer to a property
3605+ // descriptor that may not exist in older versions of their home dylib.
3606+ // Their definition is also always entirely visible to clients so it isn't
3607+ // needed.
3608+ if (baseDecl->getAttrs ().hasAttribute <AlwaysEmitIntoClientAttr>()) {
3609+ return false ;
3610+ }
3611+
3612+ // Properties that only dispatch via ObjC lookup do not have nor
3613+ // need property descriptors, since the selector identifies the
3614+ // storage.
3615+ // Properties that are not public don't need property descriptors
3616+ // either.
3617+ if (baseDecl->requiresOpaqueAccessors ()) {
3618+ auto representative = getAccessorDeclRef (
3619+ getRepresentativeAccessorForKeyPath (baseDecl));
3620+ if (representative.isForeign )
3621+ return false ;
3622+ if (representative.getLinkage (ForDefinition) > SILLinkage::PublicNonABI)
3623+ return false ;
3624+ }
3625+
3626+ return true ;
36013627 };
36023628
36033629 auto strategy = storage->getAccessStrategy (AccessSemantics::Ordinary,
0 commit comments