diff options
Diffstat (limited to 'tests/language-feature')
6 files changed, 203 insertions, 2 deletions
diff --git a/tests/language-feature/generics/where-optional-1.slang b/tests/language-feature/generics/where-optional-1.slang new file mode 100644 index 000000000..da4bdaacb --- /dev/null +++ b/tests/language-feature/generics/where-optional-1.slang @@ -0,0 +1,11 @@ +//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): +interface IThing +{ + void thing(); +} + +void f<T>(T t) where optional T: IThing +{ + // Unchecked optional constraint is an error. + t.thing(); // CHECK: error 30403 +} diff --git a/tests/language-feature/generics/where-optional-2.slang b/tests/language-feature/generics/where-optional-2.slang new file mode 100644 index 000000000..67679bd8d --- /dev/null +++ b/tests/language-feature/generics/where-optional-2.slang @@ -0,0 +1,63 @@ +//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK): -shaderobj +//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK): -vk -shaderobj +//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK): -cpu -shaderobj + +//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0], stride=4):out,name=outputBuffer +RWStructuredBuffer<int> outputBuffer; + +interface IThing +{ + [mutating] + int thing(int index); +} + +struct MyThing: IThing +{ + int val; + + [mutating] + int thing(int index) + { + val++; + outputBuffer[index] = val; + return val; + } +} + +struct NotMyThing +{ + int val; +} + +void f<T>(inout T t, int index) where optional T: IThing +{ + if (T is IThing) + { + outputBuffer[index+1] = 2 * t.thing(index); + } + else + { + outputBuffer[index] = 0; + outputBuffer[index+1] = 0; + } +} + +[numthreads(1, 1, 1)] +void computeMain(int3 dispatchThreadID: SV_DispatchThreadID) +{ + MyThing mt = MyThing(0); + NotMyThing nt = NotMyThing(1); + + // CHECK: 1 + // CHECK-NEXT: 2 + f<MyThing>(mt, 0); + // CHECK-NEXT: 0 + // CHECK-NEXT: 0 + f<NotMyThing>(nt, 2); + // CHECK: 2 + // CHECK-NEXT: 4 + f(mt, 4); + // CHECK-NEXT: 0 + // CHECK-NEXT: 0 + f(nt, 6); +} diff --git a/tests/language-feature/generics/where-optional-3.slang b/tests/language-feature/generics/where-optional-3.slang new file mode 100644 index 000000000..f8b3a4907 --- /dev/null +++ b/tests/language-feature/generics/where-optional-3.slang @@ -0,0 +1,95 @@ +//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK): -shaderobj +//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK): -vk -shaderobj +//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK): -cpu -shaderobj + +//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0], stride=4):out,name=outputBuffer +RWStructuredBuffer<int> outputBuffer; + +interface IReleaseable +{ + [mutating] + void release(); +} + +struct Container<K, V> + where optional K : IReleaseable + where optional V : IReleaseable +{ + K k[2]; + V v[2]; + + [mutating] + void erase(int index) + { + if (K is IReleaseable) + k[index].release(); + if (V is IReleaseable) + v[index].release(); + } +} + +struct HeavyEntry: IReleaseable +{ + int index; + int value; + + [mutating] + void release() + { + outputBuffer[index] = value; + } +}; + +struct LightEntry +{ + int value; +}; + +[numthreads(1, 1, 1)] +void computeMain(int3 dispatchThreadID: SV_DispatchThreadID) +{ + { // Neither is IReleaseable + var c = Container<LightEntry, LightEntry>(); + c.k[0] = LightEntry(1); + c.k[1] = LightEntry(2); + c.v[0] = LightEntry(3); + c.v[1] = LightEntry(4); + c.erase(0); + c.erase(1); + } + { // K is IReleaseable + var c = Container<HeavyEntry, LightEntry>(); + c.k[0] = HeavyEntry(0,1); + c.k[1] = HeavyEntry(1,2); + c.v[0] = LightEntry(3); + c.v[1] = LightEntry(4); + // CHECK: 1 + c.erase(0); + // CHECK-NEXT: 2 + c.erase(1); + } + { // V is IReleaseable + var c = Container<LightEntry, HeavyEntry>(); + c.k[0] = LightEntry(1); + c.k[1] = LightEntry(2); + c.v[0] = HeavyEntry(2,3); + c.v[1] = HeavyEntry(3,4); + // CHECK-NEXT: 3 + c.erase(0); + // CHECK-NEXT: 4 + c.erase(1); + } + { // K and V are IReleaseable + var c = Container<HeavyEntry, HeavyEntry>(); + c.k[0] = HeavyEntry(4,5); + c.k[1] = HeavyEntry(6,7); + c.v[0] = HeavyEntry(5,6); + c.v[1] = HeavyEntry(7,8); + // CHECK-NEXT: 5 + // CHECK-NEXT: 6 + c.erase(0); + // CHECK-NEXT: 7 + // CHECK-NEXT: 8 + c.erase(1); + } +} diff --git a/tests/language-feature/generics/where-optional-4.slang b/tests/language-feature/generics/where-optional-4.slang new file mode 100644 index 000000000..6d72186d9 --- /dev/null +++ b/tests/language-feature/generics/where-optional-4.slang @@ -0,0 +1,15 @@ +//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): +interface IThing +{ + void thing(); +} + +void g<T>(T t) where T: IThing +{ +} + +void f<T>(T t) where optional T: IThing +{ + // Error: cannot upgrade optional to non-optional witness in unchecked context. + g<T>(t); // CHECK: error 38029 +} diff --git a/tests/language-feature/generics/where-optional-5.slang b/tests/language-feature/generics/where-optional-5.slang new file mode 100644 index 000000000..3ce8041ad --- /dev/null +++ b/tests/language-feature/generics/where-optional-5.slang @@ -0,0 +1,17 @@ +//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): +interface IThing +{ + void thing(); +} + +void f<T, U>(T t, U u) + where optional T: IThing + where optional U: IThing +{ + // Error: cannot upgrade optional to non-optional witness in unchecked context. + if (U is IThing) + { + // U being IThing doesn't justify using T as such! + t.thing(); // CHECK: error 30403 + } +} diff --git a/tests/language-feature/interface-as-rhs-error.slang b/tests/language-feature/interface-as-rhs-error.slang index 9ad71afde..7293b5134 100644 --- a/tests/language-feature/interface-as-rhs-error.slang +++ b/tests/language-feature/interface-as-rhs-error.slang @@ -21,13 +21,13 @@ struct AnotherType // These should produce errors - interface types as RHS bool testIsOperatorWithInterface<T>() { - //CHECK: ([[# @LINE+1]]): error 30301: 'is' and 'as' operators do not support interface types as the right-hand side + //CHECK: ([[# @LINE+1]]): error 30301: cannot use 'is' operator with an interface type as the right-hand side return (T is IMyInterface); } void testAsOperatorWithInterface<T>(T value) { - //CHECK: ([[# @LINE+1]]): error 30301: 'is' and 'as' operators do not support interface types as the right-hand side + //CHECK: ([[# @LINE+1]]): error 30302: cannot use 'as' operator with an interface type as the right-hand side let result = value as IMyInterface; } |
