diff options
| author | Yong He <yonghe@outlook.com> | 2020-06-25 18:26:12 -0700 |
|---|---|---|
| committer | Yong He <yonghe@outlook.com> | 2020-06-25 18:26:12 -0700 |
| commit | 5b571955403b7562e62681157bb166b35c5d2e7b (patch) | |
| tree | 9bc18cedc7d70637647aafad730d4ed36d41e612 | |
| parent | 09c64acde25dddbd70e2070df05c2e0362b750a8 (diff) | |
Fixes.
| -rw-r--r-- | source/slang/slang-ir.h | 1 | ||||
| -rw-r--r-- | source/slang/slang-lower-to-ir.cpp | 28 |
2 files changed, 24 insertions, 5 deletions
diff --git a/source/slang/slang-ir.h b/source/slang/slang-ir.h index dadcce386..f3eccad25 100644 --- a/source/slang/slang-ir.h +++ b/source/slang/slang-ir.h @@ -1209,6 +1209,7 @@ struct IRInterfaceRequirementEntry : IRInst { IRInst* getRequirementKey() { return getOperand(0); } IRInst* getRequirementVal() { return getOperand(1); } + void setRequirementKey(IRInst* val) { setOperand(0, val); } void setRequirementVal(IRInst* val) { setOperand(1, val); } IR_LEAF_ISA(InterfaceRequirementEntry); diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index ebc2e1b74..f95ffff81 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -5306,6 +5306,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo> // Setup subContext for proper lowering `ThisType`, associated types and // the interface decl's self reference. subContext->thisType = getBuilder()->getThisType(); + // Create a temporary IR value for self references, this will be replaced // by actual interface type after we create the actual interface type. auto temporarySelf = subBuilder->createIntrinsicInst(nullptr, kIROp_undefined, 0, nullptr); @@ -5322,15 +5323,29 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo> for (auto requirementDecl : decl->members) { - auto key = getInterfaceRequirementKey(requirementDecl); + auto entry = subBuilder->createInterfaceRequirementEntry( + getInterfaceRequirementKey(requirementDecl), + nullptr); IRInst* requirementVal = lowerDecl(subContext, requirementDecl).val; if (requirementVal) { auto reqType = requirementVal->getFullType(); - requirementVal->removeAndDeallocate(); - requirementVal = reqType; + entry->setRequirementVal(reqType); + if (!requirementVal->hasUses()) + { + // Remove lowered `IRFunc`s since we only care about + // function types. + switch (requirementVal->op) + { + case kIROp_Func: + case kIROp_Generic: + requirementVal->removeAndDeallocate(); + break; + default: + break; + } + } } - auto entry = subBuilder->createInterfaceRequirementEntry(key, requirementVal); requirementEntries.add(entry); // As a special case, any type constraints placed // on an associated type will *also* need to be turned @@ -5345,7 +5360,10 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo> getBuilder()->getWitnessTableType(lowerType(context, constraintDecl->getSup().type)))); } } - context->env->mapDeclToValue[requirementDecl] = LoweredValInfo::simple(entry); + // Add lowered requirement entry to current decl mapping to prevent + // the function requirements from being lowered again when we get to + // `ensureAllDeclsRec`. + setValue(context, requirementDecl, LoweredValInfo::simple(entry)); } IRInterfaceType* irInterface = subBuilder->createInterfaceType( |
