summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/slang/slang-ast-support-types.h1
-rw-r--r--source/slang/slang-check-decl.cpp9
-rw-r--r--source/slang/slang-diagnostic-defs.h6
-rw-r--r--source/slang/slang-syntax.cpp13
-rw-r--r--tests/diagnostics/generic-value-parameter-must-have-type.slang21
5 files changed, 47 insertions, 3 deletions
diff --git a/source/slang/slang-ast-support-types.h b/source/slang/slang-ast-support-types.h
index 1d3de9c54..56e07d430 100644
--- a/source/slang/slang-ast-support-types.h
+++ b/source/slang/slang-ast-support-types.h
@@ -80,6 +80,7 @@ class SyntaxNode;
SourceLoc getDiagnosticPos(SyntaxNode const* syntax);
SourceLoc getDiagnosticPos(TypeExp const& typeExp);
SourceLoc getDiagnosticPos(DeclRefBase* declRef);
+SourceLoc getDiagnosticPos(Decl* decl);
typedef NodeBase* (*SyntaxParseCallback)(Parser* parser, void* userData);
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp
index 0319eb260..3453d0538 100644
--- a/source/slang/slang-check-decl.cpp
+++ b/source/slang/slang-check-decl.cpp
@@ -1775,7 +1775,14 @@ void SemanticsDeclHeaderVisitor::checkVarDeclCommon(VarDeclBase* varDecl)
{
if (!varDecl->type.type)
{
- getSink()->diagnose(varDecl, Diagnostics::varWithoutTypeMustHaveInitializer);
+ if (as<GenericValueParamDecl>(varDecl))
+ {
+ getSink()->diagnose(varDecl, Diagnostics::genericValueParameterMustHaveType);
+ }
+ else
+ {
+ getSink()->diagnose(varDecl, Diagnostics::varWithoutTypeMustHaveInitializer);
+ }
varDecl->type.type = m_astBuilder->getErrorType();
}
}
diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h
index ca99ac11d..37dfc8114 100644
--- a/source/slang/slang-diagnostic-defs.h
+++ b/source/slang/slang-diagnostic-defs.h
@@ -1421,7 +1421,11 @@ DIAGNOSTIC(
ambiguousDefaultInitializerForType,
"more than one default initializer was found for type '$0'")
DIAGNOSTIC(30623, Error, cannotHaveInitializer, "'$0' cannot have an initializer because it is $1")
-
+DIAGNOSTIC(
+ 30623,
+ Error,
+ genericValueParameterMustHaveType,
+ "a generic value parameter must be given an explicit type")
// 307xx: parameters
DIAGNOSTIC(
diff --git a/source/slang/slang-syntax.cpp b/source/slang/slang-syntax.cpp
index 6fdd5088a..e479f1b9d 100644
--- a/source/slang/slang-syntax.cpp
+++ b/source/slang/slang-syntax.cpp
@@ -284,7 +284,18 @@ SourceLoc getDiagnosticPos(DeclRefBase* declRef)
{
if (!declRef)
return SourceLoc();
- return declRef->getDecl()->loc;
+ return getDiagnosticPos(declRef->getDecl());
+}
+
+SourceLoc getDiagnosticPos(Decl* decl)
+{
+ if (!decl)
+ return SourceLoc();
+ if (decl->getNameLoc().isValid())
+ {
+ return decl->getNameLoc();
+ }
+ return decl->loc;
}
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!! Free functions !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
diff --git a/tests/diagnostics/generic-value-parameter-must-have-type.slang b/tests/diagnostics/generic-value-parameter-must-have-type.slang
new file mode 100644
index 000000000..a7920b86c
--- /dev/null
+++ b/tests/diagnostics/generic-value-parameter-must-have-type.slang
@@ -0,0 +1,21 @@
+//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): -target spirv
+
+interface ITest
+{
+ static const uint kValue0;
+ static const uint kValue1;
+};
+
+// `TValue1` does not have an explicit type, this should fail to compile.
+// CHECK: error 30623: a generic value parameter
+// Make sure erroneous code is printed out.
+// CHECK: let TValue1>
+struct TestImpl<let TValue0 : uint, let TValue1> : ITest
+{
+ static const uint kValue0 = TValue0;
+ static const uint kValue1 = TValue1;
+};
+
+void computeMain()
+{
+}