@@ -2867,11 +2867,20 @@ static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM,
2867
2867
2868
2868
// Emit a dynamic method branch if the storage decl is an @objc optional
2869
2869
// requirement, or just a load otherwise.
2870
- if (property->getAttrs ().hasAttribute <OptionalAttr>() &&
2871
- isa<VarDecl>(property)) {
2872
- resultRValue = subSGF.emitDynamicMemberRef (
2873
- loc, baseSubstValue.getValue (), ConcreteDeclRef (property, subs),
2874
- propertyType, SGFContext ());
2870
+ if (property->getAttrs ().hasAttribute <OptionalAttr>()) {
2871
+ const auto declRef = ConcreteDeclRef (property, subs);
2872
+
2873
+ if (isa<VarDecl>(property)) {
2874
+ resultRValue =
2875
+ subSGF.emitDynamicMemberRef (loc, baseSubstValue.getValue (), declRef,
2876
+ propertyType, SGFContext ());
2877
+ } else {
2878
+ assert (isa<SubscriptDecl>(property));
2879
+
2880
+ resultRValue = subSGF.emitDynamicSubscriptGetterApply (
2881
+ loc, baseSubstValue.getValue (), declRef,
2882
+ std::move (subscriptIndices), propertyType, SGFContext ());
2883
+ }
2875
2884
} else {
2876
2885
resultRValue = subSGF.emitRValueForStorageLoad (
2877
2886
loc, baseSubstValue, baseType, /* super*/ false , property,
@@ -3635,8 +3644,14 @@ SILGenModule::emitKeyPathComponentForDecl(SILLocation loc,
3635
3644
baseSubscriptTy = genSubscriptTy->substGenericArgs (subs);
3636
3645
auto baseSubscriptInterfaceTy = cast<AnyFunctionType>(
3637
3646
baseSubscriptTy->mapTypeOutOfContext ()->getCanonicalType ());
3647
+
3638
3648
auto componentTy = baseSubscriptInterfaceTy.getResult ();
3639
-
3649
+ if (decl->getAttrs ().hasAttribute <OptionalAttr>()) {
3650
+ // The component type for an @objc optional requirement needs to be
3651
+ // wrapped in an optional
3652
+ componentTy = OptionalType::get (componentTy)->getCanonicalType ();
3653
+ }
3654
+
3640
3655
SmallVector<IndexTypePair, 4 > indexTypes;
3641
3656
lowerKeyPathSubscriptIndexTypes (*this , indexTypes,
3642
3657
decl, subs,
0 commit comments