diff options
Diffstat (limited to 'source/slang/slang-ir-lower-generics.cpp')
| -rw-r--r-- | source/slang/slang-ir-lower-generics.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/source/slang/slang-ir-lower-generics.cpp b/source/slang/slang-ir-lower-generics.cpp index 241827561..95046787a 100644 --- a/source/slang/slang-ir-lower-generics.cpp +++ b/source/slang/slang-ir-lower-generics.cpp @@ -117,6 +117,36 @@ namespace Slang cleanUpInterfaceTypes(sharedContext); } + void checkTypeConformanceExists(SharedGenericsLoweringContext* context) + { + HashSet<IRInst*> implementedInterfaces; + + // Add all interface type that are implemented by at least one type to a set. + for (auto inst : context->module->getGlobalInsts()) + { + if (inst->getOp() == kIROp_WitnessTable) + { + auto interfaceType = cast<IRWitnessTableType>(inst->getDataType())->getConformanceType(); + implementedInterfaces.Add(interfaceType); + } + } + // Check if an interface type has any implementations. + workOnModule(context, [&](IRInst* inst) + { + if (auto lookupWitnessMethod = as<IRLookupWitnessMethod>(inst)) + { + auto witnessTableType = lookupWitnessMethod->getWitnessTable()->getDataType(); + auto interfaceType = cast<IRWitnessTableType>(witnessTableType)->getConformanceType(); + if (!implementedInterfaces.Contains(interfaceType)) + { + context->sink->diagnose(interfaceType->sourceLoc, Diagnostics::noTypeConformancesFoundForInterface, interfaceType); + // Add to set to prevent duplicate diagnostic messages. + implementedInterfaces.Add(interfaceType); + } + } + }); + } + void lowerGenerics( TargetRequest* targetReq, IRModule* module, @@ -127,6 +157,8 @@ namespace Slang sharedContext.module = module; sharedContext.sink = sink; + checkTypeConformanceExists(&sharedContext); + // Replace all `makeExistential` insts with `makeExistentialWithRTTI` // before making any other changes. This is necessary because a parameter of // generic type will be lowered into `AnyValueType`, and after that we can no longer |
