@@ -504,24 +504,6 @@ class Callee {
504
504
return SubstFormalInterfaceType;
505
505
}
506
506
507
- unsigned getParameterListCount () const {
508
- switch (kind) {
509
- case Kind::IndirectValue:
510
- return 1 ;
511
-
512
- case Kind::StandaloneFunction:
513
- case Kind::StandaloneFunctionDynamicallyReplaceableImpl:
514
- case Kind::EnumElement:
515
- case Kind::ClassMethod:
516
- case Kind::SuperMethod:
517
- case Kind::WitnessMethod:
518
- case Kind::DynamicMethod:
519
- return Constant.getParameterListCount ();
520
- }
521
-
522
- llvm_unreachable (" Unhandled Kind in switch." );
523
- }
524
-
525
507
bool requiresSelfValueForDispatch () const {
526
508
switch (kind) {
527
509
case Kind::IndirectValue:
@@ -847,22 +829,23 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
847
829
selfParam = std::move (theSelfParam);
848
830
}
849
831
850
- bool isSelfApplyOfMethod (ApplyExpr *e) {
851
- if (auto *selfApply = dyn_cast<ApplyExpr>(e->getFn ())) {
852
- if (auto *declRefExpr = dyn_cast<DeclRefExpr>(selfApply->getFn ()))
853
- return declRefExpr->getDecl ()->getNumCurryLevels () == 2 ;
854
-
855
- if (isa<OtherConstructorDeclRefExpr>(selfApply->getFn ()))
856
- return true ;
857
- }
858
-
859
- return false ;
832
+ bool isMethodSelfApply (Expr *e) {
833
+ return (isa<SelfApplyExpr>(e) &&
834
+ !isa<AutoClosureExpr>(
835
+ cast<SelfApplyExpr>(e)->getFn ()));
860
836
}
861
837
862
838
void decompose (ApplyExpr *e) {
839
+ if (isMethodSelfApply (e)) {
840
+ selfApply = e;
841
+
842
+ visit (selfApply->getFn ());
843
+ return ;
844
+ }
845
+
863
846
callSite = e;
864
847
865
- if (isSelfApplyOfMethod (e )) {
848
+ if (isMethodSelfApply (e-> getFn () )) {
866
849
selfApply = cast<ApplyExpr>(e->getFn ());
867
850
868
851
if (selfApply->isSuper ()) {
@@ -3659,10 +3642,11 @@ namespace {
3659
3642
class CallEmission {
3660
3643
SILGenFunction &SGF;
3661
3644
3662
- std::vector<CallSite> uncurriedSites;
3645
+ Optional<CallSite> selfArg;
3646
+ Optional<CallSite> callSite;
3647
+
3663
3648
Callee callee;
3664
3649
FormalEvaluationScope initialWritebackScope;
3665
- unsigned expectedSiteCount;
3666
3650
bool implicitlyAsync;
3667
3651
3668
3652
public:
@@ -3671,7 +3655,6 @@ class CallEmission {
3671
3655
FormalEvaluationScope &&writebackScope)
3672
3656
: SGF(SGF), callee(std::move(callee)),
3673
3657
initialWritebackScope (std::move(writebackScope)),
3674
- expectedSiteCount(callee.getParameterListCount()),
3675
3658
implicitlyAsync(false ) {}
3676
3659
3677
3660
// / A factory method for decomposing the apply expr \p e into a call
@@ -3682,8 +3665,8 @@ class CallEmission {
3682
3665
// / unevaluated arguments and their formal type.
3683
3666
void addCallSite (CallSite &&site) {
3684
3667
// Append to the main argument list if we have uncurry levels remaining.
3685
- assert (uncurriedSites. size () < expectedSiteCount );
3686
- uncurriedSites. push_back ( std::move (site) );
3668
+ assert (!callSite. hasValue () );
3669
+ callSite = std::move (site);
3687
3670
}
3688
3671
3689
3672
// / Add a level of function application by passing in its possibly
@@ -3694,12 +3677,14 @@ class CallEmission {
3694
3677
}
3695
3678
3696
3679
void addSelfParam (SILLocation loc,
3697
- ArgumentSource &&selfArg ,
3680
+ ArgumentSource &&self ,
3698
3681
AnyFunctionType::Param selfParam) {
3682
+ assert (!selfArg.hasValue ());
3683
+
3699
3684
PreparedArguments preparedSelf (llvm::ArrayRef<AnyFunctionType::Param>{selfParam});
3700
- preparedSelf.addArbitrary (std::move (selfArg ));
3685
+ preparedSelf.addArbitrary (std::move (self ));
3701
3686
3702
- addCallSite (loc, std::move (preparedSelf));
3687
+ selfArg = CallSite (loc, std::move (preparedSelf));
3703
3688
}
3704
3689
3705
3690
// / Is this a fully-applied enum element constructor call?
@@ -3860,8 +3845,6 @@ SILGenFunction::emitBeginApply(SILLocation loc, ManagedValue fn,
3860
3845
}
3861
3846
3862
3847
RValue CallEmission::applyFirstLevelCallee (SGFContext C) {
3863
- assert (uncurriedSites.size () == expectedSiteCount);
3864
-
3865
3848
// Check for a specialized emitter.
3866
3849
if (auto emitter = callee.getSpecializedEmitter (SGF.SGM )) {
3867
3850
return applySpecializedEmitter (emitter.getValue (), C);
@@ -3882,9 +3865,6 @@ RValue CallEmission::applyNormalCall(SGFContext C) {
3882
3865
auto formalType = callee.getSubstFormalType ();
3883
3866
auto origFormalType = callee.getOrigFormalType ();
3884
3867
3885
- bool isCurried = (uncurriedSites.size () < callee.getParameterListCount ());
3886
- assert (!isCurried);
3887
-
3888
3868
// Get the callee type information.
3889
3869
auto calleeTypeInfo = callee.getTypeInfo (SGF);
3890
3870
@@ -3904,17 +3884,17 @@ RValue CallEmission::applyNormalCall(SGFContext C) {
3904
3884
calleeTypeInfo.origResultType = origFormalType.getFunctionResultType ();
3905
3885
calleeTypeInfo.substResultType = formalType.getResult ();
3906
3886
3907
- if (uncurriedSites. size () == 2 ) {
3887
+ if (selfArg. hasValue () && callSite. hasValue () ) {
3908
3888
calleeTypeInfo.origResultType =
3909
3889
calleeTypeInfo.origResultType ->getFunctionResultType ();
3910
3890
calleeTypeInfo.substResultType =
3911
3891
cast<FunctionType>(calleeTypeInfo.substResultType ).getResult ();
3912
3892
}
3913
3893
3914
3894
ResultPlanPtr resultPlan = ResultPlanBuilder::computeResultPlan (
3915
- SGF, calleeTypeInfo, uncurriedSites. back (). Loc , uncurriedContext);
3895
+ SGF, calleeTypeInfo, callSite-> Loc , uncurriedContext);
3916
3896
3917
- ArgumentScope argScope (SGF, uncurriedSites. back (). Loc );
3897
+ ArgumentScope argScope (SGF, callSite-> Loc );
3918
3898
3919
3899
// Emit the arguments.
3920
3900
SmallVector<ManagedValue, 4 > uncurriedArgs;
@@ -3970,7 +3950,7 @@ RValue CallEmission::applyEnumElementConstructor(SGFContext C) {
3970
3950
// construction.
3971
3951
EnumElementDecl *element = callee.getEnumElementDecl ();
3972
3952
3973
- SILLocation uncurriedLoc = uncurriedSites[ 0 ]. Loc ;
3953
+ SILLocation uncurriedLoc = selfArg-> Loc ;
3974
3954
3975
3955
origFormalType = origFormalType.getFunctionResultType ();
3976
3956
CanType formalResultType = formalType.getResult ();
@@ -3980,21 +3960,20 @@ RValue CallEmission::applyEnumElementConstructor(SGFContext C) {
3980
3960
emitPseudoFunctionArguments (SGF,
3981
3961
AbstractionPattern (formalType),
3982
3962
formalType, metatypeVal,
3983
- std::move (uncurriedSites[ 0 ] ).forward ());
3963
+ std::move (*selfArg ).forward ());
3984
3964
assert (metatypeVal.size () == 1 );
3985
3965
3986
3966
3987
3967
// Get the payload argument.
3988
3968
ArgumentSource payload;
3989
3969
if (element->hasAssociatedValues ()) {
3990
- assert (uncurriedSites.size () == 2 );
3991
3970
SmallVector<ManagedValue, 4 > argVals;
3992
3971
auto resultFnType = cast<FunctionType>(formalResultType);
3993
3972
3994
3973
emitPseudoFunctionArguments (SGF,
3995
3974
AbstractionPattern (resultFnType),
3996
3975
resultFnType, argVals,
3997
- std::move (uncurriedSites[ 1 ] ).forward ());
3976
+ std::move (*callSite ).forward ());
3998
3977
3999
3978
auto payloadTy = AnyFunctionType::composeInput (SGF.getASTContext (),
4000
3979
resultFnType.getParams (),
@@ -4004,7 +3983,7 @@ RValue CallEmission::applyEnumElementConstructor(SGFContext C) {
4004
3983
formalResultType = cast<FunctionType>(formalResultType).getResult ();
4005
3984
origFormalType = origFormalType.getFunctionResultType ();
4006
3985
} else {
4007
- assert (uncurriedSites. size () == 1 );
3986
+ assert (!callSite. hasValue () );
4008
3987
}
4009
3988
4010
3989
ManagedValue resultMV = SGF.emitInjectEnum (
@@ -4038,13 +4017,13 @@ CallEmission::applySpecializedEmitter(SpecializedEmitter &specializedEmitter,
4038
4017
if (specializedEmitter.isEarlyEmitter ()) {
4039
4018
auto emitter = specializedEmitter.getEarlyEmitter ();
4040
4019
4041
- assert (uncurriedSites. size () == 1 );
4020
+ assert (!selfArg. hasValue () );
4042
4021
assert (!formalType->getExtInfo ().isThrowing ());
4043
- SILLocation uncurriedLoc = uncurriedSites[ 0 ]. Loc ;
4022
+ SILLocation uncurriedLoc = callSite-> Loc ;
4044
4023
4045
4024
// We should be able to enforce that these arguments are
4046
4025
// always still expressions.
4047
- PreparedArguments args = std::move (uncurriedSites[ 0 ] ).forward ();
4026
+ PreparedArguments args = std::move (*callSite ).forward ();
4048
4027
ManagedValue resultMV =
4049
4028
emitter (SGF, uncurriedLoc, callee.getSubstitutions (),
4050
4029
std::move (args), uncurriedContext);
@@ -4054,7 +4033,7 @@ CallEmission::applySpecializedEmitter(SpecializedEmitter &specializedEmitter,
4054
4033
Optional<ResultPlanPtr> resultPlan;
4055
4034
Optional<ArgumentScope> argScope;
4056
4035
Optional<CalleeTypeInfo> calleeTypeInfo;
4057
- SILLocation loc = uncurriedSites[ 0 ]. Loc ;
4036
+ SILLocation loc = callSite-> Loc ;
4058
4037
SILFunctionConventions substConv (substFnType, SGF.SGM .M );
4059
4038
4060
4039
// If we have a named builtin and have an indirect out parameter, compute a
@@ -4148,18 +4127,18 @@ ApplyOptions CallEmission::emitArgumentsForNormalApply(
4148
4127
SmallVector<SmallVector<ManagedValue, 4 >, 2 > args;
4149
4128
SmallVector<DelayedArgument, 2 > delayedArgs;
4150
4129
4151
- args.reserve (uncurriedSites. size () );
4130
+ args.reserve (selfArg. hasValue () ? 2 : 1 );
4152
4131
{
4153
4132
ParamLowering paramLowering (substFnType, SGF);
4154
4133
4155
4134
assert ((!foreign.error && !foreign.async )
4156
- || uncurriedSites. size () == 1
4157
- || (uncurriedSites. size () == 2 && substFnType->hasSelfParam ()));
4135
+ || !selfArg. hasValue ()
4136
+ || (selfArg. hasValue () && substFnType->hasSelfParam ()));
4158
4137
4159
- if (uncurriedSites. back (). isNoThrows ()) {
4138
+ if (callSite-> isNoThrows ()) {
4160
4139
options |= ApplyFlags::DoesNotThrow;
4161
4140
}
4162
- if (uncurriedSites. back (). isNoAsync ()) {
4141
+ if (callSite-> isNoAsync ()) {
4163
4142
options |= ApplyFlags::DoesNotAwait;
4164
4143
}
4165
4144
@@ -4172,27 +4151,30 @@ ApplyOptions CallEmission::emitArgumentsForNormalApply(
4172
4151
}
4173
4152
4174
4153
// Collect the arguments to the uncurried call.
4175
- for (auto &site : uncurriedSites) {
4176
- uncurriedLoc = site.Loc ;
4154
+ if (selfArg.hasValue ()) {
4177
4155
args.push_back ({});
4178
-
4179
- bool isParamSite = &site == &uncurriedSites.back ();
4180
4156
4181
- auto siteForeign = isParamSite
4182
- // Claim the foreign error and/or async argument(s) with the method
4183
- // formal params.
4184
- ? CalleeTypeInfo::ForeignInfo{foreign.error , foreign.async , {}}
4185
- // Claim the foreign "self" with the self param.
4186
- : CalleeTypeInfo::ForeignInfo{{}, {}, foreign.self };
4187
-
4188
- std::move (site).emit (SGF, origFormalType, substFnType, paramLowering,
4189
- args.back (), delayedArgs,
4190
- siteForeign);
4157
+ // Claim the foreign "self" with the self param.
4158
+ auto siteForeign = CalleeTypeInfo::ForeignInfo{{}, {}, foreign.self };
4159
+ std::move (*selfArg).emit (SGF, origFormalType, substFnType, paramLowering,
4160
+ args.back (), delayedArgs,
4161
+ siteForeign);
4191
4162
4192
4163
origFormalType = origFormalType.getFunctionResultType ();
4193
4164
}
4165
+
4166
+ args.push_back ({});
4167
+
4168
+ // Claim the foreign error and/or async argument(s) with the method
4169
+ // formal params.
4170
+ auto siteForeign =
4171
+ CalleeTypeInfo::ForeignInfo{foreign.error , foreign.async , {}};
4172
+ std::move (*callSite).emit (SGF, origFormalType, substFnType, paramLowering,
4173
+ args.back (), delayedArgs,
4174
+ siteForeign);
4194
4175
}
4195
- assert (uncurriedLoc);
4176
+
4177
+ uncurriedLoc = callSite->Loc ;
4196
4178
4197
4179
// Emit any delayed arguments: formal accesses to inout arguments, etc.
4198
4180
if (!delayedArgs.empty ()) {
0 commit comments