diff options
| author | Yong He <yonghe@outlook.com> | 2022-09-13 18:58:05 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-09-13 18:58:05 -0700 |
| commit | 05f9aaf6a4ef246dcf89b00000a8e59e90c47662 (patch) | |
| tree | f4c94d339066c9700bf0d806acd2b6d2647f3256 | |
| parent | f216b77752b9e4aea52882b2110ceb1cc64a2171 (diff) | |
Allow interface requirements to reference to the interface type itself. (#2398)
* Allow interface requirements to reference to the interface type itself.
* add comment explaining the change.
Co-authored-by: Yong He <yhe@nvidia.com>
| -rw-r--r-- | source/slang/slang-check-expr.cpp | 2 | ||||
| -rw-r--r-- | source/slang/slang-syntax.cpp | 46 | ||||
| -rw-r--r-- | source/slang/slang.natvis | 11 | ||||
| -rw-r--r-- | tests/bugs/interface-type-self-ref.slang | 32 | ||||
| -rw-r--r-- | tests/bugs/interface-type-self-ref.slang.expected.txt | 5 |
5 files changed, 77 insertions, 19 deletions
diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp index 4d55669e2..b988fac60 100644 --- a/source/slang/slang-check-expr.cpp +++ b/source/slang/slang-check-expr.cpp @@ -157,8 +157,6 @@ namespace Slang openedType->originalInterfaceType = expr->type.type; openedType->originalInterfaceDeclRef = interfaceDeclRef; - DeclRef<InterfaceDecl> substDeclRef = openedType->getSpecializedInterfaceDeclRef(); - ExtractExistentialValueExpr* openedValue = m_astBuilder->create<ExtractExistentialValueExpr>(); openedValue->declRef = varDeclRef; openedValue->type = QualType(openedType); diff --git a/source/slang/slang-syntax.cpp b/source/slang/slang-syntax.cpp index 9a7200e9d..5b4b61849 100644 --- a/source/slang/slang-syntax.cpp +++ b/source/slang/slang-syntax.cpp @@ -838,28 +838,40 @@ Index getFilterCountImpl(const ReflectClassInfo& clsInfo, MemberFilterStyle filt // Otherwise, check if we are trying to apply // a this-type substitution to the given interface // - for(auto s = substsToApply; s; s = s->outer) + // Note: We want to skip the ThisTypeSubstitution that specializes + // declToSpecialize itself (when declToSpecialize is an interface + // decl and the subst specializes it), and only pull the + // ThisTypeSubstitution when the decl is referencing a child of + // the interface decl being specialized. This is because + // by default an interface declref type is a "free" existential + // type that shouldn't be specialized by someone else, unless + // there is an "implicit" ThisType reference preceeding a child + // reference. + if (declToSpecialize != ancestorInterfaceDecl) { - auto appThisTypeSubst = as<ThisTypeSubstitution>(s); - if(!appThisTypeSubst) - continue; + for (auto s = substsToApply; s; s = s->outer) + { + auto appThisTypeSubst = as<ThisTypeSubstitution>(s); + if (!appThisTypeSubst) + continue; - if(appThisTypeSubst->interfaceDecl != ancestorInterfaceDecl) - continue; + if (appThisTypeSubst->interfaceDecl != ancestorInterfaceDecl) + continue; - int diff = 0; - auto restSubst = specializeSubstitutions( - astBuilder, - ancestorInterfaceDecl->parentDecl, - substsToSpecialize, - substsToApply, - &diff); + int diff = 0; + auto restSubst = specializeSubstitutions( + astBuilder, + ancestorInterfaceDecl->parentDecl, + substsToSpecialize, + substsToApply, + &diff); - ThisTypeSubstitution* firstSubst = astBuilder->getOrCreateThisTypeSubstitution( - ancestorInterfaceDecl, appThisTypeSubst->witness, restSubst); + ThisTypeSubstitution* firstSubst = astBuilder->getOrCreateThisTypeSubstitution( + ancestorInterfaceDecl, appThisTypeSubst->witness, restSubst); - (*ioDiff)++; - return firstSubst; + (*ioDiff)++; + return firstSubst; + } } } } diff --git a/source/slang/slang.natvis b/source/slang/slang.natvis index 4d5bad2d3..6c8f15ec9 100644 --- a/source/slang/slang.natvis +++ b/source/slang/slang.natvis @@ -239,6 +239,7 @@ <ExpandedItem Condition="astNodeType == Slang::ASTNodeType::AndTypeExpr">(Slang::AndTypeExpr*)&astNodeType</ExpandedItem> <ExpandedItem Condition="astNodeType == Slang::ASTNodeType::ModifiedTypeExpr">(Slang::ModifiedTypeExpr*)&astNodeType</ExpandedItem> <ExpandedItem Condition="astNodeType == Slang::ASTNodeType::PointerTypeExpr">(Slang::PointerTypeExpr*)&astNodeType</ExpandedItem> + <Item Name="[type]">type</Item> <Item Name="[Expr]">(Slang::Expr*)this,nd</Item> </Expand> </Type> @@ -477,4 +478,14 @@ <Item Name="[Members]">members</Item> </Expand> </Type> + <Type Name="Slang::Val" Inheritable="false"> + <DisplayString>{astNodeType}</DisplayString> + <Expand> + <ExpandedItem Condition="astNodeType == Slang::ASTNodeType::ConstantIntVal">(Slang::ConstantIntVal*)&astNodeType</ExpandedItem> + <ExpandedItem Condition="astNodeType == Slang::ASTNodeType::PolynomialIntVal">(Slang::PolynomialIntVal*)&astNodeType</ExpandedItem> + <ExpandedItem Condition="astNodeType == Slang::ASTNodeType::GenericParamIntVal">(Slang::GenericParamIntVal*)&astNodeType</ExpandedItem> + <ExpandedItem Condition="astNodeType == Slang::ASTNodeType::DeclaredSubtypeWitness">(Slang::DeclaredSubtypeWitness*)&astNodeType</ExpandedItem> + <ExpandedItem Condition="astNodeType == Slang::ASTNodeType::TransitiveSubtypeWitness">(Slang::TransitiveSubtypeWitness*)&astNodeType</ExpandedItem> + </Expand> + </Type> </AutoVisualizer>
\ No newline at end of file diff --git a/tests/bugs/interface-type-self-ref.slang b/tests/bugs/interface-type-self-ref.slang new file mode 100644 index 000000000..e3b1fe7cc --- /dev/null +++ b/tests/bugs/interface-type-self-ref.slang @@ -0,0 +1,32 @@ +//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -shaderobj -output-using-type + +//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name outputBuffer +RWStructuredBuffer<int> outputBuffer; + +interface IFoo +{ + int compute(out IFoo param); +} + +struct Impl : IFoo +{ + int compute(out IFoo param) + { + param = this; + return 0; + } +} + +int f(IFoo p) +{ + IFoo r; + return p.compute(r); +} + +[numthreads(4, 1, 1)] +void computeMain(int3 dispatchThreadID: SV_DispatchThreadID) +{ + int index = dispatchThreadID.x; + Impl impl; + outputBuffer[index] = f(impl); +} diff --git a/tests/bugs/interface-type-self-ref.slang.expected.txt b/tests/bugs/interface-type-self-ref.slang.expected.txt new file mode 100644 index 000000000..b9efb5a97 --- /dev/null +++ b/tests/bugs/interface-type-self-ref.slang.expected.txt @@ -0,0 +1,5 @@ +type: int32_t +0 +0 +0 +0 |
