[tint][resolver] Check variable use is not templated

Fixed: chromium:1466089
Change-Id: If95c7691fa5a2fec64466a553320925d66a30d3c
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/141960
Auto-Submit: Ben Clayton <bclayton@google.com>
Reviewed-by: James Price <jrprice@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc
index 44c7215..65001b6 100644
--- a/src/tint/resolver/resolver.cc
+++ b/src/tint/resolver/resolver.cc
@@ -3078,6 +3078,10 @@
         return Switch(
             resolved_node,  //
             [&](sem::Variable* variable) -> sem::VariableUser* {
+                if (!TINT_LIKELY(CheckNotTemplated("variable", ident))) {
+                    return nullptr;
+                }
+
                 auto stage = variable->Stage();
                 const constant::Value* value = variable->ConstantValue();
                 if (skip_const_eval_.Contains(expr)) {
diff --git a/src/tint/resolver/variable_test.cc b/src/tint/resolver/variable_test.cc
index f8d3210..f4d6060 100644
--- a/src/tint/resolver/variable_test.cc
+++ b/src/tint/resolver/variable_test.cc
@@ -1281,5 +1281,111 @@
     EXPECT_EQ(param->Type(), alias);
 }
 
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Templated identifier uses
+////////////////////////////////////////////////////////////////////////////////////////////////////
+TEST_F(ResolverVariableTest, GlobalVar_UseTemplatedIdent) {
+    // var<private> a : i32;
+    //
+    // fn F() {
+    //   let l = a<i32>;
+    // }
+
+    GlobalVar(Source{{56, 78}}, "a", ty.i32(), builtin::AddressSpace::kPrivate);
+    Func("F", utils::Empty, ty.void_(),
+         utils::Vector{
+             Decl(Let("l", Expr(Ident(Source{{12, 34}}, "a", "i32")))),
+         });
+
+    EXPECT_FALSE(r()->Resolve());
+    EXPECT_EQ(r()->error(), R"(12:34 error: variable 'a' does not take template arguments
+56:78 note: var 'a' declared here)");
+}
+
+TEST_F(ResolverVariableTest, GlobalConst_UseTemplatedIdent) {
+    // const a = 1i;
+    //
+    // fn F() {
+    //   let l = a<i32>;
+    // }
+
+    GlobalConst(Source{{56, 78}}, "a", Expr(1_i));
+    Func("F", utils::Empty, ty.void_(),
+         utils::Vector{
+             Decl(Let("l", Expr(Ident(Source{{12, 34}}, "a", "i32")))),
+         });
+
+    EXPECT_FALSE(r()->Resolve());
+    EXPECT_EQ(r()->error(), R"(12:34 error: variable 'a' does not take template arguments
+56:78 note: const 'a' declared here)");
+}
+
+TEST_F(ResolverVariableTest, GlobalOverride_UseTemplatedIdent) {
+    // override a = 1i;
+    //
+    // fn F() {
+    //   let l = a<i32>;
+    // }
+
+    Override(Source{{56, 78}}, "a", Expr(1_i));
+    Func("F", utils::Empty, ty.void_(),
+         utils::Vector{
+             Decl(Let("l", Expr(Ident(Source{{12, 34}}, "a", "i32")))),
+         });
+
+    EXPECT_FALSE(r()->Resolve());
+    EXPECT_EQ(r()->error(), R"(12:34 error: variable 'a' does not take template arguments
+56:78 note: override 'a' declared here)");
+}
+
+TEST_F(ResolverVariableTest, Param_UseTemplatedIdent) {
+    // fn F(a : i32) {
+    //   let l = a<i32>;
+    // }
+
+    Func("F", utils::Vector{Param(Source{{56, 78}}, "a", ty.i32())}, ty.void_(),
+         utils::Vector{
+             Decl(Let("l", Expr(Ident(Source{{12, 34}}, "a", "i32")))),
+         });
+
+    EXPECT_FALSE(r()->Resolve());
+    EXPECT_EQ(r()->error(), R"(12:34 error: variable 'a' does not take template arguments
+56:78 note: parameter 'a' declared here)");
+}
+
+TEST_F(ResolverVariableTest, LocalVar_UseTemplatedIdent) {
+    // fn F() {
+    //   var a : i32;
+    //   let l = a<i32>;
+    // }
+
+    Func("F", utils::Empty, ty.void_(),
+         utils::Vector{
+             Decl(Var(Source{{56, 78}}, "a", ty.i32())),
+             Decl(Let("l", Expr(Ident(Source{{12, 34}}, "a", "i32")))),
+         });
+
+    EXPECT_FALSE(r()->Resolve());
+    EXPECT_EQ(r()->error(), R"(12:34 error: variable 'a' does not take template arguments
+56:78 note: var 'a' declared here)");
+}
+
+TEST_F(ResolverVariableTest, Let_UseTemplatedIdent) {
+    // fn F() {
+    //   let a = 1i;
+    //   let l = a<i32>;
+    // }
+
+    Func("F", utils::Empty, ty.void_(),
+         utils::Vector{
+             Decl(Let(Source{{56, 78}}, "a", Expr(1_i))),
+             Decl(Let("l", Expr(Ident(Source{{12, 34}}, "a", "i32")))),
+         });
+
+    EXPECT_FALSE(r()->Resolve());
+    EXPECT_EQ(r()->error(), R"(12:34 error: variable 'a' does not take template arguments
+56:78 note: let 'a' declared here)");
+}
+
 }  // namespace
 }  // namespace tint::resolver