[tint] Helper types for vec (and matrix)

Also adding helper functions to type/manager.h

All of these helpers correspond to an alias in wgsl.
For example: Vector types https://www.w3.org/TR/WGSL/#vector-types

Change-Id: Ie13956892ef173167629253374cf79db1bdc7fcd
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/271074
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: Peter McNeeley <petermcneeley@google.com>
diff --git a/src/tint/lang/core/fluent_types.h b/src/tint/lang/core/fluent_types.h
index 9c26f16..de6ab77 100644
--- a/src/tint/lang/core/fluent_types.h
+++ b/src/tint/lang/core/fluent_types.h
@@ -154,6 +154,42 @@
 template <typename T>
 using vec4 = vec<4, T>;
 
+using mat2x2f = mat<2, 2, f32>;
+using mat2x3f = mat<2, 3, f32>;
+using mat2x4f = mat<2, 4, f32>;
+using mat3x2f = mat<3, 2, f32>;
+using mat3x3f = mat<3, 3, f32>;
+using mat3x4f = mat<3, 4, f32>;
+using mat4x2f = mat<4, 2, f32>;
+using mat4x3f = mat<4, 3, f32>;
+using mat4x4f = mat<4, 4, f32>;
+
+using mat2x2h = mat<2, 2, f16>;
+using mat2x3h = mat<2, 3, f16>;
+using mat2x4h = mat<2, 4, f16>;
+using mat3x2h = mat<3, 2, f16>;
+using mat3x3h = mat<3, 3, f16>;
+using mat3x4h = mat<3, 4, f16>;
+using mat4x2h = mat<4, 2, f16>;
+using mat4x3h = mat<4, 3, f16>;
+using mat4x4h = mat<4, 4, f16>;
+
+using vec2f = vec<2, f32>;
+using vec3f = vec<3, f32>;
+using vec4f = vec<4, f32>;
+
+using vec2h = vec<2, f16>;
+using vec3h = vec<3, f16>;
+using vec4h = vec<4, f16>;
+
+using vec2i = vec<2, i32>;
+using vec3i = vec<3, i32>;
+using vec4i = vec<4, i32>;
+
+using vec2u = vec<2, u32>;
+using vec3u = vec<3, u32>;
+using vec4u = vec<4, u32>;
+
 //! @endcond
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/tint/lang/core/intrinsic/table_test.cc b/src/tint/lang/core/intrinsic/table_test.cc
index d9ca2a3..ed8c591 100644
--- a/src/tint/lang/core/intrinsic/table_test.cc
+++ b/src/tint/lang/core/intrinsic/table_test.cc
@@ -85,9 +85,8 @@
 }
 
 TEST_F(CoreIntrinsicTableTest, MatchU32) {
-    auto* f32 = ty.f32();
     auto* u32 = ty.u32();
-    auto* vec2f = ty.vec2(f32);
+    auto* vec2f = ty.vec2f();
     auto result =
         table.Lookup(BuiltinFn::kUnpack2X16Float, Empty, Vector{u32}, EvaluationStage::kConstant);
     ASSERT_EQ(result, Success);
@@ -107,7 +106,7 @@
 TEST_F(CoreIntrinsicTableTest, MatchI32) {
     auto* f32 = ty.f32();
     auto* i32 = ty.i32();
-    auto* vec4f = ty.vec4(ty.f32());
+    auto* vec4f = ty.vec4f();
     auto* tex = ty.sampled_texture(type::TextureDimension::k1d, f32);
     auto result = table.Lookup(BuiltinFn::kTextureLoad, Empty, Vector{tex, i32, i32},
                                EvaluationStage::kConstant);
@@ -268,8 +267,8 @@
 
 TEST_F(CoreIntrinsicTableTest, MatchSampler) {
     auto* f32 = ty.f32();
-    auto* vec2f = ty.vec2(f32);
-    auto* vec4f = ty.vec4(f32);
+    auto* vec2f = ty.vec2f();
+    auto* vec4f = ty.vec4f();
     auto* tex = ty.sampled_texture(type::TextureDimension::k2d, f32);
     auto* sampler = ty.sampler();
     auto result = table.Lookup(BuiltinFn::kTextureSample, Empty, Vector{tex, sampler, vec2f},
@@ -287,7 +286,7 @@
 
 TEST_F(CoreIntrinsicTableTest, MismatchSampler) {
     auto* f32 = ty.f32();
-    auto* vec2f = ty.vec2(f32);
+    auto* vec2f = ty.vec2f();
     auto* tex = ty.sampled_texture(type::TextureDimension::k2d, f32);
     auto result = table.Lookup(BuiltinFn::kTextureSample, Empty, Vector{tex, f32, vec2f},
                                EvaluationStage::kConstant);
@@ -298,8 +297,8 @@
 TEST_F(CoreIntrinsicTableTest, MatchSampledTexture) {
     auto* i32 = ty.i32();
     auto* f32 = ty.f32();
-    auto* vec2i = ty.vec2(i32);
-    auto* vec4f = ty.vec4(f32);
+    auto* vec2i = ty.vec2i();
+    auto* vec4f = ty.vec4f();
     auto* tex = ty.sampled_texture(type::TextureDimension::k2d, f32);
     auto result = table.Lookup(BuiltinFn::kTextureLoad, Empty, Vector{tex, vec2i, i32},
                                EvaluationStage::kConstant);
@@ -317,8 +316,8 @@
 TEST_F(CoreIntrinsicTableTest, MatchMultisampledTexture) {
     auto* i32 = ty.i32();
     auto* f32 = ty.f32();
-    auto* vec2i = ty.vec2(i32);
-    auto* vec4f = ty.vec4(f32);
+    auto* vec2i = ty.vec2i();
+    auto* vec4f = ty.vec4f();
     auto* tex = ty.multisampled_texture(type::TextureDimension::k2d, f32);
     auto result = table.Lookup(BuiltinFn::kTextureLoad, Empty, Vector{tex, vec2i, i32},
                                EvaluationStage::kConstant);
@@ -336,7 +335,7 @@
 TEST_F(CoreIntrinsicTableTest, MatchDepthTexture) {
     auto* f32 = ty.f32();
     auto* i32 = ty.i32();
-    auto* vec2i = ty.vec2(i32);
+    auto* vec2i = ty.vec2i();
     auto* tex = ty.depth_texture(type::TextureDimension::k2d);
     auto result = table.Lookup(BuiltinFn::kTextureLoad, Empty, Vector{tex, vec2i, i32},
                                EvaluationStage::kConstant);
@@ -354,7 +353,7 @@
 TEST_F(CoreIntrinsicTableTest, MatchDepthMultisampledTexture) {
     auto* f32 = ty.f32();
     auto* i32 = ty.i32();
-    auto* vec2i = ty.vec2(i32);
+    auto* vec2i = ty.vec2i();
     auto* tex = ty.depth_multisampled_texture(type::TextureDimension::k2d);
     auto result = table.Lookup(BuiltinFn::kTextureLoad, Empty, Vector{tex, vec2i, i32},
                                EvaluationStage::kConstant);
@@ -370,10 +369,8 @@
 }
 
 TEST_F(CoreIntrinsicTableTest, MatchExternalTexture) {
-    auto* f32 = ty.f32();
-    auto* i32 = ty.i32();
-    auto* vec2i = ty.vec2(i32);
-    auto* vec4f = ty.vec4(f32);
+    auto* vec2i = ty.vec2i();
+    auto* vec4f = ty.vec4f();
     auto* tex = ty.external_texture();
     auto result = table.Lookup(BuiltinFn::kTextureLoad, Empty, Vector{tex, vec2i},
                                EvaluationStage::kConstant);
@@ -387,10 +384,8 @@
 }
 
 TEST_F(CoreIntrinsicTableTest, MatchWOStorageTexture) {
-    auto* f32 = ty.f32();
-    auto* i32 = ty.i32();
-    auto* vec2i = ty.vec2(i32);
-    auto* vec4f = ty.vec4(f32);
+    auto* vec2i = ty.vec2i();
+    auto* vec4f = ty.vec4f();
     auto* tex =
         ty.storage_texture(type::TextureDimension::k2d, TexelFormat::kR32Float, Access::kWrite);
 
@@ -408,9 +403,8 @@
 }
 
 TEST_F(CoreIntrinsicTableTest, MismatchTexture) {
+    auto* vec2i = ty.vec2i();
     auto* f32 = ty.f32();
-    auto* i32 = ty.i32();
-    auto* vec2i = ty.vec2(i32);
     auto result = table.Lookup(BuiltinFn::kTextureLoad, Empty, Vector{f32, vec2i},
                                EvaluationStage::kConstant);
     ASSERT_NE(result, Success);
@@ -438,8 +432,7 @@
 }
 
 TEST_F(CoreIntrinsicTableTest, MatchOpenSizeVector) {
-    auto* f32 = ty.f32();
-    auto* vec2f = ty.vec2(f32);
+    auto* vec2f = ty.vec2f();
     auto result = table.Lookup(BuiltinFn::kClamp, Empty, Vector{vec2f, vec2f, vec2f},
                                EvaluationStage::kConstant);
     ASSERT_EQ(result, Success);
@@ -451,9 +444,8 @@
 }
 
 TEST_F(CoreIntrinsicTableTest, MismatchOpenSizeVector) {
-    auto* f32 = ty.f32();
     auto* u32 = ty.u32();
-    auto* vec2f = ty.vec2(f32);
+    auto* vec2f = ty.vec2f();
     auto result = table.Lookup(BuiltinFn::kClamp, Empty, Vector{vec2f, u32, vec2f},
                                EvaluationStage::kConstant);
     ASSERT_NE(result, Success);
@@ -660,8 +652,7 @@
 }
 
 TEST_F(CoreIntrinsicTableTest, MatchUnaryOp) {
-    auto* i32 = ty.i32();
-    auto* vec3i = ty.vec3(i32);
+    auto* vec3i = ty.vec3i();
     auto result = table.Lookup(UnaryOp::kNegation, vec3i, EvaluationStage::kConstant);
     ASSERT_EQ(result, Success);
     EXPECT_EQ(result->return_type, vec3i);
@@ -697,7 +688,7 @@
 
 TEST_F(CoreIntrinsicTableTest, MatchBinaryOp) {
     auto* i32 = ty.i32();
-    auto* vec3i = ty.vec3(i32);
+    auto* vec3i = ty.vec3i();
     auto result = table.Lookup(BinaryOp::kMultiply, i32, vec3i, EvaluationStage::kConstant,
                                /* is_compound */ false);
     ASSERT_EQ(result, Success);
@@ -738,7 +729,7 @@
 
 TEST_F(CoreIntrinsicTableTest, MatchCompoundOp) {
     auto* i32 = ty.i32();
-    auto* vec3i = ty.vec3(i32);
+    auto* vec3i = ty.vec3i();
     auto result = table.Lookup(BinaryOp::kMultiply, i32, vec3i, EvaluationStage::kConstant,
                                /* is_compound */ true);
     ASSERT_EQ(result, Success);
@@ -779,7 +770,7 @@
 
 TEST_F(CoreIntrinsicTableTest, MatchTypeInitializer) {
     auto* i32 = ty.i32();
-    auto* vec3i = ty.vec3(i32);
+    auto* vec3i = ty.vec3i();
     auto result = table.Lookup(CtorConv::kVec3, Vector{i32}, Vector{i32, i32, i32},
                                EvaluationStage::kConstant);
     ASSERT_EQ(result, Success);
@@ -838,7 +829,7 @@
 
 TEST_F(CoreIntrinsicTableTest, MatchTypeInitializer_ConstantEval) {
     auto* i32 = ty.i32();
-    auto* vec3i = ty.vec3(i32);
+    auto* vec3i = ty.vec3i();
     auto result = table.Lookup(CtorConv::kVec3, Vector{i32}, Vector{i32, i32, i32},
                                EvaluationStage::kConstant);
     ASSERT_EQ(result, Success);
@@ -856,7 +847,7 @@
     auto* i32 = ty.i32();
     auto result = table.Lookup(CtorConv::kVec3, Vector{i32}, Vector{i32, i32, i32},
                                EvaluationStage::kRuntime);
-    auto* vec3i = ty.vec3(i32);
+    auto* vec3i = ty.vec3i();
     ASSERT_EQ(result, Success);
     EXPECT_NE(result->const_eval_fn, nullptr);
     EXPECT_EQ(result->return_type, vec3i);
@@ -870,9 +861,8 @@
 
 TEST_F(CoreIntrinsicTableTest, MatchTypeConversion) {
     auto* i32 = ty.i32();
-    auto* vec3i = ty.vec3(i32);
-    auto* f32 = ty.f32();
-    auto* vec3f = ty.vec3(f32);
+    auto* vec3i = ty.vec3i();
+    auto* vec3f = ty.vec3f();
     auto result =
         table.Lookup(CtorConv::kVec3, Vector{i32}, Vector{vec3f}, EvaluationStage::kConstant);
     ASSERT_EQ(result, Success);
@@ -926,10 +916,9 @@
 }
 
 TEST_F(CoreIntrinsicTableTest, MatchTypeConversion_ConstantEval) {
-    auto* i32 = ty.i32();
     auto* f32 = ty.f32();
-    auto* vec3i = ty.vec3(i32);
-    auto* vec3f = ty.vec3(f32);
+    auto* vec3i = ty.vec3i();
+    auto* vec3f = ty.vec3f();
     auto result =
         table.Lookup(CtorConv::kVec3, Vector{f32}, Vector{vec3i}, EvaluationStage::kConstant);
     ASSERT_EQ(result, Success);
@@ -942,10 +931,9 @@
 }
 
 TEST_F(CoreIntrinsicTableTest, MatchTypeConversion_RuntimeEval) {
-    auto* i32 = ty.i32();
     auto* f32 = ty.f32();
-    auto* vec3i = ty.vec3(i32);
-    auto* vec3f = ty.vec3(ty.f32());
+    auto* vec3i = ty.vec3i();
+    auto* vec3f = ty.vec3f();
     auto result =
         table.Lookup(CtorConv::kVec3, Vector{f32}, Vector{vec3i}, EvaluationStage::kRuntime);
     ASSERT_EQ(result, Success);
diff --git a/src/tint/lang/core/ir/analysis/for_loop_analysis_test.cc b/src/tint/lang/core/ir/analysis/for_loop_analysis_test.cc
index 1227370..4440867 100644
--- a/src/tint/lang/core/ir/analysis/for_loop_analysis_test.cc
+++ b/src/tint/lang/core/ir/analysis/for_loop_analysis_test.cc
@@ -211,10 +211,10 @@
     Var* U = nullptr;
     auto* str_ty =
         ty.Struct(mod.symbols.New("UniformStruct"), {
-                                                        {mod.symbols.New("a"), ty.vec4(ty.u32())},
-                                                        {mod.symbols.New("b"), ty.vec4(ty.u32())},
-                                                        {mod.symbols.New("c"), ty.vec4(ty.u32())},
-                                                        {mod.symbols.New("d"), ty.vec4(ty.u32())},
+                                                        {mod.symbols.New("a"), ty.vec4u()},
+                                                        {mod.symbols.New("b"), ty.vec4u()},
+                                                        {mod.symbols.New("c"), ty.vec4u()},
+                                                        {mod.symbols.New("d"), ty.vec4u()},
                                                     });
     b.Append(b.ir.root_block,
              [&] {  //
@@ -314,10 +314,10 @@
     Var* U = nullptr;
     auto* str_ty =
         ty.Struct(mod.symbols.New("UniformStruct"), {
-                                                        {mod.symbols.New("a"), ty.vec4(ty.u32())},
-                                                        {mod.symbols.New("b"), ty.vec4(ty.u32())},
-                                                        {mod.symbols.New("c"), ty.vec4(ty.u32())},
-                                                        {mod.symbols.New("d"), ty.vec4(ty.u32())},
+                                                        {mod.symbols.New("a"), ty.vec4u()},
+                                                        {mod.symbols.New("b"), ty.vec4u()},
+                                                        {mod.symbols.New("c"), ty.vec4u()},
+                                                        {mod.symbols.New("d"), ty.vec4u()},
                                                     });
     b.Append(b.ir.root_block,
              [&] {  //
diff --git a/src/tint/lang/core/ir/const_param_validator_test.cc b/src/tint/lang/core/ir/const_param_validator_test.cc
index d164c00..073fe6d 100644
--- a/src/tint/lang/core/ir/const_param_validator_test.cc
+++ b/src/tint/lang/core/ir/const_param_validator_test.cc
@@ -307,7 +307,7 @@
 }
 
 TEST_F(IR_ConstParamValidatorTest, IncorrectDomainkExtractBits_Vec) {
-    auto* func = b.Function("foo", ty.vec4(ty.i32()));
+    auto* func = b.Function("foo", ty.vec4i());
     b.Append(func->Block(), [&] {
         auto* e = b.Let("a", b.Splat(ty.vec4<i32>(), -3_i));
         auto* call_func = b.Call(ty.vec4<i32>(), core::BuiltinFn::kExtractBits, e, 13_u, 23_u);
@@ -334,7 +334,7 @@
 }
 
 TEST_F(IR_ConstParamValidatorTest, IncorrectDomainkInsertBits_Vec) {
-    auto* func = b.Function("foo", ty.vec4(ty.u32()));
+    auto* func = b.Function("foo", ty.vec4u());
     b.Append(func->Block(), [&] {
         auto* e = b.Let("a", b.Splat(ty.vec4<u32>(), 3_u));
         auto* newBits = b.Let("b", b.Splat(ty.vec4<u32>(), 4_u));
@@ -472,12 +472,12 @@
 }
 
 TEST_F(IR_ConstParamValidatorTest, IncorrectDomainClamp_Vec) {
-    auto* func = b.Function("foo", ty.vec4(ty.f16()));
+    auto* func = b.Function("foo", ty.vec4h());
     b.Append(func->Block(), [&] {
         auto* e = b.Let("b", b.Splat(ty.vec4<f16>(), 4_h));
         auto* low = b.Splat(ty.vec4<f16>(), 4_h);
         auto* high = b.Splat(ty.vec4<f16>(), 2_h);
-        auto* call_func = b.Call(ty.vec4(ty.f16()), core::BuiltinFn::kClamp, e, low, high);
+        auto* call_func = b.Call(ty.vec4h(), core::BuiltinFn::kClamp, e, low, high);
         b.ir.SetSource(call_func, Source{{5, 7}});
         b.Return(func, call_func->Result());
     });
@@ -526,12 +526,12 @@
 }
 
 TEST_F(IR_ConstParamValidatorTest, IncorrectDomainSmoothstep_Vec) {
-    auto* func = b.Function("foo", ty.vec4(ty.f16()));
+    auto* func = b.Function("foo", ty.vec4h());
     b.Append(func->Block(), [&] {
-        auto* e = b.Let("b", b.Splat(ty.vec4<f16>(), 4_h));
+        auto* e = b.Let("b", b.Splat(ty.vec4h(), 4_h));
         auto* edge0 = b.Splat(ty.vec4<f16>(), 3_h);
         auto* edge1 = b.Splat(ty.vec4<f16>(), 3_h);
-        auto* call_func = b.Call(ty.vec4(ty.f16()), core::BuiltinFn::kSmoothstep, edge0, edge1, e);
+        auto* call_func = b.Call(ty.vec4h(), core::BuiltinFn::kSmoothstep, edge0, edge1, e);
         b.ir.SetSource(call_func, Source{{5, 7}});
         b.Return(func, call_func->Result());
     });
@@ -555,7 +555,7 @@
 }
 
 TEST_F(IR_ConstParamValidatorTest, IncorrectDomainLdexp_Vec) {
-    auto* func = b.Function("foo", ty.vec4(ty.f32()));
+    auto* func = b.Function("foo", ty.vec4f());
     b.Append(func->Block(), [&] {
         auto* e1 = b.Let("b", b.Splat(ty.vec4<f32>(), 4_f));
         auto* e2 = b.Splat(ty.vec4<i32>(), 267_i);
@@ -582,7 +582,7 @@
 }
 
 TEST_F(IR_ConstParamValidatorTest, CorrectDomainLdexp_Vec) {
-    auto* func = b.Function("foo", ty.vec4(ty.f16()));
+    auto* func = b.Function("foo", ty.vec4h());
     b.Append(func->Block(), [&] {
         auto* e1 = b.Let("b", b.Splat(ty.vec4<f16>(), 4_h));
         auto* e2 = b.Splat(ty.vec4<i32>(), 10_i);
@@ -761,11 +761,11 @@
 }
 
 TEST_F(IR_ConstParamValidatorTest, IncorrectDomainShiftRight_Vec) {
-    auto* func = b.Function("foo", ty.vec4(ty.i32()));
+    auto* func = b.Function("foo", ty.vec4i());
     b.Append(func->Block(), [&] {
         auto* e1 = b.Let("b", b.Splat(ty.vec4<i32>(), 4_i));
         auto* e2 = b.Splat(ty.vec4<u32>(), 33_u);
-        auto* call_func = b.Binary(core::BinaryOp::kShiftLeft, ty.vec4(ty.i32()), e1, e2);
+        auto* call_func = b.Binary(core::BinaryOp::kShiftLeft, ty.vec4i(), e1, e2);
         b.ir.SetSource(call_func, Source{{5, 7}});
         b.Return(func, call_func->Result());
     });
@@ -841,11 +841,11 @@
 }
 
 TEST_F(IR_ConstParamValidatorTest, IncorrectDomainModulo_Vec) {
-    auto* func = b.Function("foo", ty.vec4(ty.i32()));
+    auto* func = b.Function("foo", ty.vec4i());
     b.Append(func->Block(), [&] {
         auto* e1 = b.Let("b", b.Splat(ty.vec4<i32>(), 4_i));
         auto* e2 = b.Splat(ty.vec4<i32>(), 0_i);
-        auto* call_func = b.Binary(core::BinaryOp::kModulo, ty.vec4(ty.i32()), e1, e2);
+        auto* call_func = b.Binary(core::BinaryOp::kModulo, ty.vec4i(), e1, e2);
         b.ir.SetSource(call_func, Source{{5, 7}});
         b.Return(func, call_func->Result());
     });
diff --git a/src/tint/lang/core/ir/transform/builtin_polyfill.cc b/src/tint/lang/core/ir/transform/builtin_polyfill.cc
index cdf4a6a..7ce3628 100644
--- a/src/tint/lang/core/ir/transform/builtin_polyfill.cc
+++ b/src/tint/lang/core/ir/transform/builtin_polyfill.cc
@@ -304,7 +304,7 @@
         auto* arg = call->Args()[0];
 
         b.InsertBefore(call, [&] {
-            auto* vec4f = ty.vec4<f32>();
+            auto* vec4f = ty.vec4f();
             auto* vec4u = ty.vec4<u32>();
 
             auto* neg_one = b.Splat(vec4f, -1_f);
@@ -337,7 +337,7 @@
         auto* arg = call->Args()[0];
 
         b.InsertBefore(call, [&] {
-            auto* vec4f = ty.vec4<f32>();
+            auto* vec4f = ty.vec4f();
             auto* vec4u = ty.vec4<u32>();
 
             auto* zero = b.Zero(vec4f);
@@ -368,7 +368,7 @@
         auto* arg = call->Args()[0];
 
         b.InsertBefore(call, [&] {
-            auto* vec4f = ty.vec4<f32>();
+            auto* vec4f = ty.vec4f();
             auto* vec4u = ty.vec4<u32>();
             auto* vec4i = ty.vec4<i32>();
 
@@ -393,7 +393,7 @@
         auto* arg = call->Args()[0];
 
         b.InsertBefore(call, [&] {
-            auto* vec4f = ty.vec4<f32>();
+            auto* vec4f = ty.vec4f();
             auto* vec4u = ty.vec4<u32>();
 
             auto* v = b.Construct(vec4u, arg)->Result();
diff --git a/src/tint/lang/core/type/manager.cc b/src/tint/lang/core/type/manager.cc
index 4eec22f..8e3c516 100644
--- a/src/tint/lang/core/type/manager.cc
+++ b/src/tint/lang/core/type/manager.cc
@@ -212,6 +212,46 @@
     return vec(inner, 4);
 }
 
+const core::type::Vector* Manager::vec2f() {
+    return vec(f32(), 2);
+}
+const core::type::Vector* Manager::vec3f() {
+    return vec(f32(), 3);
+}
+const core::type::Vector* Manager::vec4f() {
+    return vec(f32(), 4);
+}
+
+const core::type::Vector* Manager::vec2h() {
+    return vec(f16(), 2);
+}
+const core::type::Vector* Manager::vec3h() {
+    return vec(f16(), 3);
+}
+const core::type::Vector* Manager::vec4h() {
+    return vec(f16(), 4);
+}
+
+const core::type::Vector* Manager::vec2i() {
+    return vec(i32(), 2);
+}
+const core::type::Vector* Manager::vec3i() {
+    return vec(i32(), 3);
+}
+const core::type::Vector* Manager::vec4i() {
+    return vec(i32(), 4);
+}
+
+const core::type::Vector* Manager::vec2u() {
+    return vec(u32(), 2);
+}
+const core::type::Vector* Manager::vec3u() {
+    return vec(u32(), 3);
+}
+const core::type::Vector* Manager::vec4u() {
+    return vec(u32(), 4);
+}
+
 const core::type::SampledTexture* Manager::sampled_texture(TextureDimension dim,
                                                            const core::type::Type* type) {
     return Get<core::type::SampledTexture>(dim, type);
diff --git a/src/tint/lang/core/type/manager.h b/src/tint/lang/core/type/manager.h
index 749a571..0a1d1e9 100644
--- a/src/tint/lang/core/type/manager.h
+++ b/src/tint/lang/core/type/manager.h
@@ -272,6 +272,42 @@
     /// @returns a vec4 type with the element type @p inner
     const core::type::Vector* vec4(const core::type::Type* inner);
 
+    /// @returns a vec2 type with the element type f32
+    const core::type::Vector* vec2f();
+
+    /// @returns a vec3 type with the element type f32
+    const core::type::Vector* vec3f();
+
+    /// @returns a vec4 type with the element type f32
+    const core::type::Vector* vec4f();
+
+    /// @returns a vec2 type with the element type f16
+    const core::type::Vector* vec2h();
+
+    /// @returns a vec3 type with the element type f16
+    const core::type::Vector* vec3h();
+
+    /// @returns a vec4 type with the element type f16
+    const core::type::Vector* vec4h();
+
+    /// @returns a vec2 type with the element type i32
+    const core::type::Vector* vec2i();
+
+    /// @returns a vec3 type with the element type i32
+    const core::type::Vector* vec3i();
+
+    /// @returns a vec4 type with the element type i32
+    const core::type::Vector* vec4i();
+
+    /// @returns a vec2 type with the element type u32
+    const core::type::Vector* vec2u();
+
+    /// @returns a vec3 type with the element type u32
+    const core::type::Vector* vec3u();
+
+    /// @returns a vec4 type with the element type u32
+    const core::type::Vector* vec4u();
+
     /// @param dim the dimensionality of the texture
     /// @param type the data type of the sampled texture
     /// @returns a sampled texture type with the provided params
diff --git a/src/tint/lang/core/type/type_test.cc b/src/tint/lang/core/type/type_test.cc
index 0d75039..a2cb362 100644
--- a/src/tint/lang/core/type/type_test.cc
+++ b/src/tint/lang/core/type/type_test.cc
@@ -51,12 +51,12 @@
         f16 = ty.f16();
         i32 = ty.i32();
         u32 = ty.u32();
-        vec2_f32 = ty.vec2(f32);
-        vec3_f32 = ty.vec3(f32);
-        vec3_f16 = ty.vec3(f16);
-        vec4_f32 = ty.vec4(f32);
-        vec3_u32 = ty.vec3(u32);
-        vec3_i32 = ty.vec3(i32);
+        vec2_f32 = ty.vec2f();
+        vec3_f32 = ty.vec3f();
+        vec3_f16 = ty.vec3h();
+        vec4_f32 = ty.vec4f();
+        vec3_u32 = ty.vec3u();
+        vec3_i32 = ty.vec3i();
         vec3_af = ty.vec3(af);
         vec3_ai = ty.vec3(ai);
         mat2x4_f32 = ty.mat2x4(f32);
diff --git a/src/tint/lang/core/type/vector_test.cc b/src/tint/lang/core/type/vector_test.cc
index bbd44b8..86fe464 100644
--- a/src/tint/lang/core/type/vector_test.cc
+++ b/src/tint/lang/core/type/vector_test.cc
@@ -40,10 +40,10 @@
 
 TEST_F(VectorTest, Creation) {
     Manager ty;
-    auto* a = ty.vec2(ty.i32());
-    auto* b = ty.vec2(ty.i32());
-    auto* c = ty.vec2(ty.f32());
-    auto* d = ty.vec3(ty.f32());
+    auto* a = ty.vec2i();
+    auto* b = ty.vec2i();
+    auto* c = ty.vec2f();
+    auto* d = ty.vec3f();
 
     EXPECT_EQ(a->Type(), ty.i32());
     EXPECT_EQ(a->Width(), 2u);
@@ -55,7 +55,7 @@
 
 TEST_F(VectorTest, Creation_Packed) {
     Manager ty;
-    auto* v = ty.vec3(ty.f32());
+    auto* v = ty.vec3f();
     auto* p1 = ty.Get<Vector>(ty.f32(), 3u, true);
     auto* p2 = ty.Get<Vector>(ty.f32(), 3u, true);
 
@@ -71,18 +71,18 @@
 
 TEST_F(VectorTest, Hash) {
     Manager ty;
-    auto* a = ty.vec2(ty.i32());
-    auto* b = ty.vec2(ty.i32());
+    auto* a = ty.vec2i();
+    auto* b = ty.vec2i();
 
     EXPECT_EQ(a->unique_hash, b->unique_hash);
 }
 
 TEST_F(VectorTest, Equals) {
     Manager ty;
-    auto* a = ty.vec2(ty.i32());
-    auto* b = ty.vec2(ty.i32());
-    auto* c = ty.vec2(ty.f32());
-    auto* d = ty.vec3(ty.f32());
+    auto* a = ty.vec2i();
+    auto* b = ty.vec2i();
+    auto* c = ty.vec2f();
+    auto* d = ty.vec3f();
 
     EXPECT_TRUE(a->Equals(*b));
     EXPECT_FALSE(a->Equals(*c));
@@ -92,8 +92,7 @@
 
 TEST_F(VectorTest, FriendlyName) {
     Manager ty;
-    auto* f32 = ty.f32();
-    auto* v = ty.vec3(f32);
+    auto* v = ty.vec3f();
     EXPECT_EQ(v->FriendlyName(), "vec3<f32>");
 }
 
@@ -106,7 +105,7 @@
 
 TEST_F(VectorTest, Clone) {
     Manager ty;
-    auto* a = ty.vec2(ty.i32());
+    auto* a = ty.vec2i();
 
     core::type::Manager mgr;
     core::type::CloneContext ctx{{nullptr}, {nullptr, &mgr}};
diff --git a/src/tint/lang/glsl/writer/raise/texture_builtins_from_uniform.cc b/src/tint/lang/glsl/writer/raise/texture_builtins_from_uniform.cc
index 9814a93..6fc6ee6 100644
--- a/src/tint/lang/glsl/writer/raise/texture_builtins_from_uniform.cc
+++ b/src/tint/lang/glsl/writer/raise/texture_builtins_from_uniform.cc
@@ -108,7 +108,7 @@
 
         // Wrap the array<vec4> in a struct as GLSL cannot have uniforms that are arrays directly.
         Vector<core::type::Manager::StructMemberDesc, 1> members;
-        members.Push({ir.symbols.New("metadata"), ty.array(ty.vec4(ty.u32()), vec4_count)});
+        members.Push({ir.symbols.New("metadata"), ty.array(ty.vec4u(), vec4_count)});
         auto* strct =
             ir.Types().Struct(ir.symbols.New("TintTextureUniformData"), std::move(members));
 
@@ -169,8 +169,8 @@
         auto* index_in_array = b.Divide(ty.u32(), offset, u32(4));
         auto* index_in_vector = b.Modulo(ty.u32(), offset, u32(4));
 
-        auto* vec4_ptr = b.Access(ty.ptr<uniform>(ty.vec4(ty.u32())), texture_uniform_data_, u32(0),
-                                  index_in_array);
+        auto* vec4_ptr =
+            b.Access(ty.ptr<uniform>(ty.vec4u()), texture_uniform_data_, u32(0), index_in_array);
         auto* vec4_value = b.Load(vec4_ptr);
         auto* u32_value = b.Access(ty.u32(), vec4_value, index_in_vector);
         return u32_value->Result();
diff --git a/src/tint/lang/hlsl/writer/raise/raise.cc b/src/tint/lang/hlsl/writer/raise/raise.cc
index 8f18983..ac6819f 100644
--- a/src/tint/lang/hlsl/writer/raise/raise.cc
+++ b/src/tint/lang/hlsl/writer/raise/raise.cc
@@ -101,8 +101,7 @@
     if (options.num_workgroups_start_offset) {
         immediate_data_config.AddInternalImmediateData(
             options.num_workgroups_start_offset.value(),
-            module.symbols.New("tint_num_workgroups_start_offset"),
-            module.Types().vec3(module.Types().u32()));
+            module.symbols.New("tint_num_workgroups_start_offset"), module.Types().vec3u());
     }
     auto immediate_data_layout =
         core::ir::transform::PrepareImmediateData(module, immediate_data_config);
diff --git a/src/tint/lang/hlsl/writer/raise/shader_io_test.cc b/src/tint/lang/hlsl/writer/raise/shader_io_test.cc
index 47f0ec2..88f7438 100644
--- a/src/tint/lang/hlsl/writer/raise/shader_io_test.cc
+++ b/src/tint/lang/hlsl/writer/raise/shader_io_test.cc
@@ -1304,8 +1304,7 @@
 
     core::ir::transform::PrepareImmediateDataConfig prepare_immediate_data_layout_config;
     prepare_immediate_data_layout_config.AddInternalImmediateData(
-        num_workgroups_offset, mod.symbols.New("tint_num_workgroups_start_offset"),
-        ty.vec3(ty.u32()));
+        num_workgroups_offset, mod.symbols.New("tint_num_workgroups_start_offset"), ty.vec3u());
     auto layout =
         core::ir::transform::PrepareImmediateData(mod, prepare_immediate_data_layout_config);
 
@@ -1466,8 +1465,7 @@
 
     core::ir::transform::PrepareImmediateDataConfig prepare_immediate_data_layout_config;
     prepare_immediate_data_layout_config.AddInternalImmediateData(
-        num_workgroups_offset, mod.symbols.New("tint_num_workgroups_start_offset"),
-        ty.vec3(ty.u32()));
+        num_workgroups_offset, mod.symbols.New("tint_num_workgroups_start_offset"), ty.vec3u());
     auto layout =
         core::ir::transform::PrepareImmediateData(mod, prepare_immediate_data_layout_config);
 
@@ -1729,8 +1727,7 @@
 
     core::ir::transform::PrepareImmediateDataConfig prepare_immediate_data_layout_config;
     prepare_immediate_data_layout_config.AddInternalImmediateData(
-        num_workgroups_offset, mod.symbols.New("tint_num_workgroups_start_offset"),
-        ty.vec3(ty.u32()));
+        num_workgroups_offset, mod.symbols.New("tint_num_workgroups_start_offset"), ty.vec3u());
     auto layout =
         core::ir::transform::PrepareImmediateData(mod, prepare_immediate_data_layout_config);
 
@@ -1863,8 +1860,7 @@
 
     core::ir::transform::PrepareImmediateDataConfig prepare_immediate_data_layout_config;
     prepare_immediate_data_layout_config.AddInternalImmediateData(
-        num_workgroups_offset, mod.symbols.New("tint_num_workgroups_start_offset"),
-        ty.vec3(ty.u32()));
+        num_workgroups_offset, mod.symbols.New("tint_num_workgroups_start_offset"), ty.vec3u());
     auto layout =
         core::ir::transform::PrepareImmediateData(mod, prepare_immediate_data_layout_config);
 
@@ -2076,8 +2072,7 @@
 
     core::ir::transform::PrepareImmediateDataConfig prepare_immediate_data_layout_config;
     prepare_immediate_data_layout_config.AddInternalImmediateData(
-        num_workgroups_offset, mod.symbols.New("tint_num_workgroups_start_offset"),
-        ty.vec3(ty.u32()));
+        num_workgroups_offset, mod.symbols.New("tint_num_workgroups_start_offset"), ty.vec3u());
     auto layout =
         core::ir::transform::PrepareImmediateData(mod, prepare_immediate_data_layout_config);
 
diff --git a/src/tint/lang/spirv/writer/access_test.cc b/src/tint/lang/spirv/writer/access_test.cc
index 343320b..9acf3d9 100644
--- a/src/tint/lang/spirv/writer/access_test.cc
+++ b/src/tint/lang/spirv/writer/access_test.cc
@@ -102,7 +102,7 @@
     auto* func = b.Function("foo", ty.vec2<f32>());
     func->SetParams({mat_val});
     b.Append(func->Block(), [&] {
-        auto* result_vector = b.Access(ty.vec2(ty.f32()), mat_val, 1_u);
+        auto* result_vector = b.Access(ty.vec2f(), mat_val, 1_u);
         auto* result_scalar = b.Access(ty.f32(), mat_val, 1_u, 0_u);
         b.Return(func, b.Multiply(ty.vec2<f32>(), result_vector, result_scalar));
         mod.SetName(result_vector, "result_vector");
@@ -169,7 +169,7 @@
 }
 
 TEST_F(SpirvWriterTest, Access_Vector_Value_ConstantIndex) {
-    auto* vec_val = b.FunctionParam("vec", ty.vec4(ty.i32()));
+    auto* vec_val = b.FunctionParam("vec", ty.vec4i());
     auto* func = b.Function("foo", ty.i32());
     func->SetParams({vec_val});
     b.Append(func->Block(), [&] {
@@ -189,7 +189,7 @@
 }
 
 TEST_F(SpirvWriterTest, Access_Vector_Value_DynamicIndex) {
-    auto* vec_val = b.FunctionParam("vec", ty.vec4(ty.i32()));
+    auto* vec_val = b.FunctionParam("vec", ty.vec4i());
     auto* idx = b.FunctionParam("idx", ty.i32());
     auto* func = b.Function("foo", ty.i32());
     func->SetParams({vec_val, idx});
@@ -214,7 +214,7 @@
 }
 
 TEST_F(SpirvWriterTest, Access_NestedVector_Value_DynamicIndex) {
-    auto* arr_ty = ty.array(ty.array(ty.vec4(ty.i32()), 4), 4);
+    auto* arr_ty = ty.array(ty.array(ty.vec4i(), 4), 4);
 
     auto* val = b.FunctionParam("arr", arr_ty);
     auto* idx = b.FunctionParam("idx", ty.i32());
diff --git a/src/tint/lang/wgsl/resolver/materialize_test.cc b/src/tint/lang/wgsl/resolver/materialize_test.cc
index b14df1a..6b53999 100644
--- a/src/tint/lang/wgsl/resolver/materialize_test.cc
+++ b/src/tint/lang/wgsl/resolver/materialize_test.cc
@@ -46,12 +46,12 @@
 using AFloatA = array<AFloat, 3>;
 using AIntV = vec3<AInt>;
 using AIntA = array<AInt, 3>;
-using f32V = vec3<f32>;
-using f16V = vec3<f16>;
-using i32V = vec3<i32>;
-using u32V = vec3<u32>;
-using f32M = mat3x2<f32>;
-using f16M = mat3x2<f16>;
+using f32V = vec3f;
+using f16V = vec3h;
+using i32V = vec3i;
+using u32V = vec3u;
+using f32M = mat3x2f;
+using f16M = mat3x2h;
 using f32A = array<f32, 3>;
 using f16A = array<f16, 3>;
 using i32A = array<i32, 3>;