@@ -216,7 +216,7 @@ static CanSILFunctionType getAccessorType(IRGenModule &IGM,
216216 // A generic parameter that represents instance of invocation decoder.
217217 auto *decoderType =
218218 GenericTypeParamType::get (/* isTypeSequence=*/ false ,
219- /* depth=*/ 0 , /* index=*/ 0 , Context);
219+ /* depth=*/ 1 , /* index=*/ 0 , Context);
220220
221221 // decoder
222222 parameters.push_back (GenericFunctionType::Param (
@@ -257,9 +257,27 @@ static CanSILFunctionType getAccessorType(IRGenModule &IGM,
257257 .getProtocol (KnownProtocolKind::DistributedTargetInvocationDecoder)
258258 ->getDeclaredInterfaceType ();
259259
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+ }
263281
264282 auto accessorTy = GenericFunctionType::get (
265283 signature, parameters, Context.TheEmptyTupleType ,
@@ -572,6 +590,7 @@ void DistributedAccessor::emitReturn(llvm::Value *errorValue) {
572590}
573591
574592void DistributedAccessor::emit () {
593+ auto *actor = getDistributedActorOf (Target);
575594 auto targetTy = Target->getLoweredFunctionType ();
576595 SILFunctionConventions targetConv (targetTy, IGF.getSILModule ());
577596 TypeExpansionContext expansionContext = IGM.getMaximalTypeExpansionContext ();
@@ -604,6 +623,13 @@ void DistributedAccessor::emit() {
604623 auto *actorSelf = params.claimNext ();
605624 // Metadata that represents passed in the invocation decoder.
606625 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+
607633 // Witness table for decoder conformance to DistributedTargetInvocationDecoder
608634 auto *decoderProtocolWitness = params.claimNext ();
609635
@@ -657,11 +683,17 @@ void DistributedAccessor::emit() {
657683 llvm::SmallVector<llvm::Type *, 4 > targetGenericArguments;
658684 expandPolymorphicSignature (IGM, targetTy, targetGenericArguments);
659685
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;
663695
664- for (unsigned index = 0 ; index < numGenericArgs ; ++index) {
696+ for (unsigned index = 0 ; index < numDirectGenericArgs ; ++index) {
665697 auto offset =
666698 Size (index * IGM.DataLayout .getTypeAllocSize (IGM.TypeMetadataPtrTy ));
667699 auto alignment =
0 commit comments