summaryrefslogtreecommitdiff
path: root/source/slang/slang-lower-to-ir.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2023-11-07 19:03:52 -0800
committerGitHub <noreply@github.com>2023-11-07 19:03:52 -0800
commit0f2578d7b3e75c0e5ef724ffe610d004fb116a03 (patch)
treed8bbe837a35377a64508b0c34c34feb6da43e02e /source/slang/slang-lower-to-ir.cpp
parent421941993d169c943f2c364bfe9c48b603339fd1 (diff)
Add `IRThisTypeWitness` to stand in for witness lookups inside an interface definition. (#3316)
Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'source/slang/slang-lower-to-ir.cpp')
-rw-r--r--source/slang/slang-lower-to-ir.cpp43
1 files changed, 22 insertions, 21 deletions
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp
index 8851195b3..b2c0dbb18 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -1659,17 +1659,7 @@ struct ValLoweringVisitor : ValVisitor<ValLoweringVisitor, LoweredValInfo, Lower
// produce transitive witnesses in shapes that will cuase us
// problems here.
//
- if (!baseWitnessTable)
- {
- // If we don't have a valid baseWitnessTable,
- // This can happen when we are looking up an associatedtype defined in the base interface from
- // a derived interface that inherits the base interface.
- // For now, we just emit a null witness.
- // In the future, we may want to consider lower `ThisTypeConstraint` into IR as something like
- // `IRThisTypeWitness`, and emit an explicit lookup through that witness instead.
- SLANG_RELEASE_ASSERT(as<ThisType>(val->getSub()));
- return LoweredValInfo();
- }
+ SLANG_RELEASE_ASSERT(baseWitnessTable);
if (auto declaredMidToSup = as<DeclaredSubtypeWitness>(val->getMidToSup()))
{
@@ -1925,7 +1915,9 @@ struct ValLoweringVisitor : ValVisitor<ValLoweringVisitor, LoweredValInfo, Lower
// add them as operands of the IR type.
SubstitutionSet(type->getDeclRef()).forEachSubstitutionArg([&](Val* arg)
{
- operands.add(lowerVal(context, arg).val);
+ auto argVal = lowerVal(context, arg).val;
+ SLANG_ASSERT(argVal);
+ operands.add(argVal);
});
return getBuilder()->getType(
op,
@@ -7810,9 +7802,8 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
context->astBuilder,
createDefaultSpecializedDeclRef(subContext, nullptr, decl->getThisTypeDecl()));
subContext->thisType = thisType;
-
- // TODO: Need to add an appropriate stand-in witness here.
- subContext->thisTypeWitness = nullptr;
+ // Create a stand-in witness that represents `ThisType` conforms to the interface.
+ subContext->thisTypeWitness = subBuilder->createThisTypeWitness((IRType*)finalVal);
// Lower associated types first, so they can be referred to when lowering functions.
for (auto assocTypeDecl : decl->getMembersOfType<AssocTypeDecl>())
@@ -9712,6 +9703,15 @@ static void _addFlattenedTupleArgs(
}
}
+bool isAbstractWitnessTable(IRInst* inst)
+{
+ if (as<IRThisTypeWitness>(inst))
+ return true;
+ if (auto lookup = as<IRLookupWitnessMethod>(inst))
+ return isAbstractWitnessTable(lookup->getWitnessTable());
+ return false;
+}
+
LoweredValInfo emitDeclRef(
IRGenContext* context,
Decl* decl,
@@ -9853,25 +9853,26 @@ LoweredValInfo emitDeclRef(
// witness table for the concrete type that conforms to `ISomething<Foo>`.
//
auto irWitnessTable = lowerSimpleVal(context, thisTypeSubst->getWitness());
- if (!irWitnessTable)
+ if (isAbstractWitnessTable(irWitnessTable))
{
- // If `thisTypeSubst` doesn't lower into an IRWitnessTable,
+ // If `thisTypeSubst` doesn't lower into a concrete IRWitnessTable,
// this is a lookup of an interface requirement
// defined in some base interface from an interface type.
// For now we just lower that decl as if it is referenced
// from the same interface directly, e.g. a reference to
// IBase.AssocType from IDerived:IBase will be lowered as
// IRAssocType(IBase).
- // We may want to consider extend our IR representation to
- // have a `IRThisTypeWitness` object, so we can lower this case
- // into an explicit lookup from `IRThisTypeWitness`,
- // just like any other cases.
+ // We may want to consider unifying our IR representation to
+ // represent associated types with lookupWitness inst even inside
+ // interface definitions.
return emitDeclRef(
context,
createDefaultSpecializedDeclRef(context, nullptr, decl),
context->irBuilder->getTypeKind());
}
+ SLANG_RELEASE_ASSERT(irWitnessTable);
+
//
// The key to use for looking up the interface member is
// derived from the declaration.