@@ -588,7 +588,7 @@ class Callee {
588
588
case Kind::IndirectValue:
589
589
assert (Substitutions.empty ());
590
590
return IndirectValue;
591
-
591
+ case Kind::EnumElement:
592
592
case Kind::StandaloneFunction: {
593
593
auto constantInfo = SGF.getConstantInfo (*constant);
594
594
SILValue ref = SGF.emitGlobalFunctionRef (Loc, *constant, constantInfo);
@@ -600,8 +600,6 @@ class Callee {
600
600
SGF.emitGlobalFunctionRef (Loc, *constant, constantInfo, true );
601
601
return ManagedValue::forUnmanaged (ref);
602
602
}
603
- case Kind::EnumElement:
604
- llvm_unreachable (" Should have been curried" );
605
603
case Kind::ClassMethod: {
606
604
auto methodTy = SGF.SGM .Types .getConstantOverrideType (*constant);
607
605
@@ -704,8 +702,11 @@ class Callee {
704
702
auto constantInfo = SGF.getConstantInfo (*constant);
705
703
return createCalleeTypeInfo (SGF, constant, constantInfo.getSILType ());
706
704
}
707
- case Kind::EnumElement:
708
- llvm_unreachable (" Should have been curried" );
705
+ case Kind::EnumElement: {
706
+ // Emit a direct call to the element constructor thunk.
707
+ auto constantInfo = SGF.getConstantInfo (*constant);
708
+ return createCalleeTypeInfo (SGF, constant, constantInfo.getSILType ());
709
+ }
709
710
case Kind::ClassMethod: {
710
711
auto constantInfo = SGF.SGM .Types .getConstantOverrideInfo (*constant);
711
712
return createCalleeTypeInfo (SGF, constant, constantInfo.getSILType ());
@@ -4526,18 +4527,23 @@ CallEmission::applyEnumElementConstructor(SGFContext C) {
4526
4527
ArgumentSource payload;
4527
4528
if (element->hasAssociatedValues ()) {
4528
4529
assert (uncurriedSites.size () == 2 );
4530
+ SmallVector<ManagedValue, 4 > argVals;
4531
+ auto resultFnType = cast<FunctionType>(formalResultType);
4532
+ auto arg = SGF.prepareEnumPayload (element, resultFnType,
4533
+ std::move (uncurriedSites[1 ]).forward ());
4534
+ payload = ArgumentSource (element, std::move (arg));
4529
4535
formalResultType = firstLevelResult.formalType .getResult ();
4530
4536
origFormalType = origFormalType.getFunctionResultType ();
4531
4537
claimNextParamClause (firstLevelResult.formalType );
4532
- payload = std::move (uncurriedSites[1 ]).forward ();
4533
4538
} else {
4534
4539
assert (uncurriedSites.size () == 1 );
4535
4540
}
4536
4541
4537
4542
assert (substFnType->getNumResults () == 1 );
4538
4543
(void )substFnType;
4539
4544
ManagedValue resultMV = SGF.emitInjectEnum (
4540
- uncurriedLoc, std::move (payload), SGF.getLoweredType (formalResultType),
4545
+ uncurriedLoc, std::move (payload),
4546
+ SGF.getLoweredType (formalResultType),
4541
4547
element, uncurriedContext);
4542
4548
firstLevelResult.value =
4543
4549
RValue (SGF, uncurriedLoc, formalResultType, resultMV);
@@ -5247,7 +5253,7 @@ void SILGenFunction::emitRawYield(SILLocation loc,
5247
5253
// / unnecessary copies by emitting the payload directly into the enum
5248
5254
// / payload, or into the box in the case of an indirect payload.
5249
5255
ManagedValue SILGenFunction::emitInjectEnum (SILLocation loc,
5250
- ArgumentSource payload,
5256
+ ArgumentSource && payload,
5251
5257
SILType enumTy,
5252
5258
EnumElementDecl *element,
5253
5259
SGFContext C) {
@@ -5290,8 +5296,8 @@ ManagedValue SILGenFunction::emitInjectEnum(SILLocation loc,
5290
5296
CleanupHandle uninitCleanup = enterDeallocBoxCleanup (box);
5291
5297
5292
5298
BoxInitialization dest (box, addr, uninitCleanup, initCleanup);
5293
-
5294
- std::move (payload). forwardInto (* this , origFormalType, &dest, payloadTL);
5299
+ std::move (payload). forwardInto (* this , origFormalType, &dest,
5300
+ payloadTL);
5295
5301
5296
5302
payloadMV = dest.getManagedBox ();
5297
5303
loweredPayloadType = payloadMV.getType ();
@@ -5325,8 +5331,7 @@ ManagedValue SILGenFunction::emitInjectEnum(SILLocation loc,
5325
5331
} else if (payloadTL.isLoadable ()) {
5326
5332
// The payload of this specific enum case might be loadable
5327
5333
// even if the overall enum is address-only.
5328
- payloadMV =
5329
- std::move (payload).getAsSingleValue (*this , origFormalType);
5334
+ payloadMV = std::move (payload).getAsSingleValue (*this , origFormalType);
5330
5335
B.emitStoreValueOperation (loc, payloadMV.forward (*this ), resultData,
5331
5336
StoreOwnershipQualifier::Init);
5332
5337
} else {
@@ -5967,6 +5972,36 @@ static void collectFakeIndexParameters(SILGenModule &SGM,
5967
5972
convention});
5968
5973
}
5969
5974
5975
+ static void emitPseudoFunctionArguments (SILGenFunction &SGF,
5976
+ CanFunctionType substFnType,
5977
+ SmallVectorImpl<ManagedValue> &outVals,
5978
+ ArgumentSource &&source) {
5979
+ auto substParams = substFnType->getParams ();
5980
+
5981
+ SmallVector<SILParameterInfo, 4 > substParamTys;
5982
+ for (auto substParam : substParams) {
5983
+ auto substParamType = substParam.getParameterType ()->getCanonicalType ();
5984
+ collectFakeIndexParameters (SGF.SGM , substParamType, substParamTys);
5985
+ }
5986
+
5987
+ SmallVector<ManagedValue, 4 > argValues;
5988
+ SmallVector<DelayedArgument, 2 > delayedArgs;
5989
+
5990
+ ArgEmitter emitter (SGF, SILFunctionTypeRepresentation::Thin,
5991
+ /* yield*/ false ,
5992
+ /* isForCoroutine*/ false , ClaimedParamsRef (substParamTys),
5993
+ argValues, delayedArgs,
5994
+ /* foreign error*/ None, ImportAsMemberStatus ());
5995
+
5996
+ emitter.emitTopLevel (std::move (source), AbstractionPattern (substFnType));
5997
+
5998
+ // TODO: do something to preserve LValues in the delayed arguments?
5999
+ if (!delayedArgs.empty ())
6000
+ emitDelayedArguments (SGF, delayedArgs, argValues);
6001
+
6002
+ outVals.swap (argValues);
6003
+ }
6004
+
5970
6005
PreparedArguments
5971
6006
SILGenFunction::prepareSubscriptIndices (SubscriptDecl *subscript,
5972
6007
SubstitutionMap subs,
@@ -5992,26 +6027,8 @@ SILGenFunction::prepareSubscriptIndices(SubscriptDecl *subscript,
5992
6027
5993
6028
auto substParams = substFnType->getParams ();
5994
6029
5995
- SmallVector<SILParameterInfo, 4 > substParamTys;
5996
- for (auto substParam : substParams) {
5997
- auto substParamType = substParam.getParameterType ()->getCanonicalType ();
5998
- collectFakeIndexParameters (SGM, substParamType, substParamTys);
5999
- }
6000
-
6001
6030
SmallVector<ManagedValue, 4 > argValues;
6002
- SmallVector<DelayedArgument, 2 > delayedArgs;
6003
-
6004
- ArgEmitter emitter (*this , SILFunctionTypeRepresentation::Thin,
6005
- /* yield*/ false ,
6006
- /* isForCoroutine*/ false , ClaimedParamsRef (substParamTys),
6007
- argValues, delayedArgs,
6008
- /* foreign error*/ None, ImportAsMemberStatus ());
6009
-
6010
- emitter.emitTopLevel (indexExpr, AbstractionPattern (substFnType));
6011
-
6012
- // TODO: do something to preserve LValues in the delayed arguments?
6013
- if (!delayedArgs.empty ())
6014
- emitDelayedArguments (*this , delayedArgs, argValues);
6031
+ emitPseudoFunctionArguments (*this , substFnType, argValues, indexExpr);
6015
6032
6016
6033
PreparedArguments result (substParams, /* isScalar=*/ false );
6017
6034
@@ -6029,6 +6046,19 @@ SILGenFunction::prepareSubscriptIndices(SubscriptDecl *subscript,
6029
6046
return result;
6030
6047
}
6031
6048
6049
+ RValue
6050
+ SILGenFunction::prepareEnumPayload (EnumElementDecl *element,
6051
+ CanFunctionType substFnType,
6052
+ ArgumentSource &&args) {
6053
+ SmallVector<ManagedValue, 4 > argValues;
6054
+ emitPseudoFunctionArguments (*this , substFnType, argValues, std::move (args));
6055
+
6056
+ auto payloadTy = AnyFunctionType::composeInput (getASTContext (),
6057
+ substFnType.getParams (),
6058
+ /* canonicalVararg*/ true );
6059
+ return RValue (*this , argValues, payloadTy->getCanonicalType ());
6060
+ }
6061
+
6032
6062
SILDeclRef SILGenModule::getAccessorDeclRef (AccessorDecl *accessor) {
6033
6063
return SILDeclRef (accessor, SILDeclRef::Kind::Func)
6034
6064
.asForeign (requiresForeignEntryPoint (accessor));
0 commit comments