@@ -2843,13 +2843,27 @@ static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM,
28432843 auto subscriptIndices =
28442844 loadIndexValuesForKeyPathComponent (subSGF, loc, property,
28452845 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+
28532867 if (resultSubst.getType ().getAddressType () != resultArg->getType ())
28542868 resultSubst = subSGF.emitSubstToOrigValue (loc, resultSubst,
28552869 AbstractionPattern::getOpaque (),
@@ -3561,6 +3575,12 @@ SILGenModule::emitKeyPathComponentForDecl(SILLocation loc,
35613575 ->mapTypeOutOfContext ()
35623576 ->getCanonicalType (
35633577 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+ }
35643584 }
35653585
35663586 if (canStorageUseStoredKeyPathComponent (var, expansion)) {
0 commit comments