From 92c9fffb95c92b0bc07eb1c656375928b5cd5c33 Mon Sep 17 00:00:00 2001 From: Darren Wihandi <65404740+fairywreath@users.noreply.github.com> Date: Fri, 24 Jan 2025 16:12:38 -0500 Subject: [PATCH] improve error message on generic value decls (#6169) Co-authored-by: Yong He --- source/slang/slang-ast-support-types.h | 1 + source/slang/slang-check-decl.cpp | 9 +++++++- source/slang/slang-diagnostic-defs.h | 6 +++++- source/slang/slang-syntax.cpp | 13 +++++++++++- ...neric-value-parameter-must-have-type.slang | 21 +++++++++++++++++++ 5 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 tests/diagnostics/generic-value-parameter-must-have-type.slang diff --git a/source/slang/slang-ast-support-types.h b/source/slang/slang-ast-support-types.h index 1d3de9c546..56e07d4304 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 0319eb2609..3453d0538d 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(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 ca99ac11d8..37dfc81147 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 6fdd5088a6..e479f1b9d8 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 0000000000..a7920b86c1 --- /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 : ITest +{ + static const uint kValue0 = TValue0; + static const uint kValue1 = TValue1; +}; + +void computeMain() +{ +}