[tint][wgsl][resolver] Add missing template arg check

For calls of user declared types.

Issue: chromium:1469195
Change-Id: I7d1b314244ed8b46d2a7df4996b06c8771d991df
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/145300
Commit-Queue: Ben Clayton <bclayton@google.com>
Auto-Submit: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/tint/lang/wgsl/resolver/resolver.cc b/src/tint/lang/wgsl/resolver/resolver.cc
index ed8684c..23808aa 100644
--- a/src/tint/lang/wgsl/resolver/resolver.cc
+++ b/src/tint/lang/wgsl/resolver/resolver.cc
@@ -2239,7 +2239,13 @@
         if (auto* ast_node = resolved->Node()) {
             return Switch(
                 sem_.Get(ast_node),  //
-                [&](type::Type* t) { return ty_init_or_conv(t); },
+                [&](type::Type* t) -> tint::sem::Call* {
+                    // User declared types cannot be templated.
+                    if (!TINT_LIKELY(CheckNotTemplated("type", ident))) {
+                        return nullptr;
+                    }
+                    return ty_init_or_conv(t);
+                },
                 [&](sem::Function* f) -> sem::Call* {
                     if (!TINT_LIKELY(CheckNotTemplated("function", ident))) {
                         return nullptr;
@@ -3168,6 +3174,7 @@
                 return user;
             },
             [&](const type::Type* ty) -> sem::TypeExpression* {
+                // User declared types cannot be templated.
                 if (!TINT_LIKELY(CheckNotTemplated("type", ident))) {
                     return nullptr;
                 }
diff --git a/src/tint/lang/wgsl/resolver/type_validation_test.cc b/src/tint/lang/wgsl/resolver/type_validation_test.cc
index dd812d7..da96651 100644
--- a/src/tint/lang/wgsl/resolver/type_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/type_validation_test.cc
@@ -1481,7 +1481,7 @@
                                          "vec4i",
                                          "vec4u"));
 
-TEST_F(ResolverUntemplatedTypeUsedWithTemplateArgs, Struct_UseWithTemplateArgs) {
+TEST_F(ResolverUntemplatedTypeUsedWithTemplateArgs, Struct_Type) {
     // struct S {
     //   i: i32;
     // };
@@ -1496,6 +1496,43 @@
 56:78 note: struct 'S' declared here)");
 }
 
+TEST_F(ResolverUntemplatedTypeUsedWithTemplateArgs, Struct_Ctor) {
+    // struct S { a : i32 }
+    // var<private> v = S<true>();
+
+    Structure("S", Vector{Member("a", ty.i32())});
+    GlobalVar("v", core::AddressSpace::kPrivate, Call(ty(Source{{12, 34}}, "S", true)));
+
+    EXPECT_FALSE(r()->Resolve());
+    EXPECT_EQ(r()->error(), R"(12:34 error: type 'S' does not take template arguments
+note: struct 'S' declared here)");
+}
+
+TEST_F(ResolverUntemplatedTypeUsedWithTemplateArgs, AliasedArray_Type) {
+    // alias A = array<i32, 4u>
+    // var<private> v : A<true>;
+
+    Alias("A", ty.array<i32, 4>());
+    GlobalVar("v", core::AddressSpace::kPrivate, ty(Source{{12, 34}}, "A", true));
+
+    EXPECT_FALSE(r()->Resolve());
+    EXPECT_EQ(r()->error(),
+              R"(12:34 error: type 'A' does not take template arguments
+note: alias 'A' declared here)");
+}
+
+TEST_F(ResolverUntemplatedTypeUsedWithTemplateArgs, AliasedArray_Ctor) {
+    // alias A = array<i32, 4u>
+    // var<private> v = A<true>();
+
+    Alias("A", ty.array<i32, 4>());
+    GlobalVar("v", core::AddressSpace::kPrivate, Call(ty(Source{{12, 34}}, "A", true)));
+
+    EXPECT_FALSE(r()->Resolve());
+    EXPECT_EQ(r()->error(), R"(12:34 error: type 'A' does not take template arguments
+note: alias 'A' declared here)");
+}
+
 }  // namespace TypeDoesNotTakeTemplateArgs
 
 }  // namespace