@@ -3194,6 +3194,11 @@ emitKeyPathRValueBase(SILGenFunction &subSGF,
31943194 auto paramSubstValue = subSGF.emitOrigToSubstValue (loc, paramOrigValue,
31953195 AbstractionPattern::getOpaque (),
31963196 baseType);
3197+
3198+ // If base is a metatype, it cannot be opened as an existential or upcasted
3199+ // from a class.
3200+ if (baseType->is <MetatypeType>())
3201+ return paramSubstValue;
31973202
31983203 // Pop open an existential container base.
31993204 if (baseType->isAnyExistentialType ()) {
@@ -4031,9 +4036,30 @@ getIdForKeyPathComponentComputedProperty(SILGenModule &SGM,
40314036 AbstractStorageDecl *storage,
40324037 ResilienceExpansion expansion,
40334038 AccessStrategy strategy) {
4039+ auto getAccessorFunction = [&SGM](AbstractStorageDecl *storage,
4040+ bool isForeign) -> SILFunction * {
4041+ // Identify the property using its (unthunked) getter. For a
4042+ // computed property, this should be stable ABI; for a resilient public
4043+ // property, this should also be stable ABI across modules.
4044+ auto representativeDecl = getRepresentativeAccessorForKeyPath (storage);
4045+ // If the property came from an import-as-member function defined in C,
4046+ // use the original C function as the key.
4047+ auto ref =
4048+ SILDeclRef (representativeDecl, SILDeclRef::Kind::Func, isForeign);
4049+ // TODO: If the getter has shared linkage (say it's synthesized for a
4050+ // Clang-imported thing), we'll need some other sort of
4051+ // stable identifier.
4052+ return SGM.getFunction (ref, NotForDefinition);
4053+ };
4054+
40344055 switch (strategy.getKind ()) {
40354056 case AccessStrategy::Storage:
4036- // Identify reabstracted stored properties by the property itself.
4057+ if (auto decl = cast<VarDecl>(storage); decl->isStatic ()) {
4058+ // For metatype keypaths, identify property via accessors.
4059+ return getAccessorFunction (storage, /* isForeign=*/ false );
4060+ }
4061+ // Otherwise, identify reabstracted stored properties by the property
4062+ // itself.
40374063 return cast<VarDecl>(storage);
40384064 case AccessStrategy::MaterializeToTemporary:
40394065 // Use the read strategy. But try to avoid turning e.g. an
@@ -4046,19 +4072,9 @@ getIdForKeyPathComponentComputedProperty(SILGenModule &SGM,
40464072 }
40474073 LLVM_FALLTHROUGH;
40484074 case AccessStrategy::DirectToAccessor: {
4049- // Identify the property using its (unthunked) getter. For a
4050- // computed property, this should be stable ABI; for a resilient public
4051- // property, this should also be stable ABI across modules.
4052- auto representativeDecl = getRepresentativeAccessorForKeyPath (storage);
4053- // If the property came from an import-as-member function defined in C,
4054- // use the original C function as the key.
4055- bool isForeign = representativeDecl->isImportAsMember ();
4056- auto getterRef = SILDeclRef (representativeDecl,
4057- SILDeclRef::Kind::Func, isForeign);
4058- // TODO: If the getter has shared linkage (say it's synthesized for a
4059- // Clang-imported thing), we'll need some other sort of
4060- // stable identifier.
4061- return SGM.getFunction (getterRef, NotForDefinition);
4075+ return getAccessorFunction (
4076+ storage,
4077+ getRepresentativeAccessorForKeyPath (storage)->isImportAsMember ());
40624078 }
40634079 case AccessStrategy::DispatchToAccessor: {
40644080 // Identify the property by its vtable or wtable slot.
0 commit comments