diff options
| -rw-r--r-- | source/slang/slang-ast-decl-ref.cpp | 2 | ||||
| -rw-r--r-- | source/slang/slang-check-overload.cpp | 18 | ||||
| -rw-r--r-- | tests/language-feature/generics/prebound-variadic-pack.slang | 28 | ||||
| -rw-r--r-- | tests/language-feature/generics/variadic-tuple-field.slang | 22 |
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 +} |
