summaryrefslogtreecommitdiff
path: root/source/slang/slang-ir-lower-generics.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2021-10-21 15:51:18 -0700
committerGitHub <noreply@github.com>2021-10-21 15:51:18 -0700
commit9304c2d04c9bfbae33cc328d404b24aba375aa4f (patch)
tree88473d2ca0b03341f84bca17b359ae45c4becfaa /source/slang/slang-ir-lower-generics.cpp
parent66e319e34b99eff0a8d27be524ab4a831437ac1b (diff)
Diagnostic for no type conformance + bug fix. (#1985)
* Diagnostic for no type conformance + bug fix. * Fixes. * Fix. * Include heterogeneous example only with --enable-experimental-projects premake flag Co-authored-by: Yong He <yhe@nvidia.com> Co-authored-by: jsmall-nvidia <jsmall@nvidia.com>
Diffstat (limited to 'source/slang/slang-ir-lower-generics.cpp')
-rw-r--r--source/slang/slang-ir-lower-generics.cpp32
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