summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-09-19 15:44:32 -0700
committerGitHub <noreply@github.com>2024-09-19 15:44:32 -0700
commit26ca9c5b0657489f82a221c62903cbc802aaa6a0 (patch)
treea63a66e5794df44f2391d1f4a0a80d29ed08c40e /tests
parentdd3d80e61b316390a468a142de2be2fb85b73d0d (diff)
Synthesize conformance for generic requirements. (#5111)
* Synthesize conformance for generic requirements. * Fix. * Fix build error. * address code review.
Diffstat (limited to 'tests')
-rw-r--r--tests/language-feature/interfaces/generic-requirement-synth-2.slang35
-rw-r--r--tests/language-feature/interfaces/generic-requirement-synth.slang90
2 files changed, 125 insertions, 0 deletions
diff --git a/tests/language-feature/interfaces/generic-requirement-synth-2.slang b/tests/language-feature/interfaces/generic-requirement-synth-2.slang
new file mode 100644
index 000000000..9066fc5b7
--- /dev/null
+++ b/tests/language-feature/interfaces/generic-requirement-synth-2.slang
@@ -0,0 +1,35 @@
+// Test that we allow type conformances whose base interface is generic.
+
+//TEST(compute):COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-dx11 -compute -output-using-type
+//TEST(compute):COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-vk -compute -output-using-type
+
+interface IStack<let D : int>
+{
+ IStack<D - N> popN<let N : int>();
+
+ int get();
+}
+struct StackImpl<let D : int> : IStack<D>
+{
+ // member 'popN' does not match interface requirement.
+ StackImpl<D - N> popN<int N>() { return StackImpl<D - N>(); }
+
+ int get() { return D; }
+}
+
+int helper<int n, T : IStack<n>>(T stack)
+{
+ return stack.popN<2>().get();
+}
+
+//TEST_INPUT: set outputBuffer = out ubuffer(data=[0 0 0 0], stride=4);
+RWStructuredBuffer<int> outputBuffer;
+
+[numthreads(1, 1, 1)]
+void computeMain()
+{
+ StackImpl<5> obj = StackImpl<5>();
+
+ // CHECK: 3
+ outputBuffer[0] = helper(obj);
+} \ No newline at end of file
diff --git a/tests/language-feature/interfaces/generic-requirement-synth.slang b/tests/language-feature/interfaces/generic-requirement-synth.slang
new file mode 100644
index 000000000..1ac118014
--- /dev/null
+++ b/tests/language-feature/interfaces/generic-requirement-synth.slang
@@ -0,0 +1,90 @@
+// Test that we can synthesize requirements for generic methods.
+
+//TEST(compute):COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-dx11 -compute -output-using-type
+//TEST(compute):COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-vk -compute -output-using-type
+
+interface IBase
+{
+ static float get();
+}
+interface IBar : IBase
+{
+ float derivedMethod();
+}
+
+struct Bar : IBar
+{
+ static float get() { return 1.0f; }
+ float derivedMethod() { return 2.0f; }
+}
+
+interface ITestInterface<Real : IFloat>
+{
+ Real sample<T : IBar>(T t);
+
+ __init<T : IBar>(T t);
+
+ __generic<T : IBar>
+ __subscript(T t)->Real { get; }
+}
+
+struct TestInterfaceImpl<Real : IFloat> : ITestInterface<Real>
+{
+ // The signature of this sample method is different from the one in the
+ // interface. However, we should be able to form a call into this method
+ // from the synthesized implementation matching the interface definition,
+ // so the conformance should hold.
+ Real sample<T : IBase>(T t)
+ {
+ return x + Real(T.get());
+ }
+
+ // Test the same thing for constructors.
+ __init<T : IBase>(T t)
+ {
+ x = Real(T.get());
+ }
+
+ // Test the same thing for subscript operators.
+ __generic<T : IBase>
+ __subscript(T t)->Real { get { return x + Real(T.get()); } }
+ Real x;
+}
+
+float test(ITestInterface<float> obj)
+{
+ Bar b = {};
+ return obj.sample<Bar>(b);
+}
+
+float test1(ITestInterface<float> obj)
+{
+ Bar b = {};
+ return obj[b];
+}
+
+float test2<T:ITestInterface<float>>()
+{
+ Bar b = {};
+ T obj = T(b);
+ return obj[b];
+}
+
+//TEST_INPUT: set outputBuffer = out ubuffer(data=[0 0 0 0], stride=4);
+RWStructuredBuffer<int> outputBuffer;
+
+[numthreads(1, 1, 1)]
+void computeMain()
+{
+ TestInterfaceImpl<float> obj;
+ obj.x = 1.0f;
+
+ // CHECK: 2
+ outputBuffer[0] = int(test(obj));
+
+ // CHECK: 2
+ outputBuffer[1] = int(test1(obj));
+
+ // CHECK: 2
+ outputBuffer[3] = int(test2<TestInterfaceImpl<float>>());
+} \ No newline at end of file