@@ -846,8 +846,9 @@ static void getWitnessMethodSubstitutions(ApplySite AI, SILFunction *F,
846
846
// / Generate a new apply of a function_ref to replace an apply of a
847
847
// / witness_method when we've determined the actual function we'll end
848
848
// / up calling.
849
- static ApplySite devirtualizeWitnessMethod (ApplySite AI, SILFunction *F,
850
- ProtocolConformanceRef C) {
849
+ static DevirtualizationResult
850
+ devirtualizeWitnessMethod (ApplySite AI, SILFunction *F,
851
+ ProtocolConformanceRef C) {
851
852
// We know the witness thunk and the corresponding set of substitutions
852
853
// required to invoke the protocol method at this point.
853
854
auto &Module = AI.getModule ();
@@ -893,20 +894,38 @@ static ApplySite devirtualizeWitnessMethod(ApplySite AI, SILFunction *F,
893
894
auto ResultSILType = substConv.getSILResultType ();
894
895
ApplySite SAI;
895
896
896
- if (auto *A = dyn_cast<ApplyInst>(AI))
897
- SAI = Builder.createApply (Loc, FRI, SubstCalleeSILType,
898
- ResultSILType, NewSubs, Arguments,
899
- A->isNonThrowing ());
897
+ SILValue ResultValue;
898
+ if (auto *A = dyn_cast<ApplyInst>(AI)) {
899
+ auto *NewAI =
900
+ Builder.createApply (Loc, FRI, SubstCalleeSILType, ResultSILType,
901
+ NewSubs, Arguments, A->isNonThrowing ());
902
+ // Check if any casting is required for the return value.
903
+ ResultValue = castValueToABICompatibleType (&Builder, Loc, NewAI,
904
+ NewAI->getType (), AI.getType ());
905
+ SAI = ApplySite::isa (NewAI);
906
+ }
900
907
if (auto *TAI = dyn_cast<TryApplyInst>(AI))
901
908
SAI = Builder.createTryApply (Loc, FRI, SubstCalleeSILType,
902
909
NewSubs, Arguments,
903
910
TAI->getNormalBB (), TAI->getErrorBB ());
904
- if (auto *PAI = dyn_cast<PartialApplyInst>(AI))
905
- SAI = Builder.createPartialApply (Loc, FRI, SubstCalleeSILType,
906
- NewSubs, Arguments, PAI->getType ());
911
+ if (auto *PAI = dyn_cast<PartialApplyInst>(AI)) {
912
+ auto PartialApplyConvention = PAI->getType ()
913
+ .getSwiftRValueType ()
914
+ ->getAs <SILFunctionType>()
915
+ ->getCalleeConvention ();
916
+ auto PAIResultType = SILBuilder::getPartialApplyResultType (
917
+ SubstCalleeSILType, Arguments.size (), Module, {},
918
+ PartialApplyConvention);
919
+ auto *NewPAI = Builder.createPartialApply (
920
+ Loc, FRI, SubstCalleeSILType, NewSubs, Arguments, PAIResultType);
921
+ // Check if any casting is required for the return value.
922
+ ResultValue = castValueToABICompatibleType (
923
+ &Builder, Loc, NewPAI, NewPAI->getType (), PAI->getType ());
924
+ SAI = ApplySite::isa (NewPAI);
925
+ }
907
926
908
927
NumWitnessDevirt++;
909
- return SAI;
928
+ return std::make_pair (ResultValue, SAI) ;
910
929
}
911
930
912
931
static bool canDevirtualizeWitnessMethod (ApplySite AI) {
@@ -948,8 +967,7 @@ DevirtualizationResult swift::tryDevirtualizeWitnessMethod(ApplySite AI) {
948
967
AI.getModule ().lookUpFunctionInWitnessTable (WMI->getConformance (),
949
968
WMI->getMember ());
950
969
951
- auto Result = devirtualizeWitnessMethod (AI, F, WMI->getConformance ());
952
- return std::make_pair (Result.getInstruction (), Result);
970
+ return devirtualizeWitnessMethod (AI, F, WMI->getConformance ());
953
971
}
954
972
955
973
// ===----------------------------------------------------------------------===//
0 commit comments