@@ -2843,13 +2843,27 @@ static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM,
2843
2843
auto subscriptIndices =
2844
2844
loadIndexValuesForKeyPathComponent (subSGF, loc, property,
2845
2845
indexes, indexPtrArg);
2846
-
2847
- auto resultSubst = subSGF.emitRValueForStorageLoad (loc, baseSubstValue,
2848
- baseType, /* super*/ false ,
2849
- property, std::move (subscriptIndices),
2850
- subs, AccessSemantics::Ordinary,
2851
- propertyType, SGFContext ())
2852
- .getAsSingleValue (subSGF, loc);
2846
+
2847
+ ManagedValue resultSubst;
2848
+ {
2849
+ RValue resultRValue;
2850
+
2851
+ // Emit a dynamic method branch if the storage decl is an @objc optional
2852
+ // requirement, or just a load otherwise.
2853
+ if (property->getAttrs ().hasAttribute <OptionalAttr>() &&
2854
+ isa<VarDecl>(property)) {
2855
+ resultRValue = subSGF.emitDynamicMemberRef (
2856
+ loc, baseSubstValue.getValue (), ConcreteDeclRef (property, subs),
2857
+ propertyType, SGFContext ());
2858
+ } else {
2859
+ resultRValue = subSGF.emitRValueForStorageLoad (
2860
+ loc, baseSubstValue, baseType, /* super*/ false , property,
2861
+ std::move (subscriptIndices), subs, AccessSemantics::Ordinary,
2862
+ propertyType, SGFContext ());
2863
+ }
2864
+ resultSubst = std::move (resultRValue).getAsSingleValue (subSGF, loc);
2865
+ }
2866
+
2853
2867
if (resultSubst.getType ().getAddressType () != resultArg->getType ())
2854
2868
resultSubst = subSGF.emitSubstToOrigValue (loc, resultSubst,
2855
2869
AbstractionPattern::getOpaque (),
@@ -3561,6 +3575,12 @@ SILGenModule::emitKeyPathComponentForDecl(SILLocation loc,
3561
3575
->mapTypeOutOfContext ()
3562
3576
->getCanonicalType (
3563
3577
genericEnv ? genericEnv->getGenericSignature () : nullptr );
3578
+
3579
+ // The component type for an @objc optional requirement needs to be
3580
+ // wrapped in an optional.
3581
+ if (var->getAttrs ().hasAttribute <OptionalAttr>()) {
3582
+ componentTy = OptionalType::get (componentTy)->getCanonicalType ();
3583
+ }
3564
3584
}
3565
3585
3566
3586
if (canStorageUseStoredKeyPathComponent (var, expansion)) {
0 commit comments