From f9f6a28df40f418ddd0c8ff3b9cacccdb085e202 Mon Sep 17 00:00:00 2001 From: Yong He Date: Tue, 20 Aug 2024 20:51:57 -0700 Subject: Support dependent generic constraints. (#4870) * Support dependent generic constraints. * Fix warning. * Update comment. * Fix. * Add a test case to verify fix of #3804. * Address review. --- source/slang/slang-lower-to-ir.cpp | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) (limited to 'source/slang/slang-lower-to-ir.cpp') diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index 44c62e858..2828752a0 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -9304,15 +9304,46 @@ struct DeclLoweringVisitor : DeclVisitor auto typeGeneric = typeBuilder.emitGeneric(); typeGeneric->setFullType(typeBuilder.getGenericKind()); typeBuilder.setInsertInto(typeGeneric); - typeBuilder.emitBlock(); + auto block = typeBuilder.emitBlock(); + struct ParamCloneInfo + { + IRParam* originalParam; + IRParam* clonedParam; + }; + ShortList paramCloneInfos; + for (auto child : parentGeneric->getFirstBlock()->getChildren()) { if (valuesToClone.contains(child)) { - cloneInst(&cloneEnv, &typeBuilder, child); + if (child->getOp() == kIROp_Param) + { + // Params may have forward references in its type and + // decorations, so we just create a placeholder for it + // in this first pass. + IRParam* clonedParam = typeBuilder.emitParam(nullptr); + cloneEnv.mapOldValToNew[child] = clonedParam; + paramCloneInfos.add({ (IRParam*)child, clonedParam }); + } + else + { + cloneInst(&cloneEnv, &typeBuilder, child); + } } } + + // In a second pass, clone the types and decorations on params which may + // contain forward references. + for (auto param : paramCloneInfos) + { + typeBuilder.setInsertInto(param.clonedParam); + param.clonedParam->setFullType((IRType*)cloneInst(&cloneEnv, &typeBuilder, param.originalParam->getFullType())); + cloneInstDecorationsAndChildren(&cloneEnv, typeBuilder.getModule(), param.originalParam, param.clonedParam); + } + + typeBuilder.setInsertInto(block); + IRInst* clonedReturnType = nullptr; cloneEnv.mapOldValToNew.tryGetValue(returnType, clonedReturnType); if (clonedReturnType) -- cgit v1.2.3