@@ -880,7 +880,28 @@ struct SpecializationContext
880880 IRInst* satisfyingVal = nullptr ;
881881
882882 if (witnessTable)
883- satisfyingVal = findWitnessVal (witnessTable, requirementKey);
883+ {
884+ satisfyingVal = findWitnessTableEntry (witnessTable, requirementKey);
885+ if (const auto genericEntry = as<IRGeneric>(satisfyingVal))
886+ {
887+ IRBuilder builder (module );
888+ // Collect generic params.
889+ List<IRInst*> genericParams;
890+ for (auto param : genericEntry->getParams ())
891+ genericParams.add (param);
892+
893+ auto specializedFuncType = builder.emitSpecializeInst (
894+ builder.getTypeKind (),
895+ genericEntry->getFullType (),
896+ (UInt)genericParams.getCount (),
897+ genericParams.getBuffer ());
898+ satisfyingVal = builder.emitSpecializeInst (
899+ (IRType*)specializedFuncType,
900+ genericEntry,
901+ (UInt)genericParams.getCount (),
902+ genericParams.getBuffer ());
903+ }
904+ }
884905 else
885906 {
886907 // If we are specializing ThisTypeWitness, the result of the specialization
@@ -935,27 +956,6 @@ struct SpecializationContext
935956 return instChanged;
936957 }
937958
938- // The above subroutine needed a way to look up
939- // the satisfying value for a given requirement
940- // key in a concrete witness table, so let's
941- // define that now.
942- //
943- IRInst* findWitnessVal (IRWitnessTable* witnessTable, IRInst* requirementKey)
944- {
945- // A witness table is basically just a container
946- // for key-value pairs, and so the best we can
947- // do for now is a naive linear search.
948- //
949- for (auto entry : witnessTable->getEntries ())
950- {
951- if (requirementKey == entry->getRequirementKey ())
952- {
953- return entry->getSatisfyingVal ();
954- }
955- }
956- return nullptr ;
957- }
958-
959959 template <typename TDict>
960960 void _readSpecializationDictionaryImpl (TDict& dict, IRInst* dictInst)
961961 {
0 commit comments