summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2025-01-17 08:55:57 -0800
committerGitHub <noreply@github.com>2025-01-17 08:55:57 -0800
commit3666c66e26f90b10031578e9c8b8f2ea118aecf9 (patch)
treea9564b3becf23d17b3183d97689c126819ffce9e
parentdfb369e87dd7638e84efe8feb9e7069e5238b44c (diff)
Fix prebound parameter pack - argument list matching logic. (#6111)
* Fix prebound parameter pack - argument list matching logic. * Move tests. * Fix.
-rw-r--r--source/slang/slang-ast-decl-ref.cpp2
-rw-r--r--source/slang/slang-check-overload.cpp18
-rw-r--r--tests/language-feature/generics/prebound-variadic-pack.slang28
-rw-r--r--tests/language-feature/generics/variadic-tuple-field.slang22
4 files changed, 68 insertions, 2 deletions
diff --git a/source/slang/slang-ast-decl-ref.cpp b/source/slang/slang-ast-decl-ref.cpp
index 3025381ea..9f140a524 100644
--- a/source/slang/slang-ast-decl-ref.cpp
+++ b/source/slang/slang-ast-decl-ref.cpp
@@ -318,7 +318,7 @@ void DeclRefBase::toText(StringBuilder& out)
return;
}
- if (as<GenericTypeParamDecl>(this->getDecl()))
+ if (as<GenericTypeParamDeclBase>(this->getDecl()))
{
SLANG_ASSERT(as<DirectDeclRef>(this));
out << this->getDecl()->getName()->text;
diff --git a/source/slang/slang-check-overload.cpp b/source/slang/slang-check-overload.cpp
index fcc6780b6..1ab3aa5b0 100644
--- a/source/slang/slang-check-overload.cpp
+++ b/source/slang/slang-check-overload.cpp
@@ -10,6 +10,17 @@
namespace Slang
{
+
+bool isFreeFormTypePackParam(SemanticsVisitor* visitor, Type* type, ParamDecl* paramDecl)
+{
+ if (auto declRef = isDeclRefTypeOf<GenericTypePackParamDecl>(type))
+ {
+ return visitor->GetOuterGeneric(declRef.getDecl()) ==
+ visitor->GetOuterGeneric(paramDecl->parentDecl);
+ }
+ return false;
+}
+
SemanticsVisitor::ParamCounts SemanticsVisitor::CountParameters(
FilteredMemberRefList<ParamDecl> params)
{
@@ -25,10 +36,15 @@ SemanticsVisitor::ParamCounts SemanticsVisitor::CountParameters(
counts.required += typePack->getTypeCount();
allowedArgCountToAdd = typePack->getTypeCount();
}
- else
+ else if (isFreeFormTypePackParam(this, paramType, param.getDecl()))
{
counts.allowed = -1;
}
+ else
+ {
+ counts.required++;
+ counts.allowed++;
+ }
}
else if (!param.getDecl()->initExpr)
{
diff --git a/tests/language-feature/generics/prebound-variadic-pack.slang b/tests/language-feature/generics/prebound-variadic-pack.slang
new file mode 100644
index 000000000..01edce8f9
--- /dev/null
+++ b/tests/language-feature/generics/prebound-variadic-pack.slang
@@ -0,0 +1,28 @@
+//TEST:SIMPLE(filecheck=CHECK): -target spirv
+
+struct Set<each T>
+{
+ Tuple<expand each T> data;
+ void f(expand each T v){}
+ void h<each U>(U x){}
+ void g(expand each T d)
+ {
+ //CHECK-NOT: ([[# @LINE+1]]): error
+ f(expand each d); // OK
+
+ //CHECK-NOT: ([[# @LINE+1]]): error
+ h(54); // OK, specializing free-form parameter U.
+
+ //CHECK: ([[# @LINE+1]]): error
+ f(); // error, cannot call f without arguments.
+
+ //CHECK: ([[# @LINE+1]]): error
+ f(5); // error, cannot call f with different type pack.
+ }
+}
+
+[numthreads(1,1,1)]
+void computeMain()
+{
+ Set<float> v;
+} \ No newline at end of file
diff --git a/tests/language-feature/generics/variadic-tuple-field.slang b/tests/language-feature/generics/variadic-tuple-field.slang
new file mode 100644
index 000000000..b5ebc4fb3
--- /dev/null
+++ b/tests/language-feature/generics/variadic-tuple-field.slang
@@ -0,0 +1,22 @@
+//TEST:COMPARE_COMPUTE(filecheck-buffer=CHECK): -output-using-type
+
+struct Set<each T>
+{
+ Tuple<expand each T> data;
+ void f(expand each T v){}
+ __init(expand each T d) {
+ f(d);
+ data = makeTuple(d);
+ }
+}
+
+//TEST_INPUT: set outputBuffer = out ubuffer(data=[0 0 0 0], stride=4)
+RWStructuredBuffer<float> outputBuffer;
+
+[numthreads(1,1,1)]
+void computeMain()
+{
+ let set = Set<float>(1.0);
+ outputBuffer[0] = set.data._0;
+ // CHECK: 1.0
+}