@@ -216,7 +216,7 @@ static CanSILFunctionType getAccessorType(IRGenModule &IGM,
216
216
// A generic parameter that represents instance of invocation decoder.
217
217
auto *decoderType =
218
218
GenericTypeParamType::get (/* isTypeSequence=*/ false ,
219
- /* depth=*/ 0 , /* index=*/ 0 , Context);
219
+ /* depth=*/ 1 , /* index=*/ 0 , Context);
220
220
221
221
// decoder
222
222
parameters.push_back (GenericFunctionType::Param (
@@ -257,9 +257,27 @@ static CanSILFunctionType getAccessorType(IRGenModule &IGM,
257
257
.getProtocol (KnownProtocolKind::DistributedTargetInvocationDecoder)
258
258
->getDeclaredInterfaceType ();
259
259
260
- auto signature = GenericSignature::get (
261
- {decoderType},
262
- {{RequirementKind::Conformance, decoderType, decoderProtocolTy}});
260
+ // Build generic signature that includes all contextual generic parameters.
261
+ GenericSignature signature;
262
+ {
263
+ SmallVector<GenericTypeParamType *, 4 > genericParams;
264
+ SmallVector<Requirement, 4 > genericRequirements;
265
+
266
+ auto *actor = getDistributedActorOf (Target);
267
+ assert (actor);
268
+
269
+ for (auto *genericParam : actor->getInnermostGenericParamTypes ())
270
+ genericParams.push_back (genericParam);
271
+
272
+ // Add a generic parameter `D` which stands for decoder type in the
273
+ // accessor signature - `inout D`.
274
+ genericParams.push_back (decoderType);
275
+ // Add a requirement that decoder conforms to the expected protocol.
276
+ genericRequirements.push_back (
277
+ {RequirementKind::Conformance, decoderType, decoderProtocolTy});
278
+
279
+ signature = GenericSignature::get (genericParams, genericRequirements);
280
+ }
263
281
264
282
auto accessorTy = GenericFunctionType::get (
265
283
signature, parameters, Context.TheEmptyTupleType ,
@@ -572,6 +590,7 @@ void DistributedAccessor::emitReturn(llvm::Value *errorValue) {
572
590
}
573
591
574
592
void DistributedAccessor::emit () {
593
+ auto *actor = getDistributedActorOf (Target);
575
594
auto targetTy = Target->getLoweredFunctionType ();
576
595
SILFunctionConventions targetConv (targetTy, IGF.getSILModule ());
577
596
TypeExpansionContext expansionContext = IGM.getMaximalTypeExpansionContext ();
@@ -604,6 +623,13 @@ void DistributedAccessor::emit() {
604
623
auto *actorSelf = params.claimNext ();
605
624
// Metadata that represents passed in the invocation decoder.
606
625
auto *decoderType = params.claimNext ();
626
+
627
+ // If the distributed thunk is declarated in a protocol that conforms
628
+ // to `DistributedActor` protocol, there is an extract parameter that
629
+ // represents a type of protocol witness.
630
+ if (isa<ProtocolDecl>(actor))
631
+ (void )params.claimNext ();
632
+
607
633
// Witness table for decoder conformance to DistributedTargetInvocationDecoder
608
634
auto *decoderProtocolWitness = params.claimNext ();
609
635
@@ -657,11 +683,17 @@ void DistributedAccessor::emit() {
657
683
llvm::SmallVector<llvm::Type *, 4 > targetGenericArguments;
658
684
expandPolymorphicSignature (IGM, targetTy, targetGenericArguments);
659
685
660
- unsigned numGenericArgs = genericEnvironment->getGenericParams ().size ();
661
- unsigned expectedWitnessTables =
662
- targetGenericArguments.size () - numGenericArgs;
686
+ // Generic arguments associated with the distributed thunk directly
687
+ // e.g. `distributed func echo<T, U>(...)`
688
+ auto numDirectGenericArgs =
689
+ llvm::count_if (targetGenericArguments, [&](const llvm::Type *type) {
690
+ return type == IGM.TypeMetadataPtrTy ;
691
+ });
692
+
693
+ auto expectedWitnessTables =
694
+ targetGenericArguments.size () - numDirectGenericArgs;
663
695
664
- for (unsigned index = 0 ; index < numGenericArgs ; ++index) {
696
+ for (unsigned index = 0 ; index < numDirectGenericArgs ; ++index) {
665
697
auto offset =
666
698
Size (index * IGM.DataLayout .getTypeAllocSize (IGM.TypeMetadataPtrTy ));
667
699
auto alignment =
0 commit comments