@@ -547,6 +547,14 @@ class EmitPolymorphicParameters : public PolymorphicConvention {
547
547
// Did the convention decide that the parameter at the given index
548
548
// was a class-pointer source?
549
549
bool isClassPointerSource (unsigned paramIndex);
550
+
551
+ // If we are building a protocol witness thunk for a
552
+ // `DistributedActorSystem.remoteCall` requirement we
553
+ // need to supply witness tables associated with `Res`
554
+ // generic parameter which are not expressible on the
555
+ // requirement because they come from `SerializationRequirement`
556
+ // associated type.
557
+ void injectAdHocDistributedRemoteCallRequirements ();
550
558
};
551
559
552
560
} // end anonymous namespace
@@ -722,6 +730,40 @@ bool EmitPolymorphicParameters::isClassPointerSource(unsigned paramIndex) {
722
730
return false ;
723
731
}
724
732
733
+ void EmitPolymorphicParameters::injectAdHocDistributedRemoteCallRequirements () {
734
+ // FIXME: We need a better way to recognize that function is
735
+ // a thunk for witness of `remoteCall` requirement.
736
+ if (!Fn.hasLocation ())
737
+ return ;
738
+
739
+ auto loc = Fn.getLocation ();
740
+
741
+ auto *funcDecl = dyn_cast_or_null<FuncDecl>(loc.getAsDeclContext ());
742
+ if (!(funcDecl && funcDecl->isDistributedActorSystemRemoteCall (
743
+ /* isVoidReturn=*/ false )))
744
+ return ;
745
+
746
+ auto sig = funcDecl->getGenericSignature ();
747
+ auto resultInterfaceTy = funcDecl->getResultInterfaceType ();
748
+ auto resultArchetypeTy =
749
+ getTypeInContext (resultInterfaceTy->getCanonicalType ());
750
+ llvm::Value *resultMetadata = IGF.emitTypeMetadataRef (resultArchetypeTy);
751
+
752
+ auto resultRequirements = sig->getLocalRequirements (resultInterfaceTy);
753
+ for (auto *proto : resultRequirements.protos ) {
754
+ // Lookup the witness table for this protocol dynamically via
755
+ // swift_conformsToProtocol(<<archetype>>, <<protocol>>)
756
+ auto *witnessTable = IGF.Builder .CreateCall (
757
+ IGM.getConformsToProtocolFunctionPointer (),
758
+ {resultMetadata, IGM.getAddrOfProtocolDescriptor (proto)});
759
+
760
+ IGF.setUnscopedLocalTypeData (
761
+ resultArchetypeTy,
762
+ LocalTypeDataKind::forAbstractProtocolWitnessTable (proto),
763
+ witnessTable);
764
+ }
765
+ }
766
+
725
767
namespace {
726
768
727
769
// / A class for binding type parameters of a generic function.
@@ -2574,6 +2616,9 @@ void EmitPolymorphicParameters::emit(EntryPointArgumentEmission &emission,
2574
2616
2575
2617
// Bind all the fulfillments we can from the formal parameters.
2576
2618
bindParameterSources (getParameter);
2619
+
2620
+ // Inject ad-hoc `remoteCall` requirements if any.
2621
+ injectAdHocDistributedRemoteCallRequirements ();
2577
2622
}
2578
2623
2579
2624
MetadataResponse
0 commit comments