summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2020-06-25 18:26:12 -0700
committerYong He <yonghe@outlook.com>2020-06-25 18:26:12 -0700
commit5b571955403b7562e62681157bb166b35c5d2e7b (patch)
tree9bc18cedc7d70637647aafad730d4ed36d41e612
parent09c64acde25dddbd70e2070df05c2e0362b750a8 (diff)
Fixes.
-rw-r--r--source/slang/slang-ir.h1
-rw-r--r--source/slang/slang-lower-to-ir.cpp28
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(