Skip to content

Commit cf66563

Browse files
Fix exact-match witness synthesis for static functions (shader-slang#6204)
* fix non-static methods when trying to synthesize method requirement witness * add tests * update test * improve test --------- Co-authored-by: Yong He <[email protected]>
1 parent 1f99c20 commit cf66563

4 files changed

+103
-0
lines changed

source/slang/slang-check-decl.cpp

+25
Original file line numberDiff line numberDiff line change
@@ -4621,6 +4621,25 @@ static bool matchParamDirection(ParameterDirection implDir, ParameterDirection r
46214621
return false;
46224622
}
46234623

4624+
static void removeNonStaticLookupItems(LookupResult& lookupResult)
4625+
{
4626+
List<LookupResultItem> newItems;
4627+
for (auto item : lookupResult)
4628+
{
4629+
if (item.declRef.getDecl()->hasModifier<HLSLStaticModifier>())
4630+
{
4631+
newItems.add(item);
4632+
}
4633+
}
4634+
4635+
lookupResult.items = newItems;
4636+
lookupResult.item = LookupResultItem();
4637+
if (lookupResult.items.getCount() > 0)
4638+
{
4639+
lookupResult.item = lookupResult.items[0];
4640+
}
4641+
}
4642+
46244643
bool SemanticsVisitor::trySynthesizeMethodRequirementWitness(
46254644
ConformanceCheckingContext* context,
46264645
LookupResult const& lookupResult,
@@ -4724,6 +4743,12 @@ bool SemanticsVisitor::trySynthesizeMethodRequirementWitness(
47244743
baseOverloadedExpr->lookupResult2 = lookupResult;
47254744
}
47264745

4746+
// Non-static methods cannot implement static methods, remove them.
4747+
if (requiredMemberDeclRef.getDecl()->hasModifier<HLSLStaticModifier>())
4748+
{
4749+
removeNonStaticLookupItems(baseOverloadedExpr->lookupResult2);
4750+
}
4751+
47274752
// If `synThis` is non-null, then we will use it as the base of
47284753
// the overloaded expression, so that we have an overloaded
47294754
// member reference, and not just an overloaded reference to some
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//TEST(compute):COMPARE_COMPUTE_EX:-vk -compute -output-using-type
2+
3+
//TEST_INPUT: set outputBuffer = out ubuffer(data=[0 0 0 0 0], stride=4);
4+
RWStructuredBuffer<int> outputBuffer;
5+
6+
interface Base
7+
{
8+
int getValue();
9+
int getValue(float a);
10+
}
11+
12+
struct Impl1 : Base
13+
{
14+
// This is static and allowed to implement interface's non-static method.
15+
static int getValue() { return 5; }
16+
int getValue(float a) { return int(a) + 5; }
17+
}
18+
19+
struct Impl2 : Base
20+
{
21+
// This is static with one default parameter and allowed to implement interface's non-static method.
22+
static int getValue(int a = 3) { return a + 5; }
23+
int getValue(float a) { return int(a) + 5; }
24+
}
25+
26+
int callGet<T : Base>(T t)
27+
{
28+
return t.getValue();
29+
}
30+
31+
[numthreads(1, 1, 1)]
32+
void computeMain()
33+
{
34+
Impl1 impl1;
35+
Impl2 impl2;
36+
37+
uint index = 0;
38+
39+
outputBuffer[index++] = Impl1::getValue();
40+
outputBuffer[index++] = callGet(impl1);
41+
42+
outputBuffer[index++] = Impl2::getValue();
43+
outputBuffer[index++] = callGet(impl2);
44+
outputBuffer[index++] = impl2.getValue(5);
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
type: int32_t
2+
5
3+
5
4+
8
5+
8
6+
10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): -target spirv
2+
3+
interface Base
4+
{
5+
static int getValue();
6+
}
7+
8+
struct Impl : Base
9+
{
10+
// This is not static and not allowed to implement the interface's static method.
11+
// CHECK: error 38105: member 'getValue' does not match interface requirement
12+
int getValue() { return 5; }
13+
}
14+
15+
int callGet<Foo : Base>()
16+
{
17+
return Foo::getValue();
18+
}
19+
20+
RWStructuredBuffer<int> result;
21+
22+
[numthreads(1, 1, 1)]
23+
void computeMain()
24+
{
25+
result[0] = callGet<Impl>();
26+
}
27+

0 commit comments

Comments
 (0)