diff options
| author | Yong He <yonghe@outlook.com> | 2023-11-07 19:03:52 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-11-07 19:03:52 -0800 |
| commit | 0f2578d7b3e75c0e5ef724ffe610d004fb116a03 (patch) | |
| tree | d8bbe837a35377a64508b0c34c34feb6da43e02e /source/slang/slang-lower-to-ir.cpp | |
| parent | 421941993d169c943f2c364bfe9c48b603339fd1 (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.cpp | 43 |
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. |
