tint: Change all ProgramBuilder literals to 'i' or 'u' suffix

Unsuffixed integer literals are currently treated as i32,
but will shortly become AbstractInteger. To keep tests behaving
identically to how they are currently, change all test literals
to using either 'i' or 'u' suffixes.

Bug: tint:1504
Change-Id: Ic373d18ce1c718a16b6905568aec89da3641d36b
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/88845
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn
index 6826259..71cd2dc 100644
--- a/src/tint/BUILD.gn
+++ b/src/tint/BUILD.gn
@@ -345,6 +345,7 @@
     "debug.h",
     "demangler.cc",
     "demangler.h",
+    "number.h",
     "diagnostic/diagnostic.cc",
     "diagnostic/diagnostic.h",
     "diagnostic/formatter.cc",
diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt
index 9e606d2..4d10bcb 100644
--- a/src/tint/CMakeLists.txt
+++ b/src/tint/CMakeLists.txt
@@ -232,6 +232,7 @@
   clone_context.h
   demangler.cc
   demangler.h
+  number.h
   inspector/entry_point.cc
   inspector/entry_point.h
   inspector/inspector.cc
@@ -1043,6 +1044,7 @@
       transform/decompose_memory_access_test.cc
       transform/decompose_strided_array_test.cc
       transform/decompose_strided_matrix_test.cc
+      transform/expand_compound_assignment_test.cc
       transform/first_index_offset_test.cc
       transform/fold_constants_test.cc
       transform/fold_trivial_single_use_lets_test.cc
diff --git a/src/tint/ast/array_test.cc b/src/tint/ast/array_test.cc
index 345c04c..baed079 100644
--- a/src/tint/ast/array_test.cc
+++ b/src/tint/ast/array_test.cc
@@ -16,6 +16,8 @@
 
 #include "src/tint/ast/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::ast {
 namespace {
 
@@ -23,7 +25,7 @@
 
 TEST_F(AstArrayTest, CreateSizedArray) {
     auto* u32 = create<U32>();
-    auto* count = Expr(3);
+    auto* count = Expr(3_u);
     auto* arr = create<Array>(u32, count, AttributeList{});
     EXPECT_EQ(arr->type, u32);
     EXPECT_EQ(arr->count, count);
@@ -48,7 +50,7 @@
 
 TEST_F(AstArrayTest, FriendlyName_LiteralSized) {
     auto* i32 = create<I32>();
-    auto* arr = create<Array>(i32, Expr(5), AttributeList{});
+    auto* arr = create<Array>(i32, Expr(5_u), AttributeList{});
     EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32, 5>");
 }
 
@@ -60,7 +62,7 @@
 
 TEST_F(AstArrayTest, FriendlyName_WithStride) {
     auto* i32 = create<I32>();
-    auto* arr = create<Array>(i32, Expr(5), AttributeList{create<StrideAttribute>(32)});
+    auto* arr = create<Array>(i32, Expr(5_u), AttributeList{create<StrideAttribute>(32)});
     EXPECT_EQ(arr->FriendlyName(Symbols()), "@stride(32) array<i32, 5>");
 }
 
diff --git a/src/tint/ast/assignment_statement_test.cc b/src/tint/ast/assignment_statement_test.cc
index d361aaf..477501b 100644
--- a/src/tint/ast/assignment_statement_test.cc
+++ b/src/tint/ast/assignment_statement_test.cc
@@ -17,6 +17,8 @@
 #include "gtest/gtest-spi.h"
 #include "src/tint/ast/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::ast {
 namespace {
 
@@ -53,7 +55,7 @@
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b;
-            b.create<AssignmentStatement>(nullptr, b.Expr(1));
+            b.create<AssignmentStatement>(nullptr, b.Expr(1_i));
         },
         "internal compiler error");
 }
@@ -62,7 +64,7 @@
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b;
-            b.create<AssignmentStatement>(b.Expr(1), nullptr);
+            b.create<AssignmentStatement>(b.Expr(1_i), nullptr);
         },
         "internal compiler error");
 }
diff --git a/src/tint/ast/builtin_texture_helper_test.cc b/src/tint/ast/builtin_texture_helper_test.cc
index 976b507..8f9091d 100644
--- a/src/tint/ast/builtin_texture_helper_test.cc
+++ b/src/tint/ast/builtin_texture_helper_test.cc
@@ -18,11 +18,9 @@
 #include "src/tint/sem/multisampled_texture.h"
 #include "src/tint/sem/sampled_texture.h"
 
-namespace tint::ast::builtin::test {
+using namespace tint::number_suffixes;  // NOLINT
 
-using u32 = ProgramBuilder::u32;
-using i32 = ProgramBuilder::i32;
-using f32 = ProgramBuilder::f32;
+namespace tint::ast::builtin::test {
 
 TextureOverloadCase::TextureOverloadCase(ValidTextureOverload o,
                                          const char* desc,
@@ -214,7 +212,7 @@
             ast::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureDimensions",
-            [](ProgramBuilder* b) { return b->ExprList("texture", 1); },
+            [](ProgramBuilder* b) { return b->ExprList("texture", 1_i); },
         },
         {
             ValidTextureOverload::kDimensions2dArray,
@@ -235,7 +233,7 @@
             ast::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureDimensions",
-            [](ProgramBuilder* b) { return b->ExprList("texture", 1); },
+            [](ProgramBuilder* b) { return b->ExprList("texture", 1_i); },
         },
         {
             ValidTextureOverload::kDimensions3d,
@@ -256,7 +254,7 @@
             ast::TextureDimension::k3d,
             TextureDataType::kF32,
             "textureDimensions",
-            [](ProgramBuilder* b) { return b->ExprList("texture", 1); },
+            [](ProgramBuilder* b) { return b->ExprList("texture", 1_i); },
         },
         {
             ValidTextureOverload::kDimensionsCube,
@@ -277,7 +275,7 @@
             ast::TextureDimension::kCube,
             TextureDataType::kF32,
             "textureDimensions",
-            [](ProgramBuilder* b) { return b->ExprList("texture", 1); },
+            [](ProgramBuilder* b) { return b->ExprList("texture", 1_i); },
         },
         {
             ValidTextureOverload::kDimensionsCubeArray,
@@ -298,7 +296,7 @@
             ast::TextureDimension::kCubeArray,
             TextureDataType::kF32,
             "textureDimensions",
-            [](ProgramBuilder* b) { return b->ExprList("texture", 1); },
+            [](ProgramBuilder* b) { return b->ExprList("texture", 1_i); },
         },
         {
             ValidTextureOverload::kDimensionsMultisampled2d,
@@ -329,7 +327,7 @@
             ast::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureDimensions",
-            [](ProgramBuilder* b) { return b->ExprList("texture", 1); },
+            [](ProgramBuilder* b) { return b->ExprList("texture", 1_i); },
         },
         {
             ValidTextureOverload::kDimensionsDepth2dArray,
@@ -350,7 +348,7 @@
             ast::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureDimensions",
-            [](ProgramBuilder* b) { return b->ExprList("texture", 1); },
+            [](ProgramBuilder* b) { return b->ExprList("texture", 1_i); },
         },
         {
             ValidTextureOverload::kDimensionsDepthCube,
@@ -371,7 +369,7 @@
             ast::TextureDimension::kCube,
             TextureDataType::kF32,
             "textureDimensions",
-            [](ProgramBuilder* b) { return b->ExprList("texture", 1); },
+            [](ProgramBuilder* b) { return b->ExprList("texture", 1_i); },
         },
         {
             ValidTextureOverload::kDimensionsDepthCubeArray,
@@ -392,7 +390,7 @@
             ast::TextureDimension::kCubeArray,
             TextureDataType::kF32,
             "textureDimensions",
-            [](ProgramBuilder* b) { return b->ExprList("texture", 1); },
+            [](ProgramBuilder* b) { return b->ExprList("texture", 1_i); },
         },
         {
             ValidTextureOverload::kDimensionsDepthMultisampled2d,
@@ -460,7 +458,7 @@
             TextureDataType::kF32,
             "textureGather",
             [](ProgramBuilder* b) {
-                return b->ExprList(0,                        // component
+                return b->ExprList(0_i,                      // component
                                    "texture",                // t
                                    "sampler",                // s
                                    b->vec2<f32>(1.f, 2.f));  // coords
@@ -479,11 +477,11 @@
             TextureDataType::kF32,
             "textureGather",
             [](ProgramBuilder* b) {
-                return b->ExprList(0,                       // component
-                                   "texture",               // t
-                                   "sampler",               // s
-                                   b->vec2<f32>(1.f, 2.f),  // coords
-                                   b->vec2<i32>(3, 4));     // offset
+                return b->ExprList(0_i,                      // component
+                                   "texture",                // t
+                                   "sampler",                // s
+                                   b->vec2<f32>(1.f, 2.f),   // coords
+                                   b->vec2<i32>(3_i, 4_i));  // offset
             },
         },
         {
@@ -499,11 +497,11 @@
             TextureDataType::kF32,
             "textureGather",
             [](ProgramBuilder* b) {
-                return b->ExprList(0,                       // component
+                return b->ExprList(0_i,                     // component
                                    "texture",               // t
                                    "sampler",               // s
                                    b->vec2<f32>(1.f, 2.f),  // coords
-                                   3);                      // array index
+                                   3_i);                    // array index
             },
         },
         {
@@ -520,12 +518,12 @@
             TextureDataType::kF32,
             "textureGather",
             [](ProgramBuilder* b) {
-                return b->ExprList(0,                       // component
-                                   "texture",               // t
-                                   "sampler",               // s
-                                   b->vec2<f32>(1.f, 2.f),  // coords
-                                   3,                       // array_index
-                                   b->vec2<i32>(4, 5));     // offset
+                return b->ExprList(0_i,                      // component
+                                   "texture",                // t
+                                   "sampler",                // s
+                                   b->vec2<f32>(1.f, 2.f),   // coords
+                                   3_i,                      // array_index
+                                   b->vec2<i32>(4_i, 5_i));  // offset
             },
         },
         {
@@ -540,7 +538,7 @@
             TextureDataType::kF32,
             "textureGather",
             [](ProgramBuilder* b) {
-                return b->ExprList(0,                             // component
+                return b->ExprList(0_i,                           // component
                                    "texture",                     // t
                                    "sampler",                     // s
                                    b->vec3<f32>(1.f, 2.f, 3.f));  // coords
@@ -559,11 +557,11 @@
             TextureDataType::kF32,
             "textureGather",
             [](ProgramBuilder* b) {
-                return b->ExprList(0,                            // component
+                return b->ExprList(0_i,                          // component
                                    "texture",                    // t
                                    "sampler",                    // s
                                    b->vec3<f32>(1.f, 2.f, 3.f),  // coords
-                                   4);                           // array_index
+                                   4_i);                         // array_index
             },
         },
         {
@@ -594,10 +592,10 @@
             TextureDataType::kF32,
             "textureGather",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",               // t
-                                   "sampler",               // s
-                                   b->vec2<f32>(1.f, 2.f),  // coords
-                                   b->vec2<i32>(3, 4));     // offset
+                return b->ExprList("texture",                // t
+                                   "sampler",                // s
+                                   b->vec2<f32>(1.f, 2.f),   // coords
+                                   b->vec2<i32>(3_i, 4_i));  // offset
             },
         },
         {
@@ -615,7 +613,7 @@
                 return b->ExprList("texture",               // t
                                    "sampler",               // s
                                    b->vec2<f32>(1.f, 2.f),  // coords
-                                   3);                      // array_index
+                                   3_i);                    // array_index
             },
         },
         {
@@ -631,11 +629,11 @@
             TextureDataType::kF32,
             "textureGather",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",               // t
-                                   "sampler",               // s
-                                   b->vec2<f32>(1.f, 2.f),  // coords
-                                   3,                       // array_index
-                                   b->vec2<i32>(4, 5));     // offset
+                return b->ExprList("texture",                // t
+                                   "sampler",                // s
+                                   b->vec2<f32>(1.f, 2.f),   // coords
+                                   3_i,                      // array_index
+                                   b->vec2<i32>(4_i, 5_i));  // offset
             },
         },
         {
@@ -669,7 +667,7 @@
                 return b->ExprList("texture",                    // t
                                    "sampler",                    // s
                                    b->vec3<f32>(1.f, 2.f, 3.f),  // coords
-                                   4);                           // array_index
+                                   4_i);                         // array_index
             },
         },
         {
@@ -703,11 +701,11 @@
             TextureDataType::kF32,
             "textureGatherCompare",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",               // t
-                                   "sampler",               // s
-                                   b->vec2<f32>(1.f, 2.f),  // coords
-                                   3.f,                     // depth_ref
-                                   b->vec2<i32>(4, 5));     // offset
+                return b->ExprList("texture",                // t
+                                   "sampler",                // s
+                                   b->vec2<f32>(1.f, 2.f),   // coords
+                                   3.f,                      // depth_ref
+                                   b->vec2<i32>(4_i, 5_i));  // offset
             },
         },
         {
@@ -726,7 +724,7 @@
                 return b->ExprList("texture",               // t
                                    "sampler",               // s
                                    b->vec2<f32>(1.f, 2.f),  // coords
-                                   3,                       // array_index
+                                   3_i,                     // array_index
                                    4.f);                    // depth_ref
             },
         },
@@ -744,12 +742,12 @@
             TextureDataType::kF32,
             "textureGatherCompare",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",               // t
-                                   "sampler",               // s
-                                   b->vec2<f32>(1.f, 2.f),  // coords
-                                   3,                       // array_index
-                                   4.f,                     // depth_ref
-                                   b->vec2<i32>(5, 6));     // offset
+                return b->ExprList("texture",                // t
+                                   "sampler",                // s
+                                   b->vec2<f32>(1.f, 2.f),   // coords
+                                   3_i,                      // array_index
+                                   4.f,                      // depth_ref
+                                   b->vec2<i32>(5_i, 6_i));  // offset
             },
         },
         {
@@ -786,7 +784,7 @@
                 return b->ExprList("texture",                    // t
                                    "sampler",                    // s
                                    b->vec3<f32>(1.f, 2.f, 3.f),  // coords
-                                   4,                            // array_index
+                                   4_i,                          // array_index
                                    5.f);                         // depth_ref
             },
         },
@@ -984,10 +982,10 @@
             TextureDataType::kF32,
             "textureSample",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",               // t
-                                   "sampler",               // s
-                                   b->vec2<f32>(1.f, 2.f),  // coords
-                                   b->vec2<i32>(3, 4));     // offset
+                return b->ExprList("texture",                // t
+                                   "sampler",                // s
+                                   b->vec2<f32>(1.f, 2.f),   // coords
+                                   b->vec2<i32>(3_i, 4_i));  // offset
             },
         },
         {
@@ -1005,7 +1003,7 @@
                 return b->ExprList("texture",               // t
                                    "sampler",               // s
                                    b->vec2<f32>(1.f, 2.f),  // coords
-                                   3);                      // array_index
+                                   3_i);                    // array_index
             },
         },
         {
@@ -1021,11 +1019,11 @@
             TextureDataType::kF32,
             "textureSample",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",               // t
-                                   "sampler",               // s
-                                   b->vec2<f32>(1.f, 2.f),  // coords
-                                   3,                       // array_index
-                                   b->vec2<i32>(4, 5));     // offset
+                return b->ExprList("texture",                // t
+                                   "sampler",                // s
+                                   b->vec2<f32>(1.f, 2.f),   // coords
+                                   3_i,                      // array_index
+                                   b->vec2<i32>(4_i, 5_i));  // offset
             },
         },
         {
@@ -1056,10 +1054,10 @@
             TextureDataType::kF32,
             "textureSample",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",                    // t
-                                   "sampler",                    // s
-                                   b->vec3<f32>(1.f, 2.f, 3.f),  // coords
-                                   b->vec3<i32>(4, 5, 6));       // offset
+                return b->ExprList("texture",                     // t
+                                   "sampler",                     // s
+                                   b->vec3<f32>(1.f, 2.f, 3.f),   // coords
+                                   b->vec3<i32>(4_i, 5_i, 6_i));  // offset
             },
         },
         {
@@ -1093,7 +1091,7 @@
                 return b->ExprList("texture",                    // t
                                    "sampler",                    // s
                                    b->vec3<f32>(1.f, 2.f, 3.f),  // coords
-                                   4);                           // array_index
+                                   4_i);                         // array_index
             },
         },
         {
@@ -1124,10 +1122,10 @@
             TextureDataType::kF32,
             "textureSample",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",               // t
-                                   "sampler",               // s
-                                   b->vec2<f32>(1.f, 2.f),  // coords
-                                   b->vec2<i32>(3, 4));     // offset
+                return b->ExprList("texture",                // t
+                                   "sampler",                // s
+                                   b->vec2<f32>(1.f, 2.f),   // coords
+                                   b->vec2<i32>(3_i, 4_i));  // offset
             },
         },
         {
@@ -1145,7 +1143,7 @@
                 return b->ExprList("texture",               // t
                                    "sampler",               // s
                                    b->vec2<f32>(1.f, 2.f),  // coords
-                                   3);                      // array_index
+                                   3_i);                    // array_index
             },
         },
         {
@@ -1161,11 +1159,11 @@
             TextureDataType::kF32,
             "textureSample",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",               // t
-                                   "sampler",               // s
-                                   b->vec2<f32>(1.f, 2.f),  // coords
-                                   3,                       // array_index
-                                   b->vec2<i32>(4, 5));     // offset
+                return b->ExprList("texture",                // t
+                                   "sampler",                // s
+                                   b->vec2<f32>(1.f, 2.f),   // coords
+                                   3_i,                      // array_index
+                                   b->vec2<i32>(4_i, 5_i));  // offset
             },
         },
         {
@@ -1199,7 +1197,7 @@
                 return b->ExprList("texture",                    // t
                                    "sampler",                    // s
                                    b->vec3<f32>(1.f, 2.f, 3.f),  // coords
-                                   4);                           // array_index
+                                   4_i);                         // array_index
             },
         },
         {
@@ -1233,11 +1231,11 @@
             TextureDataType::kF32,
             "textureSampleBias",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",               // t
-                                   "sampler",               // s
-                                   b->vec2<f32>(1.f, 2.f),  // coords
-                                   3.f,                     // bias
-                                   b->vec2<i32>(4, 5));     // offset
+                return b->ExprList("texture",                // t
+                                   "sampler",                // s
+                                   b->vec2<f32>(1.f, 2.f),   // coords
+                                   3.f,                      // bias
+                                   b->vec2<i32>(4_i, 5_i));  // offset
             },
         },
         {
@@ -1256,7 +1254,7 @@
                 return b->ExprList("texture",               // t
                                    "sampler",               // s
                                    b->vec2<f32>(1.f, 2.f),  // coords
-                                   4,                       // array_index
+                                   4_i,                     // array_index
                                    3.f);                    // bias
             },
         },
@@ -1274,12 +1272,12 @@
             TextureDataType::kF32,
             "textureSampleBias",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",               // t
-                                   "sampler",               // s
-                                   b->vec2<f32>(1.f, 2.f),  // coords
-                                   3,                       // array_index
-                                   4.f,                     // bias
-                                   b->vec2<i32>(5, 6));     // offset
+                return b->ExprList("texture",                // t
+                                   "sampler",                // s
+                                   b->vec2<f32>(1.f, 2.f),   // coords
+                                   3_i,                      // array_index
+                                   4.f,                      // bias
+                                   b->vec2<i32>(5_i, 6_i));  // offset
             },
         },
         {
@@ -1313,11 +1311,11 @@
             TextureDataType::kF32,
             "textureSampleBias",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",                    // t
-                                   "sampler",                    // s
-                                   b->vec3<f32>(1.f, 2.f, 3.f),  // coords
-                                   4.f,                          // bias
-                                   b->vec3<i32>(5, 6, 7));       // offset
+                return b->ExprList("texture",                     // t
+                                   "sampler",                     // s
+                                   b->vec3<f32>(1.f, 2.f, 3.f),   // coords
+                                   4.f,                           // bias
+                                   b->vec3<i32>(5_i, 6_i, 7_i));  // offset
             },
         },
         {
@@ -1354,7 +1352,7 @@
                 return b->ExprList("texture",                    // t
                                    "sampler",                    // s
                                    b->vec3<f32>(1.f, 2.f, 3.f),  // coords
-                                   3,                            // array_index
+                                   3_i,                          // array_index
                                    4.f);                         // bias
             },
         },
@@ -1389,11 +1387,11 @@
             TextureDataType::kF32,
             "textureSampleLevel",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",               // t
-                                   "sampler",               // s
-                                   b->vec2<f32>(1.f, 2.f),  // coords
-                                   3.f,                     // level
-                                   b->vec2<i32>(4, 5));     // offset
+                return b->ExprList("texture",                // t
+                                   "sampler",                // s
+                                   b->vec2<f32>(1.f, 2.f),   // coords
+                                   3.f,                      // level
+                                   b->vec2<i32>(4_i, 5_i));  // offset
             },
         },
         {
@@ -1412,7 +1410,7 @@
                 return b->ExprList("texture",               // t
                                    "sampler",               // s
                                    b->vec2<f32>(1.f, 2.f),  // coords
-                                   3,                       // array_index
+                                   3_i,                     // array_index
                                    4.f);                    // level
             },
         },
@@ -1430,12 +1428,12 @@
             TextureDataType::kF32,
             "textureSampleLevel",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",               // t
-                                   "sampler",               // s
-                                   b->vec2<f32>(1.f, 2.f),  // coords
-                                   3,                       // array_index
-                                   4.f,                     // level
-                                   b->vec2<i32>(5, 6));     // offset
+                return b->ExprList("texture",                // t
+                                   "sampler",                // s
+                                   b->vec2<f32>(1.f, 2.f),   // coords
+                                   3_i,                      // array_index
+                                   4.f,                      // level
+                                   b->vec2<i32>(5_i, 6_i));  // offset
             },
         },
         {
@@ -1469,11 +1467,11 @@
             TextureDataType::kF32,
             "textureSampleLevel",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",                    // t
-                                   "sampler",                    // s
-                                   b->vec3<f32>(1.f, 2.f, 3.f),  // coords
-                                   4.f,                          // level
-                                   b->vec3<i32>(5, 6, 7));       // offset
+                return b->ExprList("texture",                     // t
+                                   "sampler",                     // s
+                                   b->vec3<f32>(1.f, 2.f, 3.f),   // coords
+                                   4.f,                           // level
+                                   b->vec3<i32>(5_i, 6_i, 7_i));  // offset
             },
         },
         {
@@ -1510,7 +1508,7 @@
                 return b->ExprList("texture",                    // t
                                    "sampler",                    // s
                                    b->vec3<f32>(1.f, 2.f, 3.f),  // coords
-                                   4,                            // array_index
+                                   4_i,                          // array_index
                                    5.f);                         // level
             },
         },
@@ -1529,7 +1527,7 @@
                 return b->ExprList("texture",               // t
                                    "sampler",               // s
                                    b->vec2<f32>(1.f, 2.f),  // coords
-                                   3);                      // level
+                                   3_i);                    // level
             },
         },
         {
@@ -1545,11 +1543,11 @@
             TextureDataType::kF32,
             "textureSampleLevel",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",               // t
-                                   "sampler",               // s
-                                   b->vec2<f32>(1.f, 2.f),  // coords
-                                   3,                       // level
-                                   b->vec2<i32>(4, 5));     // offset
+                return b->ExprList("texture",                // t
+                                   "sampler",                // s
+                                   b->vec2<f32>(1.f, 2.f),   // coords
+                                   3_i,                      // level
+                                   b->vec2<i32>(4_i, 5_i));  // offset
             },
         },
         {
@@ -1568,8 +1566,8 @@
                 return b->ExprList("texture",               // t
                                    "sampler",               // s
                                    b->vec2<f32>(1.f, 2.f),  // coords
-                                   3,                       // array_index
-                                   4);                      // level
+                                   3_i,                     // array_index
+                                   4_i);                    // level
             },
         },
         {
@@ -1586,12 +1584,12 @@
             TextureDataType::kF32,
             "textureSampleLevel",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",               // t
-                                   "sampler",               // s
-                                   b->vec2<f32>(1.f, 2.f),  // coords
-                                   3,                       // array_index
-                                   4,                       // level
-                                   b->vec2<i32>(5, 6));     // offset
+                return b->ExprList("texture",                // t
+                                   "sampler",                // s
+                                   b->vec2<f32>(1.f, 2.f),   // coords
+                                   3_i,                      // array_index
+                                   4_i,                      // level
+                                   b->vec2<i32>(5_i, 6_i));  // offset
             },
         },
         {
@@ -1609,7 +1607,7 @@
                 return b->ExprList("texture",                    // t
                                    "sampler",                    // s
                                    b->vec3<f32>(1.f, 2.f, 3.f),  // coords
-                                   4);                           // level
+                                   4_i);                         // level
             },
         },
         {
@@ -1628,8 +1626,8 @@
                 return b->ExprList("texture",                    // t
                                    "sampler",                    // s
                                    b->vec3<f32>(1.f, 2.f, 3.f),  // coords
-                                   4,                            // array_index
-                                   5);                           // level
+                                   4_i,                          // array_index
+                                   5_i);                         // level
             },
         },
         {
@@ -1666,12 +1664,12 @@
             TextureDataType::kF32,
             "textureSampleGrad",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",               // t
-                                   "sampler",               // s
-                                   b->vec2<f32>(1.f, 2.f),  // coords
-                                   b->vec2<f32>(3.f, 4.f),  // ddx
-                                   b->vec2<f32>(5.f, 6.f),  // ddy
-                                   b->vec2<i32>(7, 7));     // offset
+                return b->ExprList("texture",                // t
+                                   "sampler",                // s
+                                   b->vec2<f32>(1.f, 2.f),   // coords
+                                   b->vec2<f32>(3.f, 4.f),   // ddx
+                                   b->vec2<f32>(5.f, 6.f),   // ddy
+                                   b->vec2<i32>(7_i, 7_i));  // offset
             },
         },
         {
@@ -1691,7 +1689,7 @@
                 return b->ExprList("texture",                // t
                                    "sampler",                // s
                                    b->vec2<f32>(1.f, 2.f),   // coords
-                                   3,                        // array_index
+                                   3_i,                      // array_index
                                    b->vec2<f32>(4.f, 5.f),   // ddx
                                    b->vec2<f32>(6.f, 7.f));  // ddy
             },
@@ -1711,13 +1709,13 @@
             TextureDataType::kF32,
             "textureSampleGrad",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",               // t
-                                   "sampler",               // s
-                                   b->vec2<f32>(1.f, 2.f),  // coords
-                                   3,                       // array_index
-                                   b->vec2<f32>(4.f, 5.f),  // ddx
-                                   b->vec2<f32>(6.f, 7.f),  // ddy
-                                   b->vec2<i32>(6, 7));     // offset
+                return b->ExprList("texture",                // t
+                                   "sampler",                // s
+                                   b->vec2<f32>(1.f, 2.f),   // coords
+                                   3_i,                      // array_index
+                                   b->vec2<f32>(4.f, 5.f),   // ddx
+                                   b->vec2<f32>(6.f, 7.f),   // ddy
+                                   b->vec2<i32>(6_i, 7_i));  // offset
             },
         },
         {
@@ -1754,12 +1752,12 @@
             TextureDataType::kF32,
             "textureSampleGrad",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",                    // t
-                                   "sampler",                    // s
-                                   b->vec3<f32>(1.f, 2.f, 3.f),  // coords
-                                   b->vec3<f32>(4.f, 5.f, 6.f),  // ddx
-                                   b->vec3<f32>(7.f, 8.f, 9.f),  // ddy
-                                   b->vec3<i32>(0, 1, 2));       // offset
+                return b->ExprList("texture",                     // t
+                                   "sampler",                     // s
+                                   b->vec3<f32>(1.f, 2.f, 3.f),   // coords
+                                   b->vec3<f32>(4.f, 5.f, 6.f),   // ddx
+                                   b->vec3<f32>(7.f, 8.f, 9.f),   // ddy
+                                   b->vec3<i32>(0_i, 1_i, 2_i));  // offset
             },
         },
         {
@@ -1799,7 +1797,7 @@
                 return b->ExprList("texture",                      // t
                                    "sampler",                      // s
                                    b->vec3<f32>(1.f, 2.f, 3.f),    // coords
-                                   4,                              // array_index
+                                   4_i,                            // array_index
                                    b->vec3<f32>(5.f, 6.f, 7.f),    // ddx
                                    b->vec3<f32>(8.f, 9.f, 10.f));  // ddy
             },
@@ -1835,11 +1833,11 @@
             TextureDataType::kF32,
             "textureSampleCompare",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",               // t
-                                   "sampler",               // s
-                                   b->vec2<f32>(1.f, 2.f),  // coords
-                                   3.f,                     // depth_ref
-                                   b->vec2<i32>(4, 5));     // offset
+                return b->ExprList("texture",                // t
+                                   "sampler",                // s
+                                   b->vec2<f32>(1.f, 2.f),   // coords
+                                   3.f,                      // depth_ref
+                                   b->vec2<i32>(4_i, 5_i));  // offset
             },
         },
         {
@@ -1858,7 +1856,7 @@
                 return b->ExprList("texture",               // t
                                    "sampler",               // s
                                    b->vec2<f32>(1.f, 2.f),  // coords
-                                   4,                       // array_index
+                                   4_i,                     // array_index
                                    3.f);                    // depth_ref
             },
         },
@@ -1876,12 +1874,12 @@
             TextureDataType::kF32,
             "textureSampleCompare",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",               // t
-                                   "sampler",               // s
-                                   b->vec2<f32>(1.f, 2.f),  // coords
-                                   4,                       // array_index
-                                   3.f,                     // depth_ref
-                                   b->vec2<i32>(5, 6));     // offset
+                return b->ExprList("texture",                // t
+                                   "sampler",                // s
+                                   b->vec2<f32>(1.f, 2.f),   // coords
+                                   4_i,                      // array_index
+                                   3.f,                      // depth_ref
+                                   b->vec2<i32>(5_i, 6_i));  // offset
             },
         },
         {
@@ -1918,7 +1916,7 @@
                 return b->ExprList("texture",                    // t
                                    "sampler",                    // s
                                    b->vec3<f32>(1.f, 2.f, 3.f),  // coords
-                                   4,                            // array_index
+                                   4_i,                          // array_index
                                    5.f);                         // depth_ref
             },
         },
@@ -1933,8 +1931,8 @@
             "textureLoad",
             [](ProgramBuilder* b) {
                 return b->ExprList("texture",  // t
-                                   1,          // coords
-                                   3);         // level
+                                   1_i,        // coords
+                                   3_i);       // level
             },
         },
         {
@@ -1948,8 +1946,8 @@
             "textureLoad",
             [](ProgramBuilder* b) {
                 return b->ExprList("texture",  // t
-                                   1,          // coords
-                                   3);         // level
+                                   1_i,        // coords
+                                   3_i);       // level
             },
         },
         {
@@ -1963,8 +1961,8 @@
             "textureLoad",
             [](ProgramBuilder* b) {
                 return b->ExprList("texture",  // t
-                                   1,          // coords
-                                   3);         // level
+                                   1_i,        // coords
+                                   3_i);       // level
             },
         },
         {
@@ -1977,9 +1975,9 @@
             TextureDataType::kF32,
             "textureLoad",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",           // t
-                                   b->vec2<i32>(1, 2),  // coords
-                                   3);                  // level
+                return b->ExprList("texture",               // t
+                                   b->vec2<i32>(1_i, 2_i),  // coords
+                                   3_i);                    // level
             },
         },
         {
@@ -1992,9 +1990,9 @@
             TextureDataType::kU32,
             "textureLoad",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",           // t
-                                   b->vec2<i32>(1, 2),  // coords
-                                   3);                  // level
+                return b->ExprList("texture",               // t
+                                   b->vec2<i32>(1_i, 2_i),  // coords
+                                   3_i);                    // level
             },
         },
         {
@@ -2007,9 +2005,9 @@
             TextureDataType::kI32,
             "textureLoad",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",           // t
-                                   b->vec2<i32>(1, 2),  // coords
-                                   3);                  // level
+                return b->ExprList("texture",               // t
+                                   b->vec2<i32>(1_i, 2_i),  // coords
+                                   3_i);                    // level
             },
         },
         {
@@ -2023,10 +2021,10 @@
             TextureDataType::kF32,
             "textureLoad",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",           // t
-                                   b->vec2<i32>(1, 2),  // coords
-                                   3,                   // array_index
-                                   4);                  // level
+                return b->ExprList("texture",               // t
+                                   b->vec2<i32>(1_i, 2_i),  // coords
+                                   3_i,                     // array_index
+                                   4_i);                    // level
             },
         },
         {
@@ -2040,10 +2038,10 @@
             TextureDataType::kU32,
             "textureLoad",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",           // t
-                                   b->vec2<i32>(1, 2),  // coords
-                                   3,                   // array_index
-                                   4);                  // level
+                return b->ExprList("texture",               // t
+                                   b->vec2<i32>(1_i, 2_i),  // coords
+                                   3_i,                     // array_index
+                                   4_i);                    // level
             },
         },
         {
@@ -2057,10 +2055,10 @@
             TextureDataType::kI32,
             "textureLoad",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",           // t
-                                   b->vec2<i32>(1, 2),  // coords
-                                   3,                   // array_index
-                                   4);                  // level
+                return b->ExprList("texture",               // t
+                                   b->vec2<i32>(1_i, 2_i),  // coords
+                                   3_i,                     // array_index
+                                   4_i);                    // level
             },
         },
         {
@@ -2073,9 +2071,9 @@
             TextureDataType::kF32,
             "textureLoad",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",              // t
-                                   b->vec3<i32>(1, 2, 3),  // coords
-                                   4);                     // level
+                return b->ExprList("texture",                    // t
+                                   b->vec3<i32>(1_i, 2_i, 3_i),  // coords
+                                   4_i);                         // level
             },
         },
         {
@@ -2088,9 +2086,9 @@
             TextureDataType::kU32,
             "textureLoad",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",              // t
-                                   b->vec3<i32>(1, 2, 3),  // coords
-                                   4);                     // level
+                return b->ExprList("texture",                    // t
+                                   b->vec3<i32>(1_i, 2_i, 3_i),  // coords
+                                   4_i);                         // level
             },
         },
         {
@@ -2103,9 +2101,9 @@
             TextureDataType::kI32,
             "textureLoad",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",              // t
-                                   b->vec3<i32>(1, 2, 3),  // coords
-                                   4);                     // level
+                return b->ExprList("texture",                    // t
+                                   b->vec3<i32>(1_i, 2_i, 3_i),  // coords
+                                   4_i);                         // level
             },
         },
         {
@@ -2118,9 +2116,9 @@
             TextureDataType::kF32,
             "textureLoad",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",           // t
-                                   b->vec2<i32>(1, 2),  // coords
-                                   3);                  // sample_index
+                return b->ExprList("texture",               // t
+                                   b->vec2<i32>(1_i, 2_i),  // coords
+                                   3_i);                    // sample_index
             },
         },
         {
@@ -2133,9 +2131,9 @@
             TextureDataType::kU32,
             "textureLoad",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",           // t
-                                   b->vec2<i32>(1, 2),  // coords
-                                   3);                  // sample_index
+                return b->ExprList("texture",               // t
+                                   b->vec2<i32>(1_i, 2_i),  // coords
+                                   3_i);                    // sample_index
             },
         },
         {
@@ -2148,9 +2146,9 @@
             TextureDataType::kI32,
             "textureLoad",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",           // t
-                                   b->vec2<i32>(1, 2),  // coords
-                                   3);                  // sample_index
+                return b->ExprList("texture",               // t
+                                   b->vec2<i32>(1_i, 2_i),  // coords
+                                   3_i);                    // sample_index
             },
         },
         {
@@ -2163,9 +2161,9 @@
             TextureDataType::kF32,
             "textureLoad",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",           // t
-                                   b->vec2<i32>(1, 2),  // coords
-                                   3);                  // level
+                return b->ExprList("texture",               // t
+                                   b->vec2<i32>(1_i, 2_i),  // coords
+                                   3_i);                    // level
             },
         },
         {
@@ -2179,10 +2177,10 @@
             TextureDataType::kF32,
             "textureLoad",
             [](ProgramBuilder* b) {
-                return b->ExprList("texture",           // t
-                                   b->vec2<i32>(1, 2),  // coords
-                                   3,                   // array_index
-                                   4);                  // level
+                return b->ExprList("texture",               // t
+                                   b->vec2<i32>(1_i, 2_i),  // coords
+                                   3_i,                     // array_index
+                                   4_i);                    // level
             },
         },
         {
@@ -2197,7 +2195,7 @@
             "textureStore",
             [](ProgramBuilder* b) {
                 return b->ExprList("texture",                          // t
-                                   1,                                  // coords
+                                   1_i,                                // coords
                                    b->vec4<f32>(2.f, 3.f, 4.f, 5.f));  // value
             },
         },
@@ -2213,7 +2211,7 @@
             "textureStore",
             [](ProgramBuilder* b) {
                 return b->ExprList("texture",                          // t
-                                   b->vec2<i32>(1, 2),                 // coords
+                                   b->vec2<i32>(1_i, 2_i),             // coords
                                    b->vec4<f32>(3.f, 4.f, 5.f, 6.f));  // value
             },
         },
@@ -2230,8 +2228,8 @@
             "textureStore",
             [](ProgramBuilder* b) {
                 return b->ExprList("texture",                          // t
-                                   b->vec2<i32>(1, 2),                 // coords
-                                   3,                                  // array_index
+                                   b->vec2<i32>(1_i, 2_i),             // coords
+                                   3_i,                                // array_index
                                    b->vec4<f32>(4.f, 5.f, 6.f, 7.f));  // value
             },
         },
@@ -2247,7 +2245,7 @@
             "textureStore",
             [](ProgramBuilder* b) {
                 return b->ExprList("texture",                          // t
-                                   b->vec3<i32>(1, 2, 3),              // coords
+                                   b->vec3<i32>(1_i, 2_i, 3_i),        // coords
                                    b->vec4<f32>(4.f, 5.f, 6.f, 7.f));  // value
             },
         },
diff --git a/src/tint/ast/case_statement_test.cc b/src/tint/ast/case_statement_test.cc
index 314a642..12fcbda 100644
--- a/src/tint/ast/case_statement_test.cc
+++ b/src/tint/ast/case_statement_test.cc
@@ -19,6 +19,8 @@
 #include "src/tint/ast/if_statement.h"
 #include "src/tint/ast/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::ast {
 namespace {
 
@@ -26,7 +28,7 @@
 
 TEST_F(CaseStatementTest, Creation_i32) {
     CaseSelectorList b;
-    auto* selector = Expr(2);
+    auto* selector = Expr(2_i);
     b.push_back(selector);
 
     auto* discard = create<DiscardStatement>();
@@ -41,7 +43,7 @@
 
 TEST_F(CaseStatementTest, Creation_u32) {
     CaseSelectorList b;
-    auto* selector = Expr(2u);
+    auto* selector = Expr(2_u);
     b.push_back(selector);
 
     auto* discard = create<DiscardStatement>();
@@ -56,7 +58,7 @@
 
 TEST_F(CaseStatementTest, Creation_WithSource) {
     CaseSelectorList b;
-    b.push_back(Expr(2));
+    b.push_back(Expr(2_i));
 
     auto* body = create<BlockStatement>(StatementList{
         create<DiscardStatement>(),
@@ -77,7 +79,7 @@
 
 TEST_F(CaseStatementTest, IsDefault_WithSelectors) {
     CaseSelectorList b;
-    b.push_back(Expr(2));
+    b.push_back(Expr(2_i));
 
     auto* c = create<CaseStatement>(b, create<BlockStatement>(StatementList{}));
     EXPECT_FALSE(c->IsDefault());
@@ -123,7 +125,7 @@
         {
             ProgramBuilder b1;
             ProgramBuilder b2;
-            b1.create<CaseStatement>(CaseSelectorList{b2.Expr(2)},
+            b1.create<CaseStatement>(CaseSelectorList{b2.Expr(2_i)},
                                      b1.create<BlockStatement>(StatementList{}));
         },
         "internal compiler error");
diff --git a/src/tint/ast/compound_assignment_statement_test.cc b/src/tint/ast/compound_assignment_statement_test.cc
index 47e7201..7560889 100644
--- a/src/tint/ast/compound_assignment_statement_test.cc
+++ b/src/tint/ast/compound_assignment_statement_test.cc
@@ -17,6 +17,8 @@
 #include "gtest/gtest-spi.h"
 #include "src/tint/ast/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::ast {
 namespace {
 
@@ -57,7 +59,7 @@
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b;
-            b.create<CompoundAssignmentStatement>(nullptr, b.Expr(1), BinaryOp::kAdd);
+            b.create<CompoundAssignmentStatement>(nullptr, b.Expr(1_i), BinaryOp::kAdd);
         },
         "internal compiler error");
 }
@@ -66,7 +68,7 @@
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b;
-            b.create<CompoundAssignmentStatement>(b.Expr(1), nullptr, BinaryOp::kAdd);
+            b.create<CompoundAssignmentStatement>(b.Expr(1_i), nullptr, BinaryOp::kAdd);
         },
         "internal compiler error");
 }
diff --git a/src/tint/ast/for_loop_statement_test.cc b/src/tint/ast/for_loop_statement_test.cc
index f0826e9..5e2a000 100644
--- a/src/tint/ast/for_loop_statement_test.cc
+++ b/src/tint/ast/for_loop_statement_test.cc
@@ -16,6 +16,8 @@
 #include "src/tint/ast/binary_expression.h"
 #include "src/tint/ast/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::ast {
 namespace {
 
@@ -23,8 +25,8 @@
 
 TEST_F(ForLoopStatementTest, Creation) {
     auto* init = Decl(Var("i", ty.u32()));
-    auto* cond = create<BinaryExpression>(BinaryOp::kLessThan, Expr("i"), Expr(5u));
-    auto* cont = Assign("i", Add("i", 1));
+    auto* cond = create<BinaryExpression>(BinaryOp::kLessThan, Expr("i"), Expr(5_u));
+    auto* cont = Assign("i", Add("i", 1_u));
     auto* body = Block(Return());
     auto* l = For(init, cond, cont, body);
 
diff --git a/src/tint/ast/function_test.cc b/src/tint/ast/function_test.cc
index 464bdcf..bd05fd8 100644
--- a/src/tint/ast/function_test.cc
+++ b/src/tint/ast/function_test.cc
@@ -18,6 +18,8 @@
 #include "src/tint/ast/test_helper.h"
 #include "src/tint/ast/workgroup_attribute.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::ast {
 namespace {
 
@@ -105,7 +107,7 @@
             ProgramBuilder b2;
             b1.Func("func", VariableList{}, b1.ty.void_(), StatementList{},
                     AttributeList{
-                        b2.WorkgroupSize(2, 4, 6),
+                        b2.WorkgroupSize(2_i, 4_i, 6_i),
                     });
         },
         "internal compiler error");
@@ -118,7 +120,7 @@
             ProgramBuilder b2;
             b1.Func("func", VariableList{}, b1.ty.void_(), StatementList{}, AttributeList{},
                     AttributeList{
-                        b2.WorkgroupSize(2, 4, 6),
+                        b2.WorkgroupSize(2_i, 4_i, 6_i),
                     });
         },
         "internal compiler error");
diff --git a/src/tint/ast/switch_statement_test.cc b/src/tint/ast/switch_statement_test.cc
index 9d2d5d2..19d1cfb 100644
--- a/src/tint/ast/switch_statement_test.cc
+++ b/src/tint/ast/switch_statement_test.cc
@@ -17,6 +17,8 @@
 #include "gtest/gtest-spi.h"
 #include "src/tint/ast/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::ast {
 namespace {
 
@@ -24,7 +26,7 @@
 
 TEST_F(SwitchStatementTest, Creation) {
     CaseSelectorList lit;
-    lit.push_back(Expr(1));
+    lit.push_back(Expr(1_u));
 
     auto* ident = Expr("ident");
     CaseStatementList body;
@@ -49,7 +51,7 @@
 
 TEST_F(SwitchStatementTest, IsSwitch) {
     CaseSelectorList lit;
-    lit.push_back(Expr(2));
+    lit.push_back(Expr(2_i));
 
     auto* ident = Expr("ident");
     CaseStatementList body;
@@ -64,7 +66,7 @@
         {
             ProgramBuilder b;
             CaseStatementList cases;
-            cases.push_back(b.create<CaseStatement>(CaseSelectorList{b.Expr(1)}, b.Block()));
+            cases.push_back(b.create<CaseStatement>(CaseSelectorList{b.Expr(1_i)}, b.Block()));
             b.create<SwitchStatement>(nullptr, cases);
         },
         "internal compiler error");
@@ -87,7 +89,7 @@
             b1.create<SwitchStatement>(b2.Expr(true), CaseStatementList{
                                                           b1.create<CaseStatement>(
                                                               CaseSelectorList{
-                                                                  b1.Expr(1),
+                                                                  b1.Expr(1_i),
                                                               },
                                                               b1.Block()),
                                                       });
@@ -103,7 +105,7 @@
             b1.create<SwitchStatement>(b1.Expr(true), CaseStatementList{
                                                           b2.create<CaseStatement>(
                                                               CaseSelectorList{
-                                                                  b2.Expr(1),
+                                                                  b2.Expr(1_i),
                                                               },
                                                               b2.Block()),
                                                       });
diff --git a/src/tint/ast/traverse_expressions_test.cc b/src/tint/ast/traverse_expressions_test.cc
index 403ec9b..622a7ff 100644
--- a/src/tint/ast/traverse_expressions_test.cc
+++ b/src/tint/ast/traverse_expressions_test.cc
@@ -16,15 +16,17 @@
 #include "gmock/gmock.h"
 #include "src/tint/ast/test_helper.h"
 
+using ::testing::ElementsAre;
+
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::ast {
 namespace {
 
-using ::testing::ElementsAre;
-
 using TraverseExpressionsTest = TestHelper;
 
 TEST_F(TraverseExpressionsTest, DescendIndexAccessor) {
-    std::vector<const ast::Expression*> e = {Expr(1), Expr(1), Expr(1), Expr(1)};
+    std::vector<const ast::Expression*> e = {Expr(1_i), Expr(1_i), Expr(1_i), Expr(1_i)};
     std::vector<const ast::Expression*> i = {IndexAccessor(e[0], e[1]), IndexAccessor(e[2], e[3])};
     auto* root = IndexAccessor(i[0], i[1]);
     {
@@ -48,7 +50,7 @@
 }
 
 TEST_F(TraverseExpressionsTest, DescendBinaryExpression) {
-    std::vector<const ast::Expression*> e = {Expr(1), Expr(1), Expr(1), Expr(1)};
+    std::vector<const ast::Expression*> e = {Expr(1_i), Expr(1_i), Expr(1_i), Expr(1_i)};
     std::vector<const ast::Expression*> i = {Add(e[0], e[1]), Sub(e[2], e[3])};
     auto* root = Mul(i[0], i[1]);
     {
@@ -72,7 +74,7 @@
 }
 
 TEST_F(TraverseExpressionsTest, DescendBitcastExpression) {
-    auto* e = Expr(1);
+    auto* e = Expr(1_i);
     auto* b0 = Bitcast<i32>(e);
     auto* b1 = Bitcast<i32>(b0);
     auto* b2 = Bitcast<i32>(b1);
@@ -98,7 +100,7 @@
 }
 
 TEST_F(TraverseExpressionsTest, DescendCallExpression) {
-    std::vector<const ast::Expression*> e = {Expr(1), Expr(1), Expr(1), Expr(1)};
+    std::vector<const ast::Expression*> e = {Expr(1_i), Expr(1_i), Expr(1_i), Expr(1_i)};
     std::vector<const ast::Expression*> c = {Call("a", e[0], e[1]), Call("b", e[2], e[3])};
     auto* root = Call("c", c[0], c[1]);
     {
@@ -124,7 +126,7 @@
 // TODO(crbug.com/tint/1257): Test ignores member accessor 'member' field.
 // Replace with the test below when fixed.
 TEST_F(TraverseExpressionsTest, DescendMemberIndexExpression) {
-    auto* e = Expr(1);
+    auto* e = Expr(1_i);
     auto* m = MemberAccessor(e, Expr("a"));
     auto* root = MemberAccessor(m, Expr("b"));
     {
@@ -149,7 +151,7 @@
 
 // TODO(crbug.com/tint/1257): The correct test for DescendMemberIndexExpression.
 TEST_F(TraverseExpressionsTest, DISABLED_DescendMemberIndexExpression) {
-    auto* e = Expr(1);
+    auto* e = Expr(1_i);
     std::vector<const ast::IdentifierExpression*> i = {Expr("a"), Expr("b")};
     auto* m = MemberAccessor(e, i[0]);
     auto* root = MemberAccessor(m, i[1]);
@@ -174,7 +176,7 @@
 }
 
 TEST_F(TraverseExpressionsTest, DescendUnaryExpression) {
-    auto* e = Expr(1);
+    auto* e = Expr(1_i);
     auto* u0 = AddressOf(e);
     auto* u1 = Deref(u0);
     auto* u2 = AddressOf(u1);
@@ -200,7 +202,7 @@
 }
 
 TEST_F(TraverseExpressionsTest, Skip) {
-    std::vector<const ast::Expression*> e = {Expr(1), Expr(1), Expr(1), Expr(1)};
+    std::vector<const ast::Expression*> e = {Expr(1_i), Expr(1_i), Expr(1_i), Expr(1_i)};
     std::vector<const ast::Expression*> i = {IndexAccessor(e[0], e[1]), IndexAccessor(e[2], e[3])};
     auto* root = IndexAccessor(i[0], i[1]);
     std::vector<const ast::Expression*> order;
@@ -213,7 +215,7 @@
 }
 
 TEST_F(TraverseExpressionsTest, Stop) {
-    std::vector<const ast::Expression*> e = {Expr(1), Expr(1), Expr(1), Expr(1)};
+    std::vector<const ast::Expression*> e = {Expr(1_i), Expr(1_i), Expr(1_i), Expr(1_i)};
     std::vector<const ast::Expression*> i = {IndexAccessor(e[0], e[1]), IndexAccessor(e[2], e[3])};
     auto* root = IndexAccessor(i[0], i[1]);
     std::vector<const ast::Expression*> order;
diff --git a/src/tint/ast/workgroup_attribute_test.cc b/src/tint/ast/workgroup_attribute_test.cc
index cc9765a..d4fb6c7 100644
--- a/src/tint/ast/workgroup_attribute_test.cc
+++ b/src/tint/ast/workgroup_attribute_test.cc
@@ -17,13 +17,15 @@
 #include "src/tint/ast/stage_attribute.h"
 #include "src/tint/ast/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::ast {
 namespace {
 
 using WorkgroupAttributeTest = TestHelper;
 
 TEST_F(WorkgroupAttributeTest, Creation_1param) {
-    auto* d = WorkgroupSize(2);
+    auto* d = WorkgroupSize(2_i);
     auto values = d->Values();
 
     ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
@@ -33,7 +35,7 @@
     EXPECT_EQ(values[2], nullptr);
 }
 TEST_F(WorkgroupAttributeTest, Creation_2param) {
-    auto* d = WorkgroupSize(2, 4);
+    auto* d = WorkgroupSize(2_i, 4_i);
     auto values = d->Values();
 
     ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
@@ -46,7 +48,7 @@
 }
 
 TEST_F(WorkgroupAttributeTest, Creation_3param) {
-    auto* d = WorkgroupSize(2, 4, 6);
+    auto* d = WorkgroupSize(2_i, 4_i, 6_i);
     auto values = d->Values();
 
     ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
@@ -60,7 +62,7 @@
 }
 
 TEST_F(WorkgroupAttributeTest, Creation_WithIdentifier) {
-    auto* d = WorkgroupSize(2, 4, "depth");
+    auto* d = WorkgroupSize(2_i, 4_i, "depth");
     auto values = d->Values();
 
     ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
diff --git a/src/tint/inspector/inspector_test.cc b/src/tint/inspector/inspector_test.cc
index a3bc8fa..8e3662b 100644
--- a/src/tint/inspector/inspector_test.cc
+++ b/src/tint/inspector/inspector_test.cc
@@ -28,6 +28,8 @@
 #include "src/tint/sem/variable.h"
 #include "tint/tint.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::inspector {
 namespace {
 
@@ -175,7 +177,7 @@
                                  });
 
     MakeEmptyBodyFunction(
-        "bar", ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+        "bar", ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     // TODO(dsinclair): Update to run the namer transform when available.
 
@@ -197,7 +199,8 @@
     MakeEmptyBodyFunction("func", {});
 
     MakeCallerBodyFunction(
-        "foo", {"func"}, ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+        "foo", {"func"},
+        ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     MakeCallerBodyFunction("bar", {"func"},
                            ast::AttributeList{
@@ -221,8 +224,8 @@
 }
 
 TEST_F(InspectorGetEntryPointTest, DefaultWorkgroupSize) {
-    MakeEmptyBodyFunction(
-        "foo", ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(8, 2, 1)});
+    MakeEmptyBodyFunction("foo", ast::AttributeList{Stage(ast::PipelineStage::kCompute),
+                                                    WorkgroupSize(8_i, 2_i, 1_i)});
 
     Inspector& inspector = Build();
 
@@ -238,7 +241,8 @@
 }
 
 TEST_F(InspectorGetEntryPointTest, NonDefaultWorkgroupSize) {
-    MakeEmptyBodyFunction("foo", {Stage(ast::PipelineStage::kCompute), WorkgroupSize(8, 2, 1)});
+    MakeEmptyBodyFunction("foo",
+                          {Stage(ast::PipelineStage::kCompute), WorkgroupSize(8_i, 2_i, 1_i)});
 
     Inspector& inspector = Build();
 
@@ -529,7 +533,7 @@
 
 TEST_F(InspectorGetEntryPointTest, OverridableConstantUnreferenced) {
     AddOverridableConstantWithoutID("foo", ty.f32(), nullptr);
-    MakeEmptyBodyFunction("ep_func", {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+    MakeEmptyBodyFunction("ep_func", {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     Inspector& inspector = Build();
 
@@ -542,7 +546,7 @@
 TEST_F(InspectorGetEntryPointTest, OverridableConstantReferencedByEntryPoint) {
     AddOverridableConstantWithoutID("foo", ty.f32(), nullptr);
     MakePlainGlobalReferenceBodyFunction("ep_func", "foo", ty.f32(),
-                                         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+                                         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     Inspector& inspector = Build();
 
@@ -557,7 +561,7 @@
     AddOverridableConstantWithoutID("foo", ty.f32(), nullptr);
     MakePlainGlobalReferenceBodyFunction("callee_func", "foo", ty.f32(), {});
     MakeCallerBodyFunction("ep_func", {"callee_func"},
-                           {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+                           {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     Inspector& inspector = Build();
 
@@ -573,7 +577,7 @@
     AddOverridableConstantWithID("bar", 2, ty.f32(), nullptr);
     MakePlainGlobalReferenceBodyFunction("callee_func", "foo", ty.f32(), {});
     MakeCallerBodyFunction("ep_func", {"callee_func"},
-                           {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+                           {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     Inspector& inspector = Build();
 
@@ -597,7 +601,7 @@
     MakePlainGlobalReferenceBodyFunction("i32_func", "i32_var", ty.i32(), {});
 
     MakeCallerBodyFunction("ep_func", {"bool_func", "float_func", "u32_func", "i32_func"},
-                           {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+                           {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     Inspector& inspector = Build();
 
@@ -621,7 +625,7 @@
 TEST_F(InspectorGetEntryPointTest, OverridableConstantInitialized) {
     AddOverridableConstantWithoutID("foo", ty.f32(), Expr(0.0f));
     MakePlainGlobalReferenceBodyFunction("ep_func", "foo", ty.f32(),
-                                         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+                                         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     Inspector& inspector = Build();
 
@@ -636,7 +640,7 @@
 TEST_F(InspectorGetEntryPointTest, OverridableConstantUninitialized) {
     AddOverridableConstantWithoutID("foo", ty.f32(), nullptr);
     MakePlainGlobalReferenceBodyFunction("ep_func", "foo", ty.f32(),
-                                         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+                                         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     Inspector& inspector = Build();
 
@@ -657,7 +661,7 @@
     MakePlainGlobalReferenceBodyFunction("id_func", "foo_id", ty.f32(), {});
 
     MakeCallerBodyFunction("ep_func", {"no_id_func", "id_func"},
-                           {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+                           {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     Inspector& inspector = Build();
 
@@ -848,7 +852,7 @@
 TEST_F(InspectorGetEntryPointTest, NumWorkgroupsSimpleReferenced) {
     auto* in_var = Param("in_var", ty.vec3<u32>(), {Builtin(ast::Builtin::kNumWorkgroups)});
     Func("ep_func", {in_var}, ty.void_(), {Return()},
-         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)}, {});
+         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)}, {});
 
     Inspector& inspector = Build();
 
@@ -866,7 +870,7 @@
     auto* in_var = Param("in_var", ty.type_name("in_struct"), {});
 
     Func("ep_func", {in_var}, ty.void_(), {Return()},
-         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)}, {});
+         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)}, {});
 
     Inspector& inspector = Build();
 
@@ -970,7 +974,7 @@
 
 TEST_F(InspectorGetConstantIDsTest, U32) {
     AddOverridableConstantWithID("foo", 1, ty.u32(), nullptr);
-    AddOverridableConstantWithID("bar", 20, ty.u32(), Expr(42u));
+    AddOverridableConstantWithID("bar", 20, ty.u32(), Expr(42_u));
 
     Inspector& inspector = Build();
 
@@ -987,8 +991,8 @@
 
 TEST_F(InspectorGetConstantIDsTest, I32) {
     AddOverridableConstantWithID("foo", 1, ty.i32(), nullptr);
-    AddOverridableConstantWithID("bar", 20, ty.i32(), Expr(-42));
-    AddOverridableConstantWithID("baz", 300, ty.i32(), Expr(42));
+    AddOverridableConstantWithID("bar", 20, ty.i32(), Expr(i32(-42)));
+    AddOverridableConstantWithID("baz", 300, ty.i32(), Expr(42_i));
 
     Inspector& inspector = Build();
 
@@ -1071,7 +1075,7 @@
 
 TEST_F(InspectorGetStorageSizeTest, Empty) {
     MakeEmptyBodyFunction(
-        "ep_func", ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+        "ep_func", ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
     Inspector& inspector = Build();
     EXPECT_EQ(0u, inspector.GetStorageSize("ep_func"));
 }
@@ -1086,7 +1090,7 @@
              Decl(Let("sb", nullptr, Expr("sb_var"))),
              Decl(Let("rosb", nullptr, Expr("rosb_var"))),
          },
-         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     Inspector& inspector = Build();
 
@@ -1109,7 +1113,7 @@
     MakeCallerBodyFunction("ep_func", {"ub_func", "sb_func", "rosb_func"},
                            ast::AttributeList{
                                Stage(ast::PipelineStage::kCompute),
-                               WorkgroupSize(1),
+                               WorkgroupSize(1_i),
                            });
 
     Inspector& inspector = Build();
@@ -1123,7 +1127,7 @@
          {
              Decl(Let("ub", nullptr, Expr("ub_var"))),
          },
-         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     Inspector& inspector = Build();
 
@@ -1137,7 +1141,7 @@
          {
              Decl(Let("ub", nullptr, Expr("ub_var"))),
          },
-         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     Inspector& inspector = Build();
 
@@ -1441,7 +1445,7 @@
     // with elem stride of 16, and that is 16-byte aligned within the struct)
     auto* foo_struct_type = Structure(
         "foo_type", {Member("0i32", ty.i32()),
-                     Member("b", ty.array(ty.u32(), 4, /*stride*/ 16), {MemberAlign(16)})});
+                     Member("b", ty.array(ty.u32(), 4_u, /*stride*/ 16), {MemberAlign(16)})});
 
     AddUniformBuffer("foo_ub", ty.Of(foo_struct_type), 0, 0);
 
@@ -2741,7 +2745,7 @@
 
 TEST_F(InspectorGetWorkgroupStorageSizeTest, Empty) {
     MakeEmptyBodyFunction(
-        "ep_func", ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+        "ep_func", ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
     Inspector& inspector = Build();
     EXPECT_EQ(0u, inspector.GetWorkgroupStorageSize("ep_func"));
 }
@@ -2753,7 +2757,7 @@
     MakeCallerBodyFunction("ep_func", {"f32_func"},
                            ast::AttributeList{
                                Stage(ast::PipelineStage::kCompute),
-                               WorkgroupSize(1),
+                               WorkgroupSize(1_i),
                            });
 
     Inspector& inspector = Build();
@@ -2764,7 +2768,7 @@
     // This struct should occupy 68 bytes. 4 from the i32 field, and another 64
     // from the 4-element array with 16-byte stride.
     auto* wg_struct_type =
-        MakeStructType("WgStruct", {ty.i32(), ty.array(ty.i32(), 4, /*stride=*/16)});
+        MakeStructType("WgStruct", {ty.i32(), ty.array(ty.i32(), 4_u, /*stride=*/16)});
     AddWorkgroupStorage("wg_struct_var", ty.Of(wg_struct_type));
     MakeStructVariableReferenceBodyFunction("wg_struct_func", "wg_struct_var", {{0, ty.i32()}});
 
@@ -2775,7 +2779,7 @@
     MakeCallerBodyFunction("ep_func", {"wg_struct_func", "f32_func"},
                            ast::AttributeList{
                                Stage(ast::PipelineStage::kCompute),
-                               WorkgroupSize(1),
+                               WorkgroupSize(1_i),
                            });
 
     Inspector& inspector = Build();
@@ -2791,7 +2795,7 @@
     MakeCallerBodyFunction("ep_func", {"wg_func"},
                            ast::AttributeList{
                                Stage(ast::PipelineStage::kCompute),
-                               WorkgroupSize(1),
+                               WorkgroupSize(1_i),
                            });
 
     Inspector& inspector = Build();
@@ -2812,7 +2816,7 @@
     MakeCallerBodyFunction("ep_func", {"wg_struct_func"},
                            ast::AttributeList{
                                Stage(ast::PipelineStage::kCompute),
-                               WorkgroupSize(1),
+                               WorkgroupSize(1_i),
                            });
 
     Inspector& inspector = Build();
diff --git a/src/tint/number.h b/src/tint/number.h
new file mode 100644
index 0000000..165a00a
--- /dev/null
+++ b/src/tint/number.h
@@ -0,0 +1,86 @@
+// Copyright 2021 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SRC_TINT_NUMBER_H_
+#define SRC_TINT_NUMBER_H_
+
+#include <stdint.h>
+
+namespace tint {
+
+/// Number wraps a integer or floating point number, enforcing explicit casting.
+template <typename T>
+struct Number {
+    /// Constructor. The value is zero-initialized.
+    Number() = default;
+
+    /// Constructor.
+    /// @param v the value to initialize this Number to
+    explicit Number(T v) : value(v) {}
+
+    /// Conversion operator
+    /// @returns the value as T
+    operator T() const { return value; }
+
+    /// Assignment operator
+    /// @param v the new value
+    /// @returns this Number so calls can be chained
+    Number& operator=(T v) {
+        value = v;
+        return *this;
+    }
+
+    /// The number value
+    T value = {};
+};
+
+template <typename A, typename B>
+bool operator==(Number<A> a, Number<B> b) {
+    return a.value == b.value;
+}
+
+template <typename A, typename B>
+bool operator==(Number<A> a, B b) {
+    return a.value == b;
+}
+
+template <typename A, typename B>
+bool operator==(A a, Number<B> b) {
+    return a == b.value;
+}
+
+/// `i32` is a type alias to `Number<int32_t>`.
+using i32 = Number<int32_t>;
+/// `u32` is a type alias to `Number<uint32_t>`.
+using u32 = Number<uint32_t>;
+/// `f32` is a type alias to `float`
+using f32 = float;
+
+}  // namespace tint
+
+namespace tint::number_suffixes {
+
+/// Literal suffix for i32 literals
+inline i32 operator"" _i(unsigned long long int value) {  // NOLINT
+    return i32(static_cast<int32_t>(value));
+}
+
+/// Literal suffix for u32 literals
+inline u32 operator"" _u(unsigned long long int value) {  // NOLINT
+    return u32(static_cast<uint32_t>(value));
+}
+
+}  // namespace tint::number_suffixes
+
+#endif  // SRC_TINT_NUMBER_H_
diff --git a/src/tint/program_builder.cc b/src/tint/program_builder.cc
index 199bdb8..cd05fd4 100644
--- a/src/tint/program_builder.cc
+++ b/src/tint/program_builder.cc
@@ -22,6 +22,8 @@
 #include "src/tint/sem/expression.h"
 #include "src/tint/sem/variable.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint {
 
 ProgramBuilder::VarOptionals::~VarOptionals() = default;
@@ -126,7 +128,7 @@
 const ast::Function* ProgramBuilder::WrapInFunction(const ast::StatementList stmts) {
     return Func(
         "test_function", {}, ty.void_(), std::move(stmts),
-        {create<ast::StageAttribute>(ast::PipelineStage::kCompute), WorkgroupSize(1, 1, 1)});
+        {create<ast::StageAttribute>(ast::PipelineStage::kCompute), WorkgroupSize(1_i, 1_i, 1_i)});
 }
 
 }  // namespace tint
diff --git a/src/tint/program_builder.h b/src/tint/program_builder.h
index c1499b8..088efc9 100644
--- a/src/tint/program_builder.h
+++ b/src/tint/program_builder.h
@@ -75,6 +75,7 @@
 #include "src/tint/ast/vector.h"
 #include "src/tint/ast/void.h"
 #include "src/tint/ast/workgroup_attribute.h"
+#include "src/tint/number.h"
 #include "src/tint/program.h"
 #include "src/tint/program_id.h"
 #include "src/tint/sem/array.h"
@@ -153,23 +154,6 @@
     /// SemNodeAllocator is an alias to BlockAllocator<sem::Node>
     using SemNodeAllocator = utils::BlockAllocator<sem::Node>;
 
-    /// `i32` is a type alias to `int`.
-    /// Useful for passing to template methods such as `vec2<i32>()` to imitate
-    /// WGSL syntax.
-    /// Note: this is intentionally not aliased to uint32_t as we want integer
-    /// literals passed to the builder to match WGSL's integer literal types.
-    using i32 = decltype(1);
-    /// `u32` is a type alias to `unsigned int`.
-    /// Useful for passing to template methods such as `vec2<u32>()` to imitate
-    /// WGSL syntax.
-    /// Note: this is intentionally not aliased to uint32_t as we want integer
-    /// literals passed to the builder to match WGSL's integer literal types.
-    using u32 = decltype(1u);
-    /// `f32` is a type alias to `float`
-    /// Useful for passing to template methods such as `vec2<f32>()` to imitate
-    /// WGSL syntax.
-    using f32 = float;
-
     /// Constructor
     ProgramBuilder();
 
@@ -672,7 +656,7 @@
         /// @return the tint AST type for an array of size `N` of type `T`
         template <typename T, int N>
         const ast::Array* array() const {
-            return array(Of<T>(), builder->Expr(N));
+            return array(Of<T>(), builder->Expr(tint::u32(N)));
         }
 
         /// @param stride the array stride
@@ -686,7 +670,7 @@
         /// @return the tint AST type for an array of size `N` of type `T`
         template <typename T, int N>
         const ast::Array* array(uint32_t stride) const {
-            return array(Of<T>(), builder->Expr(N), stride);
+            return array(Of<T>(), builder->Expr(tint::u32(N)), stride);
         }
 
         /// Creates a type name
@@ -1015,28 +999,28 @@
 
     /// @param source the source information
     /// @param value the integer value
-    /// @return a Scalar constructor for the given value
+    /// @return a 'i'-suffixed IntLiteralExpression for the given value
     const ast::IntLiteralExpression* Expr(const Source& source, i32 value) {
         return create<ast::IntLiteralExpression>(source, value,
-                                                 ast::IntLiteralExpression::Suffix::kNone);
+                                                 ast::IntLiteralExpression::Suffix::kI);
     }
 
     /// @param value the integer value
-    /// @return a Scalar constructor for the given value
+    /// @return a 'i'-suffixed IntLiteralExpression for the given value
     const ast::IntLiteralExpression* Expr(i32 value) {
-        return create<ast::IntLiteralExpression>(value, ast::IntLiteralExpression::Suffix::kNone);
+        return create<ast::IntLiteralExpression>(value, ast::IntLiteralExpression::Suffix::kI);
     }
 
     /// @param source the source information
     /// @param value the unsigned int value
-    /// @return a Scalar constructor for the given value
+    /// @return a 'u'-suffixed IntLiteralExpression for the given value
     const ast::IntLiteralExpression* Expr(const Source& source, u32 value) {
         return create<ast::IntLiteralExpression>(source, value,
                                                  ast::IntLiteralExpression::Suffix::kU);
     }
 
     /// @param value the unsigned int value
-    /// @return a Scalar constructor for the given value
+    /// @return a 'u'-suffixed IntLiteralExpression for the given value
     const ast::IntLiteralExpression* Expr(u32 value) {
         return create<ast::IntLiteralExpression>(value, ast::IntLiteralExpression::Suffix::kU);
     }
@@ -2643,15 +2627,15 @@
 //! @cond Doxygen_Suppress
 // Various template specializations for ProgramBuilder::TypesBuilder::CToAST.
 template <>
-struct ProgramBuilder::TypesBuilder::CToAST<ProgramBuilder::i32> {
+struct ProgramBuilder::TypesBuilder::CToAST<i32> {
     static const ast::Type* get(const ProgramBuilder::TypesBuilder* t) { return t->i32(); }
 };
 template <>
-struct ProgramBuilder::TypesBuilder::CToAST<ProgramBuilder::u32> {
+struct ProgramBuilder::TypesBuilder::CToAST<u32> {
     static const ast::Type* get(const ProgramBuilder::TypesBuilder* t) { return t->u32(); }
 };
 template <>
-struct ProgramBuilder::TypesBuilder::CToAST<ProgramBuilder::f32> {
+struct ProgramBuilder::TypesBuilder::CToAST<f32> {
     static const ast::Type* get(const ProgramBuilder::TypesBuilder* t) { return t->f32(); }
 };
 template <>
diff --git a/src/tint/reader/spirv/function.cc b/src/tint/reader/spirv/function.cc
index f2fa3a4..b416a6a 100644
--- a/src/tint/reader/spirv/function.cc
+++ b/src/tint/reader/spirv/function.cc
@@ -1026,11 +1026,11 @@
                 Switch(
                     current_type,
                     [&](const Matrix* matrix_type) {
-                        store_dest = builder_.IndexAccessor(store_dest, builder_.Expr(index));
+                        store_dest = builder_.IndexAccessor(store_dest, builder_.Expr(i32(index)));
                         current_type = ty_.Vector(matrix_type->type, matrix_type->rows);
                     },
                     [&](const Array* array_type) {
-                        store_dest = builder_.IndexAccessor(store_dest, builder_.Expr(index));
+                        store_dest = builder_.IndexAccessor(store_dest, builder_.Expr(i32(index)));
                         current_type = array_type->type->UnwrapAlias();
                     },
                     [&](const Struct* struct_type) {
@@ -1169,11 +1169,13 @@
                 Switch(
                     current_type,
                     [&](const Matrix* matrix_type) {
-                        load_source = builder_.IndexAccessor(load_source, builder_.Expr(index));
+                        load_source =
+                            builder_.IndexAccessor(load_source, builder_.Expr(i32(index)));
                         current_type = ty_.Vector(matrix_type->type, matrix_type->rows);
                     },
                     [&](const Array* array_type) {
-                        load_source = builder_.IndexAccessor(load_source, builder_.Expr(index));
+                        load_source =
+                            builder_.IndexAccessor(load_source, builder_.Expr(i32(index)));
                         current_type = array_type->type->UnwrapAlias();
                     },
                     [&](const Struct* struct_type) {
@@ -1356,9 +1358,9 @@
     if (ep_info_->stage == ast::PipelineStage::kCompute) {
         auto& size = ep_info_->workgroup_size;
         if (size.x != 0 && size.y != 0 && size.z != 0) {
-            const ast::Expression* x = builder_.Expr(static_cast<int>(size.x));
-            const ast::Expression* y = size.y ? builder_.Expr(static_cast<int>(size.y)) : nullptr;
-            const ast::Expression* z = size.z ? builder_.Expr(static_cast<int>(size.z)) : nullptr;
+            const ast::Expression* x = builder_.Expr(i32(size.x));
+            const ast::Expression* y = size.y ? builder_.Expr(i32(size.y)) : nullptr;
+            const ast::Expression* z = size.z ? builder_.Expr(i32(size.z)) : nullptr;
             fn_attrs.emplace_back(create<ast::WorkgroupAttribute>(Source{}, x, y, z));
         }
     }
diff --git a/src/tint/reader/spirv/parser_impl_function_decl_test.cc b/src/tint/reader/spirv/parser_impl_function_decl_test.cc
index b7aede3..c821c85 100644
--- a/src/tint/reader/spirv/parser_impl_function_decl_test.cc
+++ b/src/tint/reader/spirv/parser_impl_function_decl_test.cc
@@ -162,7 +162,7 @@
     Program program = p->program();
     const auto program_ast = test::ToString(program);
     EXPECT_THAT(program_ast, HasSubstr(R"(
-@stage(compute) @workgroup_size(1, 1, 1)
+@stage(compute) @workgroup_size(1i, 1i, 1i)
 fn main() {
 )"));
 }
@@ -208,7 +208,7 @@
     Program program = p->program();
     const auto program_ast = test::ToString(program);
     EXPECT_THAT(program_ast, HasSubstr(R"(
-@stage(compute) @workgroup_size(2, 4, 8)
+@stage(compute) @workgroup_size(2i, 4i, 8i)
 fn comp_main() {
 )")) << program_ast;
 }
@@ -233,7 +233,7 @@
     Program program = p->program();
     const auto program_ast = test::ToString(program);
     EXPECT_THAT(program_ast, HasSubstr(R"(
-@stage(compute) @workgroup_size(3, 5, 7)
+@stage(compute) @workgroup_size(3i, 5i, 7i)
 fn comp_main() {
 )")) << program_ast;
 }
@@ -262,7 +262,7 @@
     Program program = p->program();
     const auto program_ast = test::ToString(program);
     EXPECT_THAT(program_ast, HasSubstr(R"(
-@stage(compute) @workgroup_size(3, 5, 7)
+@stage(compute) @workgroup_size(3i, 5i, 7i)
 fn comp_main() {
 )")) << program_ast;
 }
@@ -290,7 +290,7 @@
     Program program = p->program();
     const auto program_ast = test::ToString(program);
     EXPECT_THAT(program_ast, HasSubstr(R"(
-@stage(compute) @workgroup_size(3, 5, 7)
+@stage(compute) @workgroup_size(3i, 5i, 7i)
 fn comp_main() {
 )")) << program_ast;
 }
@@ -323,7 +323,7 @@
     Program program = p->program();
     const auto program_ast = test::ToString(program);
     EXPECT_THAT(program_ast, HasSubstr(R"(
-@stage(compute) @workgroup_size(3, 5, 7)
+@stage(compute) @workgroup_size(3i, 5i, 7i)
 fn comp_main() {
 )")) << program_ast;
 }
diff --git a/src/tint/reader/spirv/parser_impl_module_var_test.cc b/src/tint/reader/spirv/parser_impl_module_var_test.cc
index 5066659..8ef704e 100644
--- a/src/tint/reader/spirv/parser_impl_module_var_test.cc
+++ b/src/tint/reader/spirv/parser_impl_module_var_test.cc
@@ -1991,7 +1991,7 @@
 
 @stage(fragment)
 fn main(@builtin(sample_mask) x_1_param : u32) {
-  x_1[0] = x_1_param;
+  x_1[0i] = x_1_param;
   main_1();
 }
 )";
@@ -2023,7 +2023,7 @@
 
 @stage(fragment)
 fn main(@builtin(sample_mask) x_1_param : u32) {
-  x_1[0] = x_1_param;
+  x_1[0i] = x_1_param;
   main_1();
 }
 )";
@@ -2055,7 +2055,7 @@
 
 @stage(fragment)
 fn main(@builtin(sample_mask) x_1_param : u32) {
-  x_1[0] = x_1_param;
+  x_1[0i] = x_1_param;
   main_1();
 }
 )";
@@ -2086,7 +2086,7 @@
 
 @stage(fragment)
 fn main(@builtin(sample_mask) x_1_param : u32) {
-  x_1[0] = bitcast<i32>(x_1_param);
+  x_1[0i] = bitcast<i32>(x_1_param);
   main_1();
 }
 )";
@@ -2118,7 +2118,7 @@
 
 @stage(fragment)
 fn main(@builtin(sample_mask) x_1_param : u32) {
-  x_1[0] = bitcast<i32>(x_1_param);
+  x_1[0i] = bitcast<i32>(x_1_param);
   main_1();
 }
 )";
@@ -2150,7 +2150,7 @@
 
 @stage(fragment)
 fn main(@builtin(sample_mask) x_1_param : u32) {
-  x_1[0] = bitcast<i32>(x_1_param);
+  x_1[0i] = bitcast<i32>(x_1_param);
   main_1();
 }
 )";
@@ -2205,7 +2205,7 @@
 @stage(fragment)
 fn main() -> main_out {
   main_1();
-  return main_out(x_1[0]);
+  return main_out(x_1[0i]);
 }
 )";
     EXPECT_EQ(module_str, expected);
@@ -2242,7 +2242,7 @@
 @stage(fragment)
 fn main() -> main_out {
   main_1();
-  return main_out(x_1[0]);
+  return main_out(x_1[0i]);
 }
 )";
     EXPECT_EQ(module_str, expected);
@@ -2279,7 +2279,7 @@
 @stage(fragment)
 fn main() -> main_out {
   main_1();
-  return main_out(x_1[0]);
+  return main_out(x_1[0i]);
 }
 )";
     EXPECT_EQ(module_str, expected);
@@ -2315,7 +2315,7 @@
 @stage(fragment)
 fn main() -> main_out {
   main_1();
-  return main_out(bitcast<u32>(x_1[0]));
+  return main_out(bitcast<u32>(x_1[0i]));
 }
 )";
     EXPECT_EQ(module_str, expected);
@@ -2352,7 +2352,7 @@
 @stage(fragment)
 fn main() -> main_out {
   main_1();
-  return main_out(bitcast<u32>(x_1[0]));
+  return main_out(bitcast<u32>(x_1[0i]));
 }
 )";
     EXPECT_EQ(module_str, expected);
@@ -2389,7 +2389,7 @@
 @stage(fragment)
 fn main() -> main_out {
   main_1();
-  return main_out(bitcast<u32>(x_1[0]));
+  return main_out(bitcast<u32>(x_1[0i]));
 }
 )";
     EXPECT_EQ(module_str, expected);
@@ -2427,7 +2427,7 @@
 
 @stage(fragment)
 fn main(@builtin(sample_mask) x_1_param : u32) {
-  x_1[0] = x_1_param;
+  x_1[0i] = x_1_param;
   main_1();
 }
 )";
@@ -2472,7 +2472,7 @@
 @stage(fragment)
 fn main() -> main_out {
   main_1();
-  return main_out(x_1[0]);
+  return main_out(x_1[0i]);
 }
 )";
     EXPECT_EQ(module_str, expected);
@@ -3149,7 +3149,7 @@
   return;
 }
 
-@stage(compute) @workgroup_size(1, 1, 1)
+@stage(compute) @workgroup_size(1i, 1i, 1i)
 fn main(@builtin(${wgsl_builtin}) x_1_param : ${unsigned_wgsl_type}) {
   x_1 = ${assignment_value};
   main_1();
@@ -3195,7 +3195,7 @@
   return;
 }
 
-@stage(compute) @workgroup_size(1, 1, 1)
+@stage(compute) @workgroup_size(1i, 1i, 1i)
 fn main(@builtin(${wgsl_builtin}) x_1_param : ${unsigned_wgsl_type}) {
   x_1 = ${assignment_value};
   main_1();
@@ -3240,7 +3240,7 @@
   return;
 }
 
-@stage(compute) @workgroup_size(1, 1, 1)
+@stage(compute) @workgroup_size(1i, 1i, 1i)
 fn main(@builtin(${wgsl_builtin}) x_1_param : ${unsigned_wgsl_type}) {
   x_1 = ${assignment_value};
   main_1();
@@ -3694,7 +3694,7 @@
 
 @stage(fragment)
 fn main(@builtin(sample_mask) x_1_param : u32) {
-  x_1[0] = x_1_param;
+  x_1[0i] = x_1_param;
   main_1();
 }
 )";
@@ -3732,7 +3732,7 @@
 
 @stage(fragment)
 fn main(@builtin(sample_mask) x_1_param : u32) {
-  x_1[0] = bitcast<i32>(x_1_param);
+  x_1[0i] = bitcast<i32>(x_1_param);
   main_1();
 }
 )";
@@ -3779,7 +3779,7 @@
 @stage(fragment)
 fn main() -> main_out {
   main_1();
-  return main_out(x_1[0]);
+  return main_out(x_1[0i]);
 }
 )";
     EXPECT_EQ(got, expected) << got;
@@ -3825,7 +3825,7 @@
 @stage(fragment)
 fn main() -> main_out {
   main_1();
-  return main_out(bitcast<u32>(x_1[0]));
+  return main_out(bitcast<u32>(x_1[0i]));
 }
 )";
     EXPECT_EQ(got, expected) << got;
@@ -4027,9 +4027,9 @@
 
 @stage(vertex)
 fn main(@location(4) x_1_param : f32, @location(5) x_1_param_1 : f32, @location(6) x_1_param_2 : f32) -> main_out {
-  x_1[0] = x_1_param;
-  x_1[1] = x_1_param_1;
-  x_1[2] = x_1_param_2;
+  x_1[0i] = x_1_param;
+  x_1[1i] = x_1_param_1;
+  x_1[2i] = x_1_param_2;
   main_1();
   return main_out(x_2);
 }
@@ -4085,8 +4085,8 @@
 
 @stage(vertex)
 fn main(@location(9) x_1_param : vec4<f32>, @location(10) x_1_param_1 : vec4<f32>) -> main_out {
-  x_1[0] = x_1_param;
-  x_1[1] = x_1_param_1;
+  x_1[0i] = x_1_param;
+  x_1[1i] = x_1_param_1;
   main_1();
   return main_out(x_2);
 }
@@ -4211,10 +4211,10 @@
 
 @stage(vertex)
 fn main(@location(7) x_1_param : vec4<f32>, @location(8) x_1_param_1 : vec4<f32>, @location(9) x_1_param_2 : vec4<f32>, @location(10) x_1_param_3 : vec4<f32>) -> main_out {
-  x_1[0][0] = x_1_param;
-  x_1[0][1] = x_1_param_1;
-  x_1[1][0] = x_1_param_2;
-  x_1[1][1] = x_1_param_3;
+  x_1[0i][0i] = x_1_param;
+  x_1[0i][1i] = x_1_param_1;
+  x_1[1i][0i] = x_1_param_2;
+  x_1[1i][1i] = x_1_param_3;
   main_1();
   return main_out(x_2);
 }
@@ -4279,7 +4279,7 @@
 @stage(vertex)
 fn main() -> main_out {
   main_1();
-  return main_out(x_1[0], x_1[1], x_1[2], x_2);
+  return main_out(x_1[0i], x_1[1i], x_1[2i], x_2);
 }
 )";
     EXPECT_EQ(got, expected) << got;
@@ -4338,7 +4338,7 @@
 @stage(vertex)
 fn main() -> main_out {
   main_1();
-  return main_out(x_1[0], x_1[1], x_2);
+  return main_out(x_1[0i], x_1[1i], x_2);
 }
 )";
     EXPECT_EQ(got, expected) << got;
@@ -4705,8 +4705,8 @@
 
 @stage(fragment)
 fn main(@location(1) @interpolate(flat) x_1_param : f32, @location(2) @interpolate(flat) x_1_param_1 : f32, @location(5) @interpolate(flat) x_2_param : f32, @location(6) @interpolate(flat) x_2_param_1 : f32) {
-  x_1[0] = x_1_param;
-  x_1[1] = x_1_param_1;
+  x_1[0i] = x_1_param;
+  x_1[1i] = x_1_param_1;
   x_2.field0 = x_2_param;
   x_2.field1 = x_2_param_1;
   main_1();
diff --git a/src/tint/reader/spirv/parser_type.cc b/src/tint/reader/spirv/parser_type.cc
index 4747efc..3332cd4 100644
--- a/src/tint/reader/spirv/parser_type.cc
+++ b/src/tint/reader/spirv/parser_type.cc
@@ -196,7 +196,7 @@
 
 const ast::Type* Array::Build(ProgramBuilder& b) const {
     if (size > 0) {
-        return b.ty.array(type->Build(b), size, stride);
+        return b.ty.array(type->Build(b), u32(size), stride);
     } else {
         return b.ty.array(type->Build(b), nullptr, stride);
     }
diff --git a/src/tint/resolver/array_accessor_test.cc b/src/tint/resolver/array_accessor_test.cc
index d227ce4..1704699 100644
--- a/src/tint/resolver/array_accessor_test.cc
+++ b/src/tint/resolver/array_accessor_test.cc
@@ -18,6 +18,8 @@
 #include "src/tint/resolver/resolver_test_helper.h"
 #include "src/tint/sem/reference.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -43,8 +45,8 @@
 
 TEST_F(ResolverIndexAccessorTest, Matrix_BothDimensions_Dynamic_Ref) {
     Global("my_var", ty.mat4x4<f32>(), ast::StorageClass::kPrivate);
-    auto* idx = Var("idx", ty.u32(), Expr(3u));
-    auto* idy = Var("idy", ty.u32(), Expr(2u));
+    auto* idx = Var("idx", ty.u32(), Expr(3_u));
+    auto* idy = Var("idy", ty.u32(), Expr(2_u));
     auto* acc = IndexAccessor(IndexAccessor("my_var", idx), idy);
     WrapInFunction(Decl(idx), Decl(idy), acc);
 
@@ -63,7 +65,7 @@
 
 TEST_F(ResolverIndexAccessorTest, Matrix_XDimension_Dynamic) {
     GlobalConst("my_var", ty.mat4x4<f32>(), Construct(ty.mat4x4<f32>()));
-    auto* idx = Var("idx", ty.u32(), Expr(3u));
+    auto* idx = Var("idx", ty.u32(), Expr(3_u));
     auto* acc = IndexAccessor("my_var", Expr(Source{{12, 34}}, idx));
     WrapInFunction(Decl(idx), acc);
 
@@ -73,8 +75,8 @@
 
 TEST_F(ResolverIndexAccessorTest, Matrix_BothDimension_Dynamic) {
     GlobalConst("my_var", ty.mat4x4<f32>(), Construct(ty.mat4x4<f32>()));
-    auto* idx = Var("idy", ty.u32(), Expr(2u));
-    auto* acc = IndexAccessor(IndexAccessor("my_var", Expr(Source{{12, 34}}, idx)), 1);
+    auto* idx = Var("idy", ty.u32(), Expr(2_u));
+    auto* acc = IndexAccessor(IndexAccessor("my_var", Expr(Source{{12, 34}}, idx)), 1_i);
     WrapInFunction(Decl(idx), acc);
 
     EXPECT_TRUE(r()->Resolve());
@@ -84,7 +86,7 @@
 TEST_F(ResolverIndexAccessorTest, Matrix) {
     Global("my_var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
 
-    auto* acc = IndexAccessor("my_var", 2);
+    auto* acc = IndexAccessor("my_var", 2_i);
     WrapInFunction(acc);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -100,7 +102,7 @@
 TEST_F(ResolverIndexAccessorTest, Matrix_BothDimensions) {
     Global("my_var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
 
-    auto* acc = IndexAccessor(IndexAccessor("my_var", 2), 1);
+    auto* acc = IndexAccessor(IndexAccessor("my_var", 2_i), 1_i);
     WrapInFunction(acc);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -123,7 +125,7 @@
 
 TEST_F(ResolverIndexAccessorTest, Vector_Dynamic_Ref) {
     Global("my_var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
-    auto* idx = Var("idx", ty.i32(), Expr(2));
+    auto* idx = Var("idx", ty.i32(), Expr(2_i));
     auto* acc = IndexAccessor("my_var", idx);
     WrapInFunction(Decl(idx), acc);
 
@@ -132,7 +134,7 @@
 
 TEST_F(ResolverIndexAccessorTest, Vector_Dynamic) {
     GlobalConst("my_var", ty.vec3<f32>(), Construct(ty.vec3<f32>()));
-    auto* idx = Var("idx", ty.i32(), Expr(2));
+    auto* idx = Var("idx", ty.i32(), Expr(2_i));
     auto* acc = IndexAccessor("my_var", Expr(Source{{12, 34}}, idx));
     WrapInFunction(Decl(idx), acc);
 
@@ -142,7 +144,7 @@
 TEST_F(ResolverIndexAccessorTest, Vector) {
     Global("my_var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
 
-    auto* acc = IndexAccessor("my_var", 2);
+    auto* acc = IndexAccessor("my_var", 2_i);
     WrapInFunction(acc);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -155,7 +157,7 @@
 }
 
 TEST_F(ResolverIndexAccessorTest, Array) {
-    auto* idx = Expr(2);
+    auto* idx = Expr(2_i);
     Global("my_var", ty.array<f32, 3>(), ast::StorageClass::kPrivate);
 
     auto* acc = IndexAccessor("my_var", idx);
@@ -175,7 +177,7 @@
 
     Global("my_var", ty.Of(aary), ast::StorageClass::kPrivate);
 
-    auto* acc = IndexAccessor("my_var", 2);
+    auto* acc = IndexAccessor("my_var", 2_i);
     WrapInFunction(acc);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -190,7 +192,7 @@
 TEST_F(ResolverIndexAccessorTest, Array_Constant) {
     GlobalConst("my_var", ty.array<f32, 3>(), array<f32, 3>());
 
-    auto* acc = IndexAccessor("my_var", 2);
+    auto* acc = IndexAccessor("my_var", 2_i);
     WrapInFunction(acc);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -235,9 +237,9 @@
 
 TEST_F(ResolverIndexAccessorTest, Array_Literal_I32) {
     // let a : array<f32, 3>;
-    // var f : f32 = a[2];
+    // var f : f32 = a[2i];
     auto* a = Let("a", ty.array<f32, 3>(), array<f32, 3>());
-    auto* f = Var("a_2", ty.f32(), IndexAccessor("a", 2));
+    auto* f = Var("a_2", ty.f32(), IndexAccessor("a", 2_i));
     Func("my_func", ast::VariableList{}, ty.void_(),
          {
              Decl(a),
diff --git a/src/tint/resolver/assignment_validation_test.cc b/src/tint/resolver/assignment_validation_test.cc
index 36ea1ed..f12f804 100644
--- a/src/tint/resolver/assignment_validation_test.cc
+++ b/src/tint/resolver/assignment_validation_test.cc
@@ -18,6 +18,8 @@
 #include "src/tint/resolver/resolver_test_helper.h"
 #include "src/tint/sem/storage_texture.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -34,7 +36,7 @@
                create<ast::GroupAttribute>(0),
            });
 
-    WrapInFunction(Assign(Source{{56, 78}}, MemberAccessor("a", "m"), 1));
+    WrapInFunction(Assign(Source{{56, 78}}, MemberAccessor("a", "m"), 1_i));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -44,11 +46,11 @@
 
 TEST_F(ResolverAssignmentValidationTest, AssignIncompatibleTypes) {
     // {
-    //  var a : i32 = 2;
+    //  var a : i32 = 2i;
     //  a = 2.3;
     // }
 
-    auto* var = Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2));
+    auto* var = Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2_i));
 
     auto* assign = Assign(Source{{12, 34}}, "a", 2.3f);
     WrapInFunction(var, assign);
@@ -61,14 +63,14 @@
 TEST_F(ResolverAssignmentValidationTest, AssignArraysWithDifferentSizeExpressions_Pass) {
     // let len = 4u;
     // {
-    //   var a : array<f32, 4>;
+    //   var a : array<f32, 4u>;
     //   var b : array<f32, len>;
     //   a = b;
     // }
 
-    GlobalConst("len", nullptr, Expr(4u));
+    GlobalConst("len", nullptr, Expr(4_u));
 
-    auto* a = Var("a", ty.array(ty.f32(), 4));
+    auto* a = Var("a", ty.array(ty.f32(), 4_u));
     auto* b = Var("b", ty.array(ty.f32(), "len"));
 
     auto* assign = Assign(Source{{12, 34}}, "a", "b");
@@ -80,14 +82,14 @@
 TEST_F(ResolverAssignmentValidationTest, AssignArraysWithDifferentSizeExpressions_Fail) {
     // let len = 5u;
     // {
-    //   var a : array<f32, 4>;
+    //   var a : array<f32, 4u>;
     //   var b : array<f32, len>;
     //   a = b;
     // }
 
-    GlobalConst("len", nullptr, Expr(5u));
+    GlobalConst("len", nullptr, Expr(5_u));
 
-    auto* a = Var("a", ty.array(ty.f32(), 4));
+    auto* a = Var("a", ty.array(ty.f32(), 4_u));
     auto* b = Var("b", ty.array(ty.f32(), "len"));
 
     auto* assign = Assign(Source{{12, 34}}, "a", "b");
@@ -100,22 +102,22 @@
 
 TEST_F(ResolverAssignmentValidationTest, AssignCompatibleTypesInBlockStatement_Pass) {
     // {
-    //  var a : i32 = 2;
-    //  a = 2
+    //  var a : i32 = 2i;
+    //  a = 2i
     // }
-    auto* var = Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2));
-    WrapInFunction(var, Assign("a", 2));
+    auto* var = Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2_i));
+    WrapInFunction(var, Assign("a", 2_i));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverAssignmentValidationTest, AssignIncompatibleTypesInBlockStatement_Fail) {
     // {
-    //  var a : i32 = 2;
+    //  var a : i32 = 2i;
     //  a = 2.3;
     // }
 
-    auto* var = Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2));
+    auto* var = Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2_i));
     WrapInFunction(var, Assign(Source{{12, 34}}, "a", 2.3f));
 
     ASSERT_FALSE(r()->Resolve());
@@ -126,12 +128,12 @@
 TEST_F(ResolverAssignmentValidationTest, AssignIncompatibleTypesInNestedBlockStatement_Fail) {
     // {
     //  {
-    //   var a : i32 = 2;
+    //   var a : i32 = 2i;
     //   a = 2.3;
     //  }
     // }
 
-    auto* var = Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2));
+    auto* var = Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2_i));
     auto* inner_block = Block(Decl(var), Assign(Source{{12, 34}}, "a", 2.3f));
     auto* outer_block = Block(inner_block);
     WrapInFunction(outer_block);
@@ -142,42 +144,42 @@
 }
 
 TEST_F(ResolverAssignmentValidationTest, AssignToScalar_Fail) {
-    // var my_var : i32 = 2;
+    // var my_var : i32 = 2i;
     // 1 = my_var;
 
-    auto* var = Var("my_var", ty.i32(), ast::StorageClass::kNone, Expr(2));
-    WrapInFunction(var, Assign(Expr(Source{{12, 34}}, 1), "my_var"));
+    auto* var = Var("my_var", ty.i32(), ast::StorageClass::kNone, Expr(2_i));
+    WrapInFunction(var, Assign(Expr(Source{{12, 34}}, 1_i), "my_var"));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: cannot assign to value of type 'i32'");
 }
 
 TEST_F(ResolverAssignmentValidationTest, AssignCompatibleTypes_Pass) {
-    // var a : i32 = 2;
-    // a = 2
-    auto* var = Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2));
-    WrapInFunction(var, Assign(Source{{12, 34}}, "a", 2));
+    // var a : i32 = 2i;
+    // a = 2i
+    auto* var = Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2_i));
+    WrapInFunction(var, Assign(Source{{12, 34}}, "a", 2_i));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverAssignmentValidationTest, AssignCompatibleTypesThroughAlias_Pass) {
     // alias myint = i32;
-    // var a : myint = 2;
+    // var a : myint = 2i;
     // a = 2
     auto* myint = Alias("myint", ty.i32());
-    auto* var = Var("a", ty.Of(myint), ast::StorageClass::kNone, Expr(2));
-    WrapInFunction(var, Assign(Source{{12, 34}}, "a", 2));
+    auto* var = Var("a", ty.Of(myint), ast::StorageClass::kNone, Expr(2_i));
+    WrapInFunction(var, Assign(Source{{12, 34}}, "a", 2_i));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverAssignmentValidationTest, AssignCompatibleTypesInferRHSLoad_Pass) {
-    // var a : i32 = 2;
-    // var b : i32 = 3;
+    // var a : i32 = 2i;
+    // var b : i32 = 3i;
     // a = b;
-    auto* var_a = Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2));
-    auto* var_b = Var("b", ty.i32(), ast::StorageClass::kNone, Expr(3));
+    auto* var_a = Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2_i));
+    auto* var_b = Var("b", ty.i32(), ast::StorageClass::kNone, Expr(3_i));
     WrapInFunction(var_a, var_b, Assign(Source{{12, 34}}, "a", "b"));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -186,22 +188,22 @@
 TEST_F(ResolverAssignmentValidationTest, AssignThroughPointer_Pass) {
     // var a : i32;
     // let b : ptr<function,i32> = &a;
-    // *b = 2;
+    // *b = 2i;
     const auto func = ast::StorageClass::kFunction;
-    auto* var_a = Var("a", ty.i32(), func, Expr(2));
-    auto* var_b = Let("b", ty.pointer<int>(func), AddressOf(Expr("a")));
-    WrapInFunction(var_a, var_b, Assign(Source{{12, 34}}, Deref("b"), 2));
+    auto* var_a = Var("a", ty.i32(), func, Expr(2_i));
+    auto* var_b = Let("b", ty.pointer<i32>(func), AddressOf(Expr("a")));
+    WrapInFunction(var_a, var_b, Assign(Source{{12, 34}}, Deref("b"), 2_i));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverAssignmentValidationTest, AssignToConstant_Fail) {
     // {
-    //  let a : i32 = 2;
-    //  a = 2
+    //  let a : i32 = 2i;
+    //  a = 2i
     // }
-    auto* var = Let("a", ty.i32(), Expr(2));
-    WrapInFunction(var, Assign(Expr(Source{{12, 34}}, "a"), 2));
+    auto* var = Let("a", ty.i32(), Expr(2_i));
+    WrapInFunction(var, Assign(Expr(Source{{12, 34}}, "a"), 2_i));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: cannot assign to const\nnote: 'a' is declared here:");
@@ -324,7 +326,7 @@
     // @group(0) @binding(3) var<storage, read_write> s : S;
     // var<workgroup> wg : array<f32, 10>
     // fn f() {
-    //   _ = 1;
+    //   _ = 1i;
     //   _ = 2u;
     //   _ = 3.0;
     //   _ = vec2<bool>();
@@ -336,7 +338,7 @@
     //   _ = u;
     //   _ = u.i;
     //   _ = wg;
-    //   _ = wg[3];
+    //   _ = wg[3i];
     // }
     auto* S = Structure("S", {
                                  Member("i", ty.i32()),
@@ -349,9 +351,9 @@
     Global("s", ty.Of(S), ast::StorageClass::kStorage, GroupAndBinding(0, 3));
     Global("wg", ty.array<f32, 10>(), ast::StorageClass::kWorkgroup);
 
-    WrapInFunction(Assign(Phony(), 1),                                      //
-                   Assign(Phony(), 2),                                      //
-                   Assign(Phony(), 3),                                      //
+    WrapInFunction(Assign(Phony(), 1_i),                                    //
+                   Assign(Phony(), 2_u),                                    //
+                   Assign(Phony(), 3.f),                                    //
                    Assign(Phony(), vec2<bool>()),                           //
                    Assign(Phony(), "tex"),                                  //
                    Assign(Phony(), "smp"),                                  //
@@ -361,7 +363,7 @@
                    Assign(Phony(), "u"),                                    //
                    Assign(Phony(), MemberAccessor("u", "i")),               //
                    Assign(Phony(), "wg"),                                   //
-                   Assign(Phony(), IndexAccessor("wg", 3)));
+                   Assign(Phony(), IndexAccessor("wg", 3_i)));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
diff --git a/src/tint/resolver/atomics_validation_test.cc b/src/tint/resolver/atomics_validation_test.cc
index de8d0ac..78c1fb9 100644
--- a/src/tint/resolver/atomics_validation_test.cc
+++ b/src/tint/resolver/atomics_validation_test.cc
@@ -19,6 +19,8 @@
 
 #include "gmock/gmock.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -131,10 +133,10 @@
     // struct S{
     //   m: atomic<u32>;
     // };
-    // var<private> v: array<S, 5>;
+    // var<private> v: array<S, 5u>;
 
     auto* s = Structure("S", {Member("m", ty.atomic<u32>())});
-    Global(Source{{56, 78}}, "v", ty.array(ty.Of(s), 5), ast::StorageClass::kPrivate);
+    Global(Source{{56, 78}}, "v", ty.array(ty.Of(s), 5_u), ast::StorageClass::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -144,16 +146,16 @@
 }
 
 TEST_F(ResolverAtomicValidationTest, InvalidStorageClass_ArrayOfStructOfArray) {
-    // type AtomicArray = array<atomic<i32>, 5>;
+    // type AtomicArray = array<atomic<i32>, 5u>;
     // struct S{
     //   m: AtomicArray;
     // };
-    // var<private> v: array<S, 5>;
+    // var<private> v: array<S, 5u>;
 
     auto* atomic_array =
         Alias(Source{{12, 34}}, "AtomicArray", ty.atomic(Source{{12, 34}}, ty.i32()));
     auto* s = Structure("S", {Member("m", ty.Of(atomic_array))});
-    Global(Source{{56, 78}}, "v", ty.array(ty.Of(s), 5), ast::StorageClass::kPrivate);
+    Global(Source{{56, 78}}, "v", ty.array(ty.Of(s), 5_u), ast::StorageClass::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -163,14 +165,14 @@
 }
 
 TEST_F(ResolverAtomicValidationTest, InvalidStorageClass_Complex) {
-    // type AtomicArray = array<atomic<i32>, 5>;
+    // type AtomicArray = array<atomic<i32>, 5u>;
     // struct S6 { x: array<i32, 4>; };
     // struct S5 { x: S6;
     //             y: AtomicArray;
-    //             z: array<atomic<u32>, 8>; };
+    //             z: array<atomic<u32>, 8u>; };
     // struct S4 { x: S6;
     //             y: S5;
-    //             z: array<atomic<i32>, 4>; };
+    //             z: array<atomic<i32>, 4u>; };
     // struct S3 { x: S4; };
     // struct S2 { x: S3; };
     // struct S1 { x: S2; };
@@ -179,9 +181,9 @@
 
     auto* atomic_array =
         Alias(Source{{12, 34}}, "AtomicArray", ty.atomic(Source{{12, 34}}, ty.i32()));
-    auto* array_i32_4 = ty.array(ty.i32(), 4);
-    auto* array_atomic_u32_8 = ty.array(ty.atomic(ty.u32()), 8);
-    auto* array_atomic_i32_4 = ty.array(ty.atomic(ty.i32()), 4);
+    auto* array_i32_4 = ty.array(ty.i32(), 4_u);
+    auto* array_atomic_u32_8 = ty.array(ty.atomic(ty.u32()), 8_u);
+    auto* array_atomic_i32_4 = ty.array(ty.atomic(ty.i32()), 4_u);
 
     auto* s6 = Structure("S6", {Member("x", array_i32_4)});
     auto* s5 = Structure("S5", {Member("x", ty.Of(s6)),             //
@@ -263,13 +265,13 @@
 
 TEST_F(ResolverAtomicValidationTest, InvalidAccessMode_Complex) {
     // type AtomicArray = array<atomic<i32>, 5>;
-    // struct S6 { x: array<i32, 4>; };
+    // struct S6 { x: array<i32, 4u>; };
     // struct S5 { x: S6;
     //             y: AtomicArray;
-    //             z: array<atomic<u32>, 8>; };
+    //             z: array<atomic<u32>, 8u>; };
     // struct S4 { x: S6;
     //             y: S5;
-    //             z: array<atomic<i32>, 4>; };
+    //             z: array<atomic<i32>, 4u>; };
     // struct S3 { x: S4; };
     // struct S2 { x: S3; };
     // struct S1 { x: S2; };
@@ -278,9 +280,9 @@
 
     auto* atomic_array =
         Alias(Source{{12, 34}}, "AtomicArray", ty.atomic(Source{{12, 34}}, ty.i32()));
-    auto* array_i32_4 = ty.array(ty.i32(), 4);
-    auto* array_atomic_u32_8 = ty.array(ty.atomic(ty.u32()), 8);
-    auto* array_atomic_i32_4 = ty.array(ty.atomic(ty.i32()), 4);
+    auto* array_i32_4 = ty.array(ty.i32(), 4_u);
+    auto* array_atomic_u32_8 = ty.array(ty.atomic(ty.u32()), 8_u);
+    auto* array_atomic_i32_4 = ty.array(ty.atomic(ty.i32()), 4_u);
 
     auto* s6 = Structure("S6", {Member("x", array_i32_4)});
     auto* s5 = Structure("S5", {Member("x", ty.Of(s6)),             //
diff --git a/src/tint/resolver/attribute_validation_test.cc b/src/tint/resolver/attribute_validation_test.cc
index f9f5ea9..dbefb14 100644
--- a/src/tint/resolver/attribute_validation_test.cc
+++ b/src/tint/resolver/attribute_validation_test.cc
@@ -19,6 +19,8 @@
 
 #include "gmock/gmock.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 
 // Helpers and typedefs
@@ -44,9 +46,6 @@
 using alias2 = builder::alias2<T>;
 template <typename T>
 using alias3 = builder::alias3<T>;
-using f32 = builder::f32;
-using i32 = builder::i32;
-using u32 = builder::u32;
 
 namespace AttributeTests {
 namespace {
@@ -115,10 +114,10 @@
         case AttributeKind::kStride:
             return {builder.create<ast::StrideAttribute>(source, 4u)};
         case AttributeKind::kWorkgroup:
-            return {builder.create<ast::WorkgroupAttribute>(source, builder.Expr(1))};
+            return {builder.create<ast::WorkgroupAttribute>(source, builder.Expr(1_i))};
         case AttributeKind::kBindingAndGroup:
-            return {builder.create<ast::BindingAttribute>(source, 1u),
-                    builder.create<ast::GroupAttribute>(source, 1u)};
+            return {builder.create<ast::BindingAttribute>(source, 1_u),
+                    builder.create<ast::GroupAttribute>(source, 1_u)};
     }
     return {};
 }
@@ -198,7 +197,7 @@
     auto& params = GetParam();
     auto* p = Param("a", ty.vec4<f32>(), createAttributes(Source{{12, 34}}, *this, params.kind));
     Func("main", ast::VariableList{p}, ty.void_(), {},
-         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     if (params.should_pass) {
         EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -318,7 +317,7 @@
 TEST_P(ComputeShaderReturnTypeAttributeTest, IsValid) {
     auto& params = GetParam();
     Func("main", ast::VariableList{}, ty.vec4<f32>(), {Return(Construct(ty.vec4<f32>(), 1.f))},
-         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)},
+         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)},
          createAttributes(Source{{12, 34}}, *this, params.kind));
 
     if (params.should_pass) {
@@ -493,7 +492,7 @@
 }
 
 TEST_F(EntryPointReturnTypeAttributeTest, DuplicateInternalAttribute) {
-    Func("f", {}, ty.i32(), {Return(1)}, {Stage(ast::PipelineStage::kFragment)},
+    Func("f", {}, ty.i32(), {Return(1_i)}, {Stage(ast::PipelineStage::kFragment)},
          ast::AttributeList{
              Disable(ast::DisabledValidation::kBindingPointCollision),
              Disable(ast::DisabledValidation::kEntryPointParameter),
@@ -794,7 +793,7 @@
        << ", should_pass: " << params.should_pass;
     SCOPED_TRACE(ss.str());
 
-    auto* arr = ty.array(Source{{12, 34}}, el_ty, 4, params.stride);
+    auto* arr = ty.array(Source{{12, 34}}, el_ty, 4_u, params.stride);
 
     Global("myarray", arr, ast::StorageClass::kPrivate);
 
@@ -873,10 +872,10 @@
                              ParamsFor<mat4x4<f32>>((default_mat4x4.align - 1) * 7, false)));
 
 TEST_F(ArrayStrideTest, DuplicateAttribute) {
-    auto* arr = ty.array(Source{{12, 34}}, ty.i32(), 4,
+    auto* arr = ty.array(Source{{12, 34}}, ty.i32(), 4_u,
                          {
-                             create<ast::StrideAttribute>(Source{{12, 34}}, 4),
-                             create<ast::StrideAttribute>(Source{{56, 78}}, 4),
+                             create<ast::StrideAttribute>(Source{{12, 34}}, 4_i),
+                             create<ast::StrideAttribute>(Source{{56, 78}}, 4_i),
                          });
 
     Global("myarray", arr, ast::StorageClass::kPrivate);
@@ -968,9 +967,9 @@
     Func("F", {}, ty.void_(),
          {
              Decl(Var("a", ty.vec4<f32>(), ast::StorageClass::kNone,
-                      Call("textureLoad", "A", vec2<i32>(1, 2), 0))),
+                      Call("textureLoad", "A", vec2<i32>(1_i, 2_i), 0_i))),
              Decl(Var("b", ty.vec4<f32>(), ast::StorageClass::kNone,
-                      Call("textureLoad", "B", vec2<i32>(1, 2), 0))),
+                      Call("textureLoad", "B", vec2<i32>(1_i, 2_i), 0_i))),
          },
          {Stage(ast::PipelineStage::kFragment)});
 
@@ -998,13 +997,13 @@
     Func("F_A", {}, ty.void_(),
          {
              Decl(Var("a", ty.vec4<f32>(), ast::StorageClass::kNone,
-                      Call("textureLoad", "A", vec2<i32>(1, 2), 0))),
+                      Call("textureLoad", "A", vec2<i32>(1_i, 2_i), 0_i))),
          },
          {Stage(ast::PipelineStage::kFragment)});
     Func("F_B", {}, ty.void_(),
          {
              Decl(Var("b", ty.vec4<f32>(), ast::StorageClass::kNone,
-                      Call("textureLoad", "B", vec2<i32>(1, 2), 0))),
+                      Call("textureLoad", "B", vec2<i32>(1_i, 2_i), 0_i))),
          },
          {Stage(ast::PipelineStage::kFragment)});
 
@@ -1065,7 +1064,7 @@
 TEST_F(WorkgroupAttribute, ComputeShaderPass) {
     Func("main", {}, ty.void_(), {},
          {Stage(ast::PipelineStage::kCompute),
-          create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1))});
+          create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i))});
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -1080,7 +1079,8 @@
 }
 
 TEST_F(WorkgroupAttribute, NotAnEntryPoint) {
-    Func("main", {}, ty.void_(), {}, {create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1))});
+    Func("main", {}, ty.void_(), {},
+         {create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i))});
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -1091,7 +1091,7 @@
 TEST_F(WorkgroupAttribute, NotAComputeShader) {
     Func("main", {}, ty.void_(), {},
          {Stage(ast::PipelineStage::kFragment),
-          create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1))});
+          create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i))});
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -1103,8 +1103,8 @@
     Func(Source{{12, 34}}, "main", {}, ty.void_(), {},
          {
              Stage(ast::PipelineStage::kCompute),
-             WorkgroupSize(Source{{12, 34}}, 1, nullptr, nullptr),
-             WorkgroupSize(Source{{56, 78}}, 2, nullptr, nullptr),
+             WorkgroupSize(Source{{12, 34}}, 1_i, nullptr, nullptr),
+             WorkgroupSize(Source{{56, 78}}, 2_i, nullptr, nullptr),
          });
 
     EXPECT_FALSE(r()->Resolve());
diff --git a/src/tint/resolver/bitcast_validation_test.cc b/src/tint/resolver/bitcast_validation_test.cc
index f7799b5..78223fc 100644
--- a/src/tint/resolver/bitcast_validation_test.cc
+++ b/src/tint/resolver/bitcast_validation_test.cc
@@ -34,24 +34,24 @@
 };
 
 static constexpr Type kNumericScalars[] = {
-    Type::Create<builder::f32>(),
-    Type::Create<builder::i32>(),
-    Type::Create<builder::u32>(),
+    Type::Create<f32>(),
+    Type::Create<i32>(),
+    Type::Create<u32>(),
 };
 static constexpr Type kVec2NumericScalars[] = {
-    Type::Create<builder::vec2<builder::f32>>(),
-    Type::Create<builder::vec2<builder::i32>>(),
-    Type::Create<builder::vec2<builder::u32>>(),
+    Type::Create<builder::vec2<f32>>(),
+    Type::Create<builder::vec2<i32>>(),
+    Type::Create<builder::vec2<u32>>(),
 };
 static constexpr Type kVec3NumericScalars[] = {
-    Type::Create<builder::vec3<builder::f32>>(),
-    Type::Create<builder::vec3<builder::i32>>(),
-    Type::Create<builder::vec3<builder::u32>>(),
+    Type::Create<builder::vec3<f32>>(),
+    Type::Create<builder::vec3<i32>>(),
+    Type::Create<builder::vec3<u32>>(),
 };
 static constexpr Type kVec4NumericScalars[] = {
-    Type::Create<builder::vec4<builder::f32>>(),
-    Type::Create<builder::vec4<builder::i32>>(),
-    Type::Create<builder::vec4<builder::u32>>(),
+    Type::Create<builder::vec4<f32>>(),
+    Type::Create<builder::vec4<i32>>(),
+    Type::Create<builder::vec4<u32>>(),
 };
 static constexpr Type kInvalid[] = {
     // A non-exhaustive selection of uncastable types
@@ -59,16 +59,16 @@
     Type::Create<builder::vec2<bool>>(),
     Type::Create<builder::vec3<bool>>(),
     Type::Create<builder::vec4<bool>>(),
-    Type::Create<builder::array<2, builder::i32>>(),
-    Type::Create<builder::array<3, builder::u32>>(),
-    Type::Create<builder::array<4, builder::f32>>(),
+    Type::Create<builder::array<2, i32>>(),
+    Type::Create<builder::array<3, u32>>(),
+    Type::Create<builder::array<4, f32>>(),
     Type::Create<builder::array<5, bool>>(),
-    Type::Create<builder::mat2x2<builder::f32>>(),
-    Type::Create<builder::mat3x3<builder::f32>>(),
-    Type::Create<builder::mat4x4<builder::f32>>(),
-    Type::Create<builder::ptr<builder::i32>>(),
-    Type::Create<builder::ptr<builder::array<2, builder::i32>>>(),
-    Type::Create<builder::ptr<builder::mat2x2<builder::f32>>>(),
+    Type::Create<builder::mat2x2<f32>>(),
+    Type::Create<builder::mat3x3<f32>>(),
+    Type::Create<builder::mat4x4<f32>>(),
+    Type::Create<builder::ptr<i32>>(),
+    Type::Create<builder::ptr<builder::array<2, i32>>>(),
+    Type::Create<builder::ptr<builder::mat2x2<f32>>>(),
 };
 
 using ResolverBitcastValidationTest = ResolverTestWithParam<std::tuple<Type, Type>>;
diff --git a/src/tint/resolver/builtin_test.cc b/src/tint/resolver/builtin_test.cc
index 3b5a03b..94684ba 100644
--- a/src/tint/resolver/builtin_test.cc
+++ b/src/tint/resolver/builtin_test.cc
@@ -39,6 +39,8 @@
 using ::testing::ElementsAre;
 using ::testing::HasSubstr;
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -331,7 +333,7 @@
 }
 
 TEST_F(ResolverBuiltinTest, Select_Error_SelectorInt) {
-    auto* expr = Call("select", 1, 1, 1);
+    auto* expr = Call("select", 1_i, 1_i, 1_i);
     WrapInFunction(expr);
 
     EXPECT_FALSE(r()->Resolve());
@@ -456,8 +458,8 @@
     bool pack4 =
         param.builtin == BuiltinType::kPack4x8snorm || param.builtin == BuiltinType::kPack4x8unorm;
 
-    auto* call =
-        pack4 ? Call(param.name, vec4<i32>(1, 2, 3, 4)) : Call(param.name, vec2<i32>(1, 2));
+    auto* call = pack4 ? Call(param.name, vec4<i32>(1_i, 2_i, 3_i, 4_i))
+                       : Call(param.name, vec2<i32>(1_i, 2_i));
     WrapInFunction(call);
 
     EXPECT_FALSE(r()->Resolve());
@@ -507,7 +509,7 @@
     bool pack4 = param.builtin == BuiltinType::kUnpack4x8snorm ||
                  param.builtin == BuiltinType::kUnpack4x8unorm;
 
-    auto* call = Call(param.name, 1u);
+    auto* call = Call(param.name, 1_u);
     WrapInFunction(call);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -573,7 +575,7 @@
 TEST_P(ResolverBuiltinTest_SingleParam, Error_TooManyParams) {
     auto param = GetParam();
 
-    auto* call = Call(param.name, 1, 2, 3);
+    auto* call = Call(param.name, 1_i, 2_i, 3_i);
     WrapInFunction(call);
 
     EXPECT_FALSE(r()->Resolve());
@@ -630,7 +632,7 @@
 }
 
 TEST_F(ResolverBuiltinDataTest, ArrayLength_Error_ArraySized) {
-    Global("arr", ty.array<int, 4>(), ast::StorageClass::kPrivate);
+    Global("arr", ty.array<i32, 4>(), ast::StorageClass::kPrivate);
     auto* call = Call("arrayLength", AddressOf("arr"));
     WrapInFunction(call);
 
@@ -732,7 +734,7 @@
 
 TEST_F(ResolverBuiltinDataTest, Frexp_Error_FirstParamInt) {
     Global("v", ty.i32(), ast::StorageClass::kWorkgroup);
-    auto* call = Call("frexp", 1, AddressOf("v"));
+    auto* call = Call("frexp", 1_i, AddressOf("v"));
     WrapInFunction(call);
 
     EXPECT_FALSE(r()->Resolve());
@@ -763,7 +765,7 @@
 }
 
 TEST_F(ResolverBuiltinDataTest, Frexp_Error_SecondParamNotAPointer) {
-    auto* call = Call("frexp", 1.0f, 1);
+    auto* call = Call("frexp", 1.0f, 1_i);
     WrapInFunction(call);
 
     EXPECT_FALSE(r()->Resolve());
@@ -856,7 +858,7 @@
 
 TEST_F(ResolverBuiltinDataTest, Modf_Error_FirstParamInt) {
     Global("whole", ty.f32(), ast::StorageClass::kWorkgroup);
-    auto* call = Call("modf", 1, AddressOf("whole"));
+    auto* call = Call("modf", 1_i, AddressOf("whole"));
     WrapInFunction(call);
 
     EXPECT_FALSE(r()->Resolve());
@@ -945,7 +947,7 @@
 TEST_P(ResolverBuiltinTest_SingleParam_FloatOrInt, Sint_Scalar) {
     auto param = GetParam();
 
-    auto* call = Call(param.name, -1);
+    auto* call = Call(param.name, i32(-1));
     WrapInFunction(call);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -957,7 +959,7 @@
 TEST_P(ResolverBuiltinTest_SingleParam_FloatOrInt, Sint_Vector) {
     auto param = GetParam();
 
-    auto* call = Call(param.name, vec3<i32>(1, 1, 3));
+    auto* call = Call(param.name, vec3<i32>(1_i, 1_i, 3_i));
     WrapInFunction(call);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -970,7 +972,7 @@
 TEST_P(ResolverBuiltinTest_SingleParam_FloatOrInt, Uint_Scalar) {
     auto param = GetParam();
 
-    auto* call = Call(param.name, 1u);
+    auto* call = Call(param.name, 1_u);
     WrapInFunction(call);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -982,7 +984,7 @@
 TEST_P(ResolverBuiltinTest_SingleParam_FloatOrInt, Uint_Vector) {
     auto param = GetParam();
 
-    auto* call = Call(param.name, vec3<u32>(1u, 1u, 3u));
+    auto* call = Call(param.name, vec3<u32>(1_u, 1_u, 3_u));
     WrapInFunction(call);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1061,7 +1063,7 @@
 TEST_P(ResolverBuiltinTest_TwoParam, Error_NoTooManyParams) {
     auto param = GetParam();
 
-    auto* call = Call(param.name, 1, 2, 3);
+    auto* call = Call(param.name, 1_i, 2_i, 3_i);
     WrapInFunction(call);
 
     EXPECT_FALSE(r()->Resolve());
@@ -1152,7 +1154,7 @@
 }
 
 TEST_F(ResolverBuiltinTest, Cross_Error_Vec3Int) {
-    auto* call = Call("cross", vec3<i32>(1, 2, 3), vec3<i32>(1, 2, 3));
+    auto* call = Call("cross", vec3<i32>(1_i, 2_i, 3_i), vec3<i32>(1_i, 2_i, 3_i));
     WrapInFunction(call);
 
     EXPECT_FALSE(r()->Resolve());
@@ -1295,7 +1297,7 @@
 TEST_P(ResolverBuiltinTest_ThreeParam_FloatOrInt, Sint_Scalar) {
     auto param = GetParam();
 
-    auto* call = Call(param.name, 1, 1, 1);
+    auto* call = Call(param.name, 1_i, 1_i, 1_i);
     WrapInFunction(call);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1307,7 +1309,8 @@
 TEST_P(ResolverBuiltinTest_ThreeParam_FloatOrInt, Sint_Vector) {
     auto param = GetParam();
 
-    auto* call = Call(param.name, vec3<i32>(1, 1, 3), vec3<i32>(1, 1, 3), vec3<i32>(1, 1, 3));
+    auto* call = Call(param.name, vec3<i32>(1_i, 1_i, 3_i), vec3<i32>(1_i, 1_i, 3_i),
+                      vec3<i32>(1_i, 1_i, 3_i));
     WrapInFunction(call);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1320,7 +1323,7 @@
 TEST_P(ResolverBuiltinTest_ThreeParam_FloatOrInt, Uint_Scalar) {
     auto param = GetParam();
 
-    auto* call = Call(param.name, 1u, 1u, 1u);
+    auto* call = Call(param.name, 1_u, 1_u, 1_u);
     WrapInFunction(call);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1332,8 +1335,8 @@
 TEST_P(ResolverBuiltinTest_ThreeParam_FloatOrInt, Uint_Vector) {
     auto param = GetParam();
 
-    auto* call =
-        Call(param.name, vec3<u32>(1u, 1u, 3u), vec3<u32>(1u, 1u, 3u), vec3<u32>(1u, 1u, 3u));
+    auto* call = Call(param.name, vec3<u32>(1_u, 1_u, 3_u), vec3<u32>(1_u, 1_u, 3_u),
+                      vec3<u32>(1_u, 1_u, 3_u));
     WrapInFunction(call);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1369,7 +1372,7 @@
 TEST_P(ResolverBuiltinTest_Int_SingleParam, Scalar) {
     auto param = GetParam();
 
-    auto* call = Call(param.name, 1);
+    auto* call = Call(param.name, 1_i);
     WrapInFunction(call);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1381,7 +1384,7 @@
 TEST_P(ResolverBuiltinTest_Int_SingleParam, Vector) {
     auto param = GetParam();
 
-    auto* call = Call(param.name, vec3<i32>(1, 1, 3));
+    auto* call = Call(param.name, vec3<i32>(1_i, 1_i, 3_i));
     WrapInFunction(call);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1416,7 +1419,7 @@
 TEST_P(ResolverBuiltinTest_FloatOrInt_TwoParam, Scalar_Signed) {
     auto param = GetParam();
 
-    auto* call = Call(param.name, 1, 1);
+    auto* call = Call(param.name, 1_i, 1_i);
     WrapInFunction(call);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1428,7 +1431,7 @@
 TEST_P(ResolverBuiltinTest_FloatOrInt_TwoParam, Scalar_Unsigned) {
     auto param = GetParam();
 
-    auto* call = Call(param.name, 1u, 1u);
+    auto* call = Call(param.name, 1_u, 1_u);
     WrapInFunction(call);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1452,7 +1455,7 @@
 TEST_P(ResolverBuiltinTest_FloatOrInt_TwoParam, Vector_Signed) {
     auto param = GetParam();
 
-    auto* call = Call(param.name, vec3<i32>(1, 1, 3), vec3<i32>(1, 1, 3));
+    auto* call = Call(param.name, vec3<i32>(1_i, 1_i, 3_i), vec3<i32>(1_i, 1_i, 3_i));
     WrapInFunction(call);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1465,7 +1468,7 @@
 TEST_P(ResolverBuiltinTest_FloatOrInt_TwoParam, Vector_Unsigned) {
     auto param = GetParam();
 
-    auto* call = Call(param.name, vec3<u32>(1u, 1u, 3u), vec3<u32>(1u, 1u, 3u));
+    auto* call = Call(param.name, vec3<u32>(1_u, 1_u, 3_u), vec3<u32>(1_u, 1_u, 3_u));
     WrapInFunction(call);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
diff --git a/src/tint/resolver/builtin_validation_test.cc b/src/tint/resolver/builtin_validation_test.cc
index f0bd8de..98e29fa 100644
--- a/src/tint/resolver/builtin_validation_test.cc
+++ b/src/tint/resolver/builtin_validation_test.cc
@@ -15,6 +15,8 @@
 #include "src/tint/ast/builtin_texture_helper_test.h"
 #include "src/tint/resolver/resolver_test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -37,7 +39,7 @@
     auto* dpdx =
         create<ast::CallExpression>(Source{{3, 4}}, Expr("dpdx"), ast::ExpressionList{Expr(1.0f)});
     Func(Source{{1, 2}}, "func", ast::VariableList{}, ty.void_(), {CallStmt(dpdx)},
-         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "3:4 error: built-in cannot be used by compute pipeline stage");
@@ -58,7 +60,7 @@
     Func(Source{{5, 6}}, "f2", {}, ty.void_(), {CallStmt(Call("f1"))});
 
     Func(Source{{7, 8}}, "main", {}, ty.void_(), {CallStmt(Call("f2"))},
-         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -78,7 +80,7 @@
 }
 
 TEST_F(ResolverBuiltinValidationTest, BuiltinRedeclaredAsGlobalLet) {
-    GlobalConst(Source{{12, 34}}, "mix", ty.i32(), Expr(1));
+    GlobalConst(Source{{12, 34}}, "mix", ty.i32(), Expr(1_i));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -86,7 +88,7 @@
 }
 
 TEST_F(ResolverBuiltinValidationTest, BuiltinRedeclaredAsGlobalVar) {
-    Global(Source{{12, 34}}, "mix", ty.i32(), Expr(1), ast::StorageClass::kPrivate);
+    Global(Source{{12, 34}}, "mix", ty.i32(), Expr(1_i), ast::StorageClass::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -115,9 +117,6 @@
 using ValidTextureOverload = ast::builtin::test::ValidTextureOverload;
 using TextureKind = ast::builtin::test::TextureKind;
 using TextureDataType = ast::builtin::test::TextureDataType;
-using u32 = ProgramBuilder::u32;
-using i32 = ProgramBuilder::i32;
-using f32 = ProgramBuilder::f32;
 
 static std::vector<TextureOverloadCase> TextureCases(
     std::unordered_set<ValidTextureOverload> overloads) {
@@ -160,17 +159,18 @@
     const ast::Expression* operator()(Source src, ProgramBuilder& b) {
         switch (kind) {
             case Kind::kScalar:
-                return b.Expr(src, values[0]);
+                return b.Expr(src, i32(values[0]));
             case Kind::kVec2:
-                return b.Construct(src, b.ty.vec2<i32>(), values[0], values[1]);
+                return b.Construct(src, b.ty.vec2<i32>(), i32(values[0]), i32(values[1]));
             case Kind::kVec3:
-                return b.Construct(src, b.ty.vec3<i32>(), values[0], values[1], values[2]);
+                return b.Construct(src, b.ty.vec3<i32>(), i32(values[0]), i32(values[1]),
+                                   i32(values[2]));
             case Kind::kVec3_Scalar_Vec2:
-                return b.Construct(src, b.ty.vec3<i32>(), values[0],
-                                   b.vec2<i32>(values[1], values[2]));
+                return b.Construct(src, b.ty.vec3<i32>(), i32(values[0]),
+                                   b.vec2<i32>(i32(values[1]), i32(values[2])));
             case Kind::kVec3_Vec2_Scalar:
-                return b.Construct(src, b.ty.vec3<i32>(), b.vec2<i32>(values[0], values[1]),
-                                   values[2]);
+                return b.Construct(src, b.ty.vec3<i32>(),
+                                   b.vec2<i32>(i32(values[0]), i32(values[1])), i32(values[2]));
             case Kind::kEmptyVec2:
                 return b.Construct(src, b.ty.vec2<i32>());
             case Kind::kEmptyVec3:
diff --git a/src/tint/resolver/builtins_validation_test.cc b/src/tint/resolver/builtins_validation_test.cc
index 804ccb4..87835d6 100644
--- a/src/tint/resolver/builtins_validation_test.cc
+++ b/src/tint/resolver/builtins_validation_test.cc
@@ -15,6 +15,8 @@
 #include "src/tint/ast/call_statement.h"
 #include "src/tint/resolver/resolver_test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -26,9 +28,6 @@
 using vec3 = builder::vec3<T>;
 template <typename T>
 using vec4 = builder::vec4<T>;
-using f32 = builder::f32;
-using i32 = builder::i32;
-using u32 = builder::u32;
 
 class ResolverBuiltinsValidationTest : public resolver::TestHelper, public testing::Test {};
 namespace StageTest {
@@ -106,7 +105,7 @@
             break;
         case ast::PipelineStage::kCompute:
             Func("main", {input}, ty.void_(), {},
-                 ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+                 ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
             break;
         default:
             break;
@@ -243,7 +242,7 @@
 TEST_F(ResolverBuiltinsValidationTest, SampleMaskNotU32_ReturnType_Fail) {
     // @stage(fragment)
     // fn main() -> @builtin(sample_mask) i32 { return 1; }
-    Func("main", {}, ty.i32(), {Return(1)}, {Stage(ast::PipelineStage::kFragment)},
+    Func("main", {}, ty.i32(), {Return(1_i)}, {Stage(ast::PipelineStage::kFragment)},
          {Builtin(Source{{12, 34}}, ast::Builtin::kSampleMask)});
 
     EXPECT_FALSE(r()->Resolve());
@@ -414,7 +413,7 @@
 
     Func("main", ast::VariableList{li_id, li_index, gi, wi, nwgs}, ty.void_(), {},
          ast::AttributeList{Stage(ast::PipelineStage::kCompute),
-                            WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2))});
+                            WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -424,7 +423,7 @@
                      ast::AttributeList{Builtin(Source{{12, 34}}, ast::Builtin::kWorkgroupId)});
     Func("main", ast::VariableList{wi}, ty.void_(), {},
          ast::AttributeList{Stage(ast::PipelineStage::kCompute),
-                            WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2))});
+                            WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -437,7 +436,7 @@
                        ast::AttributeList{Builtin(Source{{12, 34}}, ast::Builtin::kNumWorkgroups)});
     Func("main", ast::VariableList{nwgs}, ty.void_(), {},
          ast::AttributeList{Stage(ast::PipelineStage::kCompute),
-                            WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2))});
+                            WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -451,7 +450,7 @@
               ast::AttributeList{Builtin(Source{{12, 34}}, ast::Builtin::kGlobalInvocationId)});
     Func("main", ast::VariableList{gi}, ty.void_(), {},
          ast::AttributeList{Stage(ast::PipelineStage::kCompute),
-                            WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2))});
+                            WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -465,7 +464,7 @@
               ast::AttributeList{Builtin(Source{{12, 34}}, ast::Builtin::kLocalInvocationIndex)});
     Func("main", ast::VariableList{li_index}, ty.void_(), {},
          ast::AttributeList{Stage(ast::PipelineStage::kCompute),
-                            WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2))});
+                            WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -479,7 +478,7 @@
               ast::AttributeList{Builtin(Source{{12, 34}}, ast::Builtin::kLocalInvocationId)});
     Func("main", ast::VariableList{li_id}, ty.void_(), {},
          ast::AttributeList{Stage(ast::PipelineStage::kCompute),
-                            WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2))});
+                            WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -791,7 +790,7 @@
 }
 
 TEST_F(ResolverBuiltinsValidationTest, Select_Integer_Scalar) {
-    auto* builtin = Call("select", Expr(1), Expr(1), Expr(true));
+    auto* builtin = Call("select", Expr(1_i), Expr(1_i), Expr(true));
     WrapInFunction(builtin);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -813,7 +812,8 @@
 }
 
 TEST_F(ResolverBuiltinsValidationTest, Select_Integer_Vec2) {
-    auto* builtin = Call("select", vec2<int>(1, 1), vec2<int>(1, 1), vec2<bool>(true, true));
+    auto* builtin =
+        Call("select", vec2<i32>(1_i, 1_i), vec2<i32>(1_i, 1_i), vec2<bool>(true, true));
     WrapInFunction(builtin);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -950,7 +950,7 @@
 
     ast::ExpressionList params;
     for (uint32_t i = 0; i < num_params; ++i) {
-        params.push_back(Construct<uint32_t>(1));
+        params.push_back(Construct<u32>(1_i));
     }
     auto* builtin = Call(name, params);
     WrapInFunction(builtin);
@@ -965,7 +965,7 @@
 
     ast::ExpressionList params;
     for (uint32_t i = 0; i < num_params; ++i) {
-        params.push_back(vec2<uint32_t>(1u, 1u));
+        params.push_back(vec2<u32>(1_u, 1_u));
     }
     auto* builtin = Call(name, params);
     WrapInFunction(builtin);
@@ -980,7 +980,7 @@
 
     ast::ExpressionList params;
     for (uint32_t i = 0; i < num_params; ++i) {
-        params.push_back(vec3<uint32_t>(1u, 1u, 1u));
+        params.push_back(vec3<u32>(1_u, 1_u, 1_u));
     }
     auto* builtin = Call(name, params);
     WrapInFunction(builtin);
@@ -995,7 +995,7 @@
 
     ast::ExpressionList params;
     for (uint32_t i = 0; i < num_params; ++i) {
-        params.push_back(vec4<uint32_t>(1u, 1u, 1u, 1u));
+        params.push_back(vec4<u32>(1_u, 1_u, 1_u, 1_u));
     }
     auto* builtin = Call(name, params);
     WrapInFunction(builtin);
@@ -1010,7 +1010,7 @@
 
     ast::ExpressionList params;
     for (uint32_t i = 0; i < num_params; ++i) {
-        params.push_back(Construct<int32_t>(1));
+        params.push_back(Construct<i32>(1_i));
     }
     auto* builtin = Call(name, params);
     WrapInFunction(builtin);
@@ -1025,7 +1025,7 @@
 
     ast::ExpressionList params;
     for (uint32_t i = 0; i < num_params; ++i) {
-        params.push_back(vec2<int32_t>(1, 1));
+        params.push_back(vec2<i32>(1_i, 1_i));
     }
     auto* builtin = Call(name, params);
     WrapInFunction(builtin);
@@ -1040,7 +1040,7 @@
 
     ast::ExpressionList params;
     for (uint32_t i = 0; i < num_params; ++i) {
-        params.push_back(vec3<int32_t>(1, 1, 1));
+        params.push_back(vec3<i32>(1_i, 1_i, 1_i));
     }
     auto* builtin = Call(name, params);
     WrapInFunction(builtin);
@@ -1055,7 +1055,7 @@
 
     ast::ExpressionList params;
     for (uint32_t i = 0; i < num_params; ++i) {
-        params.push_back(vec4<int32_t>(1, 1, 1, 1));
+        params.push_back(vec4<i32>(1_i, 1_i, 1_i, 1_i));
     }
     auto* builtin = Call(name, params);
     WrapInFunction(builtin);
diff --git a/src/tint/resolver/call_test.cc b/src/tint/resolver/call_test.cc
index 0b622f1..c8b9856 100644
--- a/src/tint/resolver/call_test.cc
+++ b/src/tint/resolver/call_test.cc
@@ -51,9 +51,6 @@
 using alias2 = builder::alias2<T>;
 template <typename T>
 using alias3 = builder::alias3<T>;
-using f32 = builder::f32;
-using i32 = builder::i32;
-using u32 = builder::u32;
 
 using ResolverCallTest = ResolverTest;
 
diff --git a/src/tint/resolver/call_validation_test.cc b/src/tint/resolver/call_validation_test.cc
index c470bf5..756ba5c 100644
--- a/src/tint/resolver/call_validation_test.cc
+++ b/src/tint/resolver/call_validation_test.cc
@@ -18,6 +18,8 @@
 #include "src/tint/ast/call_statement.h"
 #include "src/tint/resolver/resolver_test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -25,7 +27,7 @@
 
 TEST_F(ResolverCallValidationTest, TooFewArgs) {
     Func("foo", {Param(Sym(), ty.i32()), Param(Sym(), ty.f32())}, ty.void_(), {Return()});
-    auto* call = Call(Source{{12, 34}}, "foo", 1);
+    auto* call = Call(Source{{12, 34}}, "foo", 1_i);
     WrapInFunction(call);
 
     EXPECT_FALSE(r()->Resolve());
@@ -34,7 +36,7 @@
 
 TEST_F(ResolverCallValidationTest, TooManyArgs) {
     Func("foo", {Param(Sym(), ty.i32()), Param(Sym(), ty.f32())}, ty.void_(), {Return()});
-    auto* call = Call(Source{{12, 34}}, "foo", 1, 1.0f, 1.0f);
+    auto* call = Call(Source{{12, 34}}, "foo", 1_i, 1.0f, 1.0f);
     WrapInFunction(call);
 
     EXPECT_FALSE(r()->Resolve());
@@ -70,14 +72,14 @@
 TEST_F(ResolverCallValidationTest, PointerArgument_VariableIdentExpr) {
     // fn foo(p: ptr<function, i32>) {}
     // fn main() {
-    //   var z: i32 = 1;
+    //   var z: i32 = 1i;
     //   foo(&z);
     // }
     auto* param = Param("p", ty.pointer<i32>(ast::StorageClass::kFunction));
     Func("foo", {param}, ty.void_(), {});
     Func("main", {}, ty.void_(),
          {
-             Decl(Var("z", ty.i32(), Expr(1))),
+             Decl(Var("z", ty.i32(), Expr(1_i))),
              CallStmt(Call("foo", AddressOf(Source{{12, 34}}, Expr("z")))),
          });
 
@@ -87,14 +89,14 @@
 TEST_F(ResolverCallValidationTest, PointerArgument_ConstIdentExpr) {
     // fn foo(p: ptr<function, i32>) {}
     // fn main() {
-    //   let z: i32 = 1;
+    //   let z: i32 = 1i;
     //   foo(&z);
     // }
     auto* param = Param("p", ty.pointer<i32>(ast::StorageClass::kFunction));
     Func("foo", {param}, ty.void_(), {});
     Func("main", {}, ty.void_(),
          {
-             Decl(Let("z", ty.i32(), Expr(1))),
+             Decl(Let("z", ty.i32(), Expr(1_i))),
              CallStmt(Call("foo", AddressOf(Expr(Source{{12, 34}}, "z")))),
          });
 
@@ -171,7 +173,7 @@
          ast::StatementList{CallStmt(Call("foo", Expr("p")))});
     Func("main", ast::VariableList{}, ty.void_(),
          {
-             Decl(Var("v", ty.i32(), Expr(1))),
+             Decl(Var("v", ty.i32(), Expr(1_i))),
              CallStmt(Call("foo", AddressOf(Expr("v")))),
          },
          {
diff --git a/src/tint/resolver/compound_assignment_validation_test.cc b/src/tint/resolver/compound_assignment_validation_test.cc
index bf1ed07..a3f124d 100644
--- a/src/tint/resolver/compound_assignment_validation_test.cc
+++ b/src/tint/resolver/compound_assignment_validation_test.cc
@@ -18,6 +18,8 @@
 #include "src/tint/resolver/resolver_test_helper.h"
 #include "src/tint/sem/storage_texture.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -26,8 +28,8 @@
 TEST_F(ResolverCompoundAssignmentValidationTest, CompatibleTypes) {
     // var a : i32 = 2;
     // a += 2
-    auto* var = Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2));
-    WrapInFunction(var, CompoundAssign(Source{{12, 34}}, "a", 2, ast::BinaryOp::kAdd));
+    auto* var = Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2_i));
+    WrapInFunction(var, CompoundAssign(Source{{12, 34}}, "a", 2_i, ast::BinaryOp::kAdd));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -37,8 +39,8 @@
     // var a : myint = 2;
     // a += 2
     auto* myint = Alias("myint", ty.i32());
-    auto* var = Var("a", ty.Of(myint), ast::StorageClass::kNone, Expr(2));
-    WrapInFunction(var, CompoundAssign(Source{{12, 34}}, "a", 2, ast::BinaryOp::kAdd));
+    auto* var = Var("a", ty.Of(myint), ast::StorageClass::kNone, Expr(2_i));
+    WrapInFunction(var, CompoundAssign(Source{{12, 34}}, "a", 2_i, ast::BinaryOp::kAdd));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -48,10 +50,10 @@
     // let b : ptr<function,i32> = &a;
     // *b += 2;
     const auto func = ast::StorageClass::kFunction;
-    auto* var_a = Var("a", ty.i32(), func, Expr(2));
-    auto* var_b = Let("b", ty.pointer<int>(func), AddressOf(Expr("a")));
+    auto* var_a = Var("a", ty.i32(), func, Expr(2_i));
+    auto* var_b = Let("b", ty.pointer<i32>(func), AddressOf(Expr("a")));
     WrapInFunction(var_a, var_b,
-                   CompoundAssign(Source{{12, 34}}, Deref("b"), 2, ast::BinaryOp::kAdd));
+                   CompoundAssign(Source{{12, 34}}, Deref("b"), 2_i, ast::BinaryOp::kAdd));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -62,7 +64,7 @@
     //   a += 2.3;
     // }
 
-    auto* var = Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2));
+    auto* var = Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2_i));
 
     auto* assign = CompoundAssign(Source{{12, 34}}, "a", 2.3f, ast::BinaryOp::kAdd);
     WrapInFunction(var, assign);
@@ -217,9 +219,9 @@
 
 TEST_F(ResolverCompoundAssignmentValidationTest, Phony) {
     // {
-    //   _ += 1;
+    //   _ += 1i;
     // }
-    WrapInFunction(CompoundAssign(Source{{56, 78}}, Phony(), 1, ast::BinaryOp::kAdd));
+    WrapInFunction(CompoundAssign(Source{{56, 78}}, Phony(), 1_i, ast::BinaryOp::kAdd));
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "56:78 error: compound assignment operand types are invalid: void "
@@ -229,11 +231,11 @@
 TEST_F(ResolverCompoundAssignmentValidationTest, ReadOnlyBuffer) {
     // @group(0) @binding(0) var<storage,read> a : i32;
     // {
-    //   a += 1;
+    //   a += 1i;
     // }
     Global(Source{{12, 34}}, "a", ty.i32(), ast::StorageClass::kStorage, ast::Access::kRead,
            GroupAndBinding(0, 0));
-    WrapInFunction(CompoundAssign(Source{{56, 78}}, "a", 1, ast::BinaryOp::kAdd));
+    WrapInFunction(CompoundAssign(Source{{56, 78}}, "a", 1_i, ast::BinaryOp::kAdd));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -242,10 +244,10 @@
 }
 
 TEST_F(ResolverCompoundAssignmentValidationTest, LhsConstant) {
-    // let a = 1;
-    // a += 1;
-    auto* a = Let(Source{{12, 34}}, "a", nullptr, Expr(1));
-    WrapInFunction(a, CompoundAssign(Expr(Source{{56, 78}}, "a"), 1, ast::BinaryOp::kAdd));
+    // let a = 1i;
+    // a += 1i;
+    auto* a = Let(Source{{12, 34}}, "a", nullptr, Expr(1_i));
+    WrapInFunction(a, CompoundAssign(Expr(Source{{56, 78}}, "a"), 1_i, ast::BinaryOp::kAdd));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), R"(56:78 error: cannot assign to const
@@ -253,8 +255,8 @@
 }
 
 TEST_F(ResolverCompoundAssignmentValidationTest, LhsLiteral) {
-    // 1 += 1;
-    WrapInFunction(CompoundAssign(Expr(Source{{56, 78}}, 1), 1, ast::BinaryOp::kAdd));
+    // 1i += 1i;
+    WrapInFunction(CompoundAssign(Expr(Source{{56, 78}}, 1_i), 1_i, ast::BinaryOp::kAdd));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "56:78 error: cannot assign to value of type 'i32'");
diff --git a/src/tint/resolver/compound_statement_test.cc b/src/tint/resolver/compound_statement_test.cc
index 1358b38..4061a62 100644
--- a/src/tint/resolver/compound_statement_test.cc
+++ b/src/tint/resolver/compound_statement_test.cc
@@ -22,6 +22,8 @@
 #include "src/tint/sem/loop_statement.h"
 #include "src/tint/sem/switch_statement.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -87,7 +89,7 @@
     //   }
     // }
     auto* brk = Break();
-    auto* stmt = Ignore(1);
+    auto* stmt = Ignore(1_i);
     auto* loop = Loop(Block(brk), Block(stmt));
     auto* f = Func("F", {}, ty.void_(), {loop});
 
@@ -150,7 +152,7 @@
     // }
     auto* init = Decl(Var("i", ty.u32()));
     auto* cond = Expr(true);
-    auto* cont = Assign("i", Add("i", 1u));
+    auto* cont = Assign("i", Add("i", 1_u));
     auto* stmt = Return();
     auto* body = Block(stmt);
     auto* for_ = For(init, cond, cont, body);
@@ -220,10 +222,10 @@
     // }
 
     auto* cond_a = Expr(true);
-    auto* stmt_a = Ignore(1);
+    auto* stmt_a = Ignore(1_i);
     auto* cond_b = Expr(true);
-    auto* stmt_b = Ignore(1);
-    auto* stmt_c = Ignore(1);
+    auto* stmt_b = Ignore(1_i);
+    auto* stmt_c = Ignore(1_i);
     auto* if_stmt = If(cond_a, Block(stmt_a), Else(If(cond_b, Block(stmt_b), Else(Block(stmt_c)))));
     WrapInFunction(if_stmt);
 
@@ -293,10 +295,10 @@
 TEST_F(ResolverCompoundStatementTest, Switch) {
     // fn F() {
     //   switch (expr) {
-    //     case 1: {
+    //     case 1i: {
     //        stmt_a;
     //     }
-    //     case 2: {
+    //     case 2i: {
     //        stmt_b;
     //     }
     //     default: {
@@ -305,11 +307,11 @@
     //   }
     // }
 
-    auto* expr = Expr(5);
-    auto* stmt_a = Ignore(1);
-    auto* stmt_b = Ignore(1);
-    auto* stmt_c = Ignore(1);
-    auto* swi = Switch(expr, Case(Expr(1), Block(stmt_a)), Case(Expr(2), Block(stmt_b)),
+    auto* expr = Expr(5_i);
+    auto* stmt_a = Ignore(1_i);
+    auto* stmt_b = Ignore(1_i);
+    auto* stmt_c = Ignore(1_i);
+    auto* swi = Switch(expr, Case(Expr(1_i), Block(stmt_a)), Case(Expr(2_i), Block(stmt_b)),
                        DefaultCase(Block(stmt_c)));
     WrapInFunction(swi);
 
diff --git a/src/tint/resolver/control_block_validation_test.cc b/src/tint/resolver/control_block_validation_test.cc
index 3630d5c..b4742c9 100644
--- a/src/tint/resolver/control_block_validation_test.cc
+++ b/src/tint/resolver/control_block_validation_test.cc
@@ -18,6 +18,8 @@
 #include "src/tint/ast/switch_statement.h"
 #include "src/tint/resolver/resolver_test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -46,11 +48,11 @@
     // switch (a) {
     //   case 1: {}
     // }
-    auto* var = Var("a", ty.i32(), Expr(2));
+    auto* var = Var("a", ty.i32(), Expr(2_i));
 
     auto* block = Block(Decl(var),                     //
                         Switch(Source{{12, 34}}, "a",  //
-                               Case(Expr(1))));
+                               Case(Expr(1_i))));
 
     WrapInFunction(block);
 
@@ -65,12 +67,12 @@
     //   case 1: {}
     //   default: {}
     // }
-    auto* var = Var("a", ty.i32(), Expr(2));
+    auto* var = Var("a", ty.i32(), Expr(2_i));
 
-    auto* block = Block(Decl(var),             //
-                        Switch("a",            //
-                               DefaultCase(),  //
-                               Case(Expr(1)),  //
+    auto* block = Block(Decl(var),               //
+                        Switch("a",              //
+                               DefaultCase(),    //
+                               Case(Expr(1_i)),  //
                                DefaultCase(Source{{12, 34}})));
 
     WrapInFunction(block);
@@ -88,7 +90,7 @@
     // }
     auto* decl_z = Decl(Var("z", ty.i32()));
     auto* cont = Continue();
-    auto* assign_z = Assign(Source{{12, 34}}, "z", 1);
+    auto* assign_z = Assign(Source{{12, 34}}, "z", 1_i);
     WrapInFunction(Loop(Block(If(false, Block(Break())), decl_z, cont, assign_z)));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -107,7 +109,7 @@
     // }
     auto* decl_z = Decl(Var("z", ty.i32()));
     auto* cont = Continue();
-    auto* assign_z = Assign(Source{{12, 34}}, "z", 1);
+    auto* assign_z = Assign(Source{{12, 34}}, "z", 1_i);
     WrapInFunction(
         Loop(Block(If(false, Block(Break())), decl_z, Block(Block(Block(cont))), assign_z)));
 
@@ -126,7 +128,7 @@
     // }
     auto* decl_z = Decl(Var("z", ty.i32()));
     auto* cont = Continue();
-    auto* assign_z = Assign(Source{{12, 34}}, "z", 1);
+    auto* assign_z = Assign(Source{{12, 34}}, "z", 1_i);
     WrapInFunction(For(nullptr, false, nullptr,  //
                        Block(decl_z, cont, assign_z)));
 
@@ -145,7 +147,7 @@
     // }
     auto* decl_z = Decl(Var("z", ty.i32()));
     auto* cont = Continue();
-    auto* assign_z = Assign(Source{{12, 34}}, "z", 1);
+    auto* assign_z = Assign(Source{{12, 34}}, "z", 1_i);
     WrapInFunction(
         For(nullptr, false, nullptr, Block(decl_z, Block(Block(Block(cont))), assign_z)));
 
@@ -157,19 +159,19 @@
 }
 
 TEST_F(ResolverControlBlockValidationTest, UnreachableCode_break) {
-    // switch (1) {
-    //   case 1: {
+    // switch (1i) {
+    //   case 1i: {
     //     var z: i32;
     //     break;
-    //     z = 1;
+    //     z = 1i;
     //   default: {}
     // }
     auto* decl_z = Decl(Var("z", ty.i32()));
     auto* brk = Break();
-    auto* assign_z = Assign(Source{{12, 34}}, "z", 1);
-    WrapInFunction(                                                //
-        Block(Switch(1,                                            //
-                     Case(Expr(1), Block(decl_z, brk, assign_z)),  //
+    auto* assign_z = Assign(Source{{12, 34}}, "z", 1_i);
+    WrapInFunction(                                                  //
+        Block(Switch(1_i,                                            //
+                     Case(Expr(1_i), Block(decl_z, brk, assign_z)),  //
                      DefaultCase())));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -181,18 +183,18 @@
 
 TEST_F(ResolverControlBlockValidationTest, UnreachableCode_break_InBlocks) {
     // loop {
-    //   switch (1) {
-    //     case 1: { {{{break;}}} var a : u32 = 2;}
+    //   switch (1i) {
+    //     case 1i: { {{{break;}}} var a : u32 = 2;}
     //     default: {}
     //   }
     //   break;
     // }
     auto* decl_z = Decl(Var("z", ty.i32()));
     auto* brk = Break();
-    auto* assign_z = Assign(Source{{12, 34}}, "z", 1);
+    auto* assign_z = Assign(Source{{12, 34}}, "z", 1_i);
     WrapInFunction(
-        Loop(Block(Switch(1,  //
-                          Case(Expr(1), Block(decl_z, Block(Block(Block(brk))), assign_z)),
+        Loop(Block(Switch(1_i,  //
+                          Case(Expr(1_i), Block(decl_z, Block(Block(Block(brk))), assign_z)),
                           DefaultCase()),  //
                    Break())));
 
@@ -206,13 +208,13 @@
 TEST_F(ResolverControlBlockValidationTest, SwitchConditionTypeMustMatchSelectorType2_Fail) {
     // var a : u32 = 2;
     // switch (a) {
-    //   case 1: {}
+    //   case 1i: {}
     //   default: {}
     // }
-    auto* var = Var("a", ty.i32(), Expr(2));
+    auto* var = Var("a", ty.i32(), Expr(2_i));
 
-    auto* block = Block(Decl(var), Switch("a",                                 //
-                                          Case(Source{{12, 34}}, {Expr(1u)}),  //
+    auto* block = Block(Decl(var), Switch("a",                                  //
+                                          Case(Source{{12, 34}}, {Expr(1_u)}),  //
                                           DefaultCase()));
     WrapInFunction(block);
 
@@ -225,14 +227,14 @@
 TEST_F(ResolverControlBlockValidationTest, SwitchConditionTypeMustMatchSelectorType_Fail) {
     // var a : u32 = 2;
     // switch (a) {
-    //   case -1: {}
+    //   case -1i: {}
     //   default: {}
     // }
-    auto* var = Var("a", ty.u32(), Expr(2u));
+    auto* var = Var("a", ty.u32(), Expr(2_u));
 
-    auto* block = Block(Decl(var),                                  //
-                        Switch("a",                                 //
-                               Case(Source{{12, 34}}, {Expr(-1)}),  //
+    auto* block = Block(Decl(var),                                       //
+                        Switch("a",                                      //
+                               Case(Source{{12, 34}}, {Expr(i32(-1))}),  //
                                DefaultCase()));
     WrapInFunction(block);
 
@@ -249,15 +251,15 @@
     //   case 2u, 3u, 2u: {}
     //   default: {}
     // }
-    auto* var = Var("a", ty.u32(), Expr(3u));
+    auto* var = Var("a", ty.u32(), Expr(3_u));
 
     auto* block = Block(Decl(var),   //
                         Switch("a",  //
-                               Case(Expr(0u)),
+                               Case(Expr(0_u)),
                                Case({
-                                   Expr(Source{{12, 34}}, 2u),
-                                   Expr(3u),
-                                   Expr(Source{{56, 78}}, 2u),
+                                   Expr(Source{{12, 34}}, 2_u),
+                                   Expr(3_u),
+                                   Expr(Source{{56, 78}}, 2_u),
                                }),
                                DefaultCase()));
     WrapInFunction(block);
@@ -275,16 +277,16 @@
     //   case 0,1,2,-10: {}
     //   default: {}
     // }
-    auto* var = Var("a", ty.i32(), Expr(2));
+    auto* var = Var("a", ty.i32(), Expr(2_i));
 
     auto* block = Block(Decl(var),   //
                         Switch("a",  //
-                               Case(Expr(Source{{12, 34}}, -10)),
+                               Case(Expr(Source{{12, 34}}, i32(-10))),
                                Case({
-                                   Expr(0),
-                                   Expr(1),
-                                   Expr(2),
-                                   Expr(Source{{56, 78}}, -10),
+                                   Expr(0_i),
+                                   Expr(1_i),
+                                   Expr(2_i),
+                                   Expr(Source{{56, 78}}, i32(-10)),
                                }),
                                DefaultCase()));
     WrapInFunction(block);
@@ -300,7 +302,7 @@
     // switch (a) {
     //   default: { fallthrough; }
     // }
-    auto* var = Var("a", ty.i32(), Expr(2));
+    auto* var = Var("a", ty.i32(), Expr(2_i));
     auto* fallthrough = create<ast::FallthroughStatement>(Source{{12, 34}});
     auto* block = Block(Decl(var),   //
                         Switch("a",  //
@@ -319,12 +321,12 @@
     //   default: {}
     //   case 5: {}
     // }
-    auto* var = Var("a", ty.i32(), Expr(2));
+    auto* var = Var("a", ty.i32(), Expr(2_i));
 
     auto* block = Block(Decl(var),                             //
                         Switch("a",                            //
                                DefaultCase(Source{{12, 34}}),  //
-                               Case(Expr(5))));
+                               Case(Expr(5_i))));
     WrapInFunction(block);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -338,7 +340,7 @@
     // }
 
     auto* my_int = Alias("MyInt", ty.u32());
-    auto* var = Var("a", ty.Of(my_int), Expr(2u));
+    auto* var = Var("a", ty.Of(my_int), Expr(2_u));
     auto* block = Block(Decl(var),  //
                         Switch("a", DefaultCase(Source{{12, 34}})));
 
diff --git a/src/tint/resolver/dependency_graph_test.cc b/src/tint/resolver/dependency_graph_test.cc
index a0a6edd..248dc87 100644
--- a/src/tint/resolver/dependency_graph_test.cc
+++ b/src/tint/resolver/dependency_graph_test.cc
@@ -20,6 +20,8 @@
 #include "src/tint/resolver/dependency_graph.h"
 #include "src/tint/resolver/resolver_test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -425,7 +427,7 @@
         case SymbolDeclKind::GlobalVar:
             return b.Global(source, symbol, b.ty.i32(), ast::StorageClass::kPrivate);
         case SymbolDeclKind::GlobalConst:
-            return b.GlobalConst(source, symbol, b.ty.i32(), b.Expr(1));
+            return b.GlobalConst(source, symbol, b.ty.i32(), b.Expr(1_i));
         case SymbolDeclKind::Alias:
             return b.Alias(source, symbol, b.ty.i32());
         case SymbolDeclKind::Struct:
@@ -443,7 +445,7 @@
             return node;
         }
         case SymbolDeclKind::LocalLet: {
-            auto* node = b.Let(source, symbol, b.ty.i32(), b.Expr(1));
+            auto* node = b.Let(source, symbol, b.ty.i32(), b.Expr(1_i));
             statements.emplace_back(b.Decl(node));
             return node;
         }
@@ -453,7 +455,7 @@
             return node;
         }
         case SymbolDeclKind::NestedLocalLet: {
-            auto* node = b.Let(source, symbol, b.ty.i32(), b.Expr(1));
+            auto* node = b.Let(source, symbol, b.ty.i32(), b.Expr(1_i));
             nested_statements.emplace_back(b.Decl(node));
             return node;
         }
@@ -471,7 +473,7 @@
         }
         case SymbolUseKind::GlobalVarArrayElemType: {
             auto* node = b.ty.type_name(source, symbol);
-            b.Global(b.Sym(), b.ty.array(node, 4), ast::StorageClass::kPrivate);
+            b.Global(b.Sym(), b.ty.array(node, 4_i), ast::StorageClass::kPrivate);
             return node;
         }
         case SymbolUseKind::GlobalVarArraySizeValue: {
@@ -506,27 +508,27 @@
         }
         case SymbolUseKind::GlobalLetType: {
             auto* node = b.ty.type_name(source, symbol);
-            b.GlobalConst(b.Sym(), node, b.Expr(1));
+            b.GlobalConst(b.Sym(), node, b.Expr(1_i));
             return node;
         }
         case SymbolUseKind::GlobalLetArrayElemType: {
             auto* node = b.ty.type_name(source, symbol);
-            b.GlobalConst(b.Sym(), b.ty.array(node, 4), b.Expr(1));
+            b.GlobalConst(b.Sym(), b.ty.array(node, 4_i), b.Expr(1_i));
             return node;
         }
         case SymbolUseKind::GlobalLetArraySizeValue: {
             auto* node = b.Expr(source, symbol);
-            b.GlobalConst(b.Sym(), b.ty.array(b.ty.i32(), node), b.Expr(1));
+            b.GlobalConst(b.Sym(), b.ty.array(b.ty.i32(), node), b.Expr(1_i));
             return node;
         }
         case SymbolUseKind::GlobalLetVectorElemType: {
             auto* node = b.ty.type_name(source, symbol);
-            b.GlobalConst(b.Sym(), b.ty.vec3(node), b.Expr(1));
+            b.GlobalConst(b.Sym(), b.ty.vec3(node), b.Expr(1_i));
             return node;
         }
         case SymbolUseKind::GlobalLetMatrixElemType: {
             auto* node = b.ty.type_name(source, symbol);
-            b.GlobalConst(b.Sym(), b.ty.mat3x4(node), b.Expr(1));
+            b.GlobalConst(b.Sym(), b.ty.mat3x4(node), b.Expr(1_i));
             return node;
         }
         case SymbolUseKind::GlobalLetValue: {
@@ -561,13 +563,13 @@
         }
         case SymbolUseKind::LocalVarArrayElemType: {
             auto* node = b.ty.type_name(source, symbol);
-            statements.emplace_back(b.Decl(b.Var(b.Sym(), b.ty.array(node, 4), b.Expr(1))));
+            statements.emplace_back(b.Decl(b.Var(b.Sym(), b.ty.array(node, 4_u), b.Expr(1_i))));
             return node;
         }
         case SymbolUseKind::LocalVarArraySizeValue: {
             auto* node = b.Expr(source, symbol);
             statements.emplace_back(
-                b.Decl(b.Var(b.Sym(), b.ty.array(b.ty.i32(), node), b.Expr(1))));
+                b.Decl(b.Var(b.Sym(), b.ty.array(b.ty.i32(), node), b.Expr(1_i))));
             return node;
         }
         case SymbolUseKind::LocalVarVectorElemType: {
@@ -587,7 +589,7 @@
         }
         case SymbolUseKind::LocalLetType: {
             auto* node = b.ty.type_name(source, symbol);
-            statements.emplace_back(b.Decl(b.Let(b.Sym(), node, b.Expr(1))));
+            statements.emplace_back(b.Decl(b.Let(b.Sym(), node, b.Expr(1_i))));
             return node;
         }
         case SymbolUseKind::LocalLetValue: {
@@ -607,7 +609,7 @@
         }
         case SymbolUseKind::NestedLocalLetType: {
             auto* node = b.ty.type_name(source, symbol);
-            nested_statements.emplace_back(b.Decl(b.Let(b.Sym(), node, b.Expr(1))));
+            nested_statements.emplace_back(b.Decl(b.Let(b.Sym(), node, b.Expr(1_i))));
             return node;
         }
         case SymbolUseKind::NestedLocalLetValue: {
@@ -617,7 +619,7 @@
         }
         case SymbolUseKind::WorkgroupSizeValue: {
             auto* node = b.Expr(source, symbol);
-            func_attrs.emplace_back(b.WorkgroupSize(1, node, 2));
+            func_attrs.emplace_back(b.WorkgroupSize(1_i, node, 2_i));
             return node;
         }
     }
@@ -767,27 +769,27 @@
 
 TEST_F(ResolverDependencyGraphDeclSelfUse, GlobalVar) {
     const Symbol symbol = Sym("SYMBOL");
-    Global(symbol, ty.i32(), Mul(Expr(Source{{12, 34}}, symbol), 123));
+    Global(symbol, ty.i32(), Mul(Expr(Source{{12, 34}}, symbol), 123_i));
     Build(R"(error: cyclic dependency found: 'SYMBOL' -> 'SYMBOL'
 12:34 note: var 'SYMBOL' references var 'SYMBOL' here)");
 }
 
 TEST_F(ResolverDependencyGraphDeclSelfUse, GlobalConst) {
     const Symbol symbol = Sym("SYMBOL");
-    GlobalConst(symbol, ty.i32(), Mul(Expr(Source{{12, 34}}, symbol), 123));
+    GlobalConst(symbol, ty.i32(), Mul(Expr(Source{{12, 34}}, symbol), 123_i));
     Build(R"(error: cyclic dependency found: 'SYMBOL' -> 'SYMBOL'
 12:34 note: let 'SYMBOL' references let 'SYMBOL' here)");
 }
 
 TEST_F(ResolverDependencyGraphDeclSelfUse, LocalVar) {
     const Symbol symbol = Sym("SYMBOL");
-    WrapInFunction(Decl(Var(symbol, ty.i32(), Mul(Expr(Source{{12, 34}}, symbol), 123))));
+    WrapInFunction(Decl(Var(symbol, ty.i32(), Mul(Expr(Source{{12, 34}}, symbol), 123_i))));
     Build("12:34 error: unknown identifier: 'SYMBOL'");
 }
 
 TEST_F(ResolverDependencyGraphDeclSelfUse, LocalLet) {
     const Symbol symbol = Sym("SYMBOL");
-    WrapInFunction(Decl(Let(symbol, ty.i32(), Mul(Expr(Source{{12, 34}}, symbol), 123))));
+    WrapInFunction(Decl(Let(symbol, ty.i32(), Mul(Expr(Source{{12, 34}}, symbol), 123_i))));
     Build("12:34 error: unknown identifier: 'SYMBOL'");
 }
 
@@ -1229,9 +1231,9 @@
              Loop(Block(Assign(V, V)),                  //
                   Block(Assign(V, V))),                 //
              Switch(V,                                  //
-                    Case(Expr(1),                       //
+                    Case(Expr(1_i),                     //
                          Block(Assign(V, V))),          //
-                    Case(Expr(2),                       //
+                    Case(Expr(2_i),                     //
                          Block(Fallthrough())),         //
                     DefaultCase(Block(Assign(V, V)))),  //
              Return(V),                                 //
@@ -1270,10 +1272,10 @@
 
 TEST_F(ResolverDependencyGraphTraversalTest, InferredType) {
     // Check that the nullptr of the var / let type doesn't make things explode
-    Global("a", nullptr, Expr(1));
-    GlobalConst("b", nullptr, Expr(1));
-    WrapInFunction(Var("c", nullptr, Expr(1)),  //
-                   Let("d", nullptr, Expr(1)));
+    Global("a", nullptr, Expr(1_i));
+    GlobalConst("b", nullptr, Expr(1_i));
+    WrapInFunction(Var("c", nullptr, Expr(1_i)),  //
+                   Let("d", nullptr, Expr(1_i)));
     Build();
 }
 
diff --git a/src/tint/resolver/entry_point_validation_test.cc b/src/tint/resolver/entry_point_validation_test.cc
index 5a10bf2..d1d9a48 100644
--- a/src/tint/resolver/entry_point_validation_test.cc
+++ b/src/tint/resolver/entry_point_validation_test.cc
@@ -21,6 +21,8 @@
 
 #include "gmock/gmock.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -41,9 +43,6 @@
 using mat4x4 = builder::mat4x4<T>;
 template <typename T>
 using alias = builder::alias<T>;
-using f32 = builder::f32;
-using i32 = builder::i32;
-using u32 = builder::u32;
 
 class ResolverEntryPointValidationTest : public TestHelper, public testing::Test {};
 
@@ -648,9 +647,9 @@
 }
 
 TEST_F(LocationAttributeTests, ComputeShaderLocation_Input) {
-    Func("main", {}, ty.i32(), {Return(Expr(1))},
+    Func("main", {}, ty.i32(), {Return(Expr(1_i))},
          {Stage(ast::PipelineStage::kCompute),
-          create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1))},
+          create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i))},
          ast::AttributeList{Location(Source{{12, 34}}, 1)});
 
     EXPECT_FALSE(r()->Resolve());
@@ -661,7 +660,7 @@
     auto* input = Param("input", ty.i32(), ast::AttributeList{Location(Source{{12, 34}}, 0u)});
     Func("main", {input}, ty.void_(), {},
          {Stage(ast::PipelineStage::kCompute),
-          create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1))});
+          create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i))});
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: attribute is not valid for compute shader inputs");
@@ -673,7 +672,7 @@
     Func(Source{{56, 78}}, "main", {}, ty.Of(s),
          ast::StatementList{Return(Expr(Construct(ty.Of(s))))},
          {Stage(ast::PipelineStage::kCompute),
-          create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1))});
+          create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i))});
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -687,7 +686,7 @@
     auto* input = Param("input", ty.Of(s));
     Func(Source{{56, 78}}, "main", {input}, ty.void_(), {},
          {Stage(ast::PipelineStage::kCompute),
-          create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1))});
+          create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i))});
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
diff --git a/src/tint/resolver/function_validation_test.cc b/src/tint/resolver/function_validation_test.cc
index 0df7d3f..1bc70a5 100644
--- a/src/tint/resolver/function_validation_test.cc
+++ b/src/tint/resolver/function_validation_test.cc
@@ -20,6 +20,8 @@
 
 #include "gmock/gmock.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -45,10 +47,10 @@
 
 TEST_F(ResolverFunctionValidationTest, LocalConflictsWithParameter) {
     // fn func(common_name : f32) {
-    //   let common_name = 1;
+    //   let common_name = 1i;
     // }
     Func("func", {Param(Source{{12, 34}}, "common_name", ty.f32())}, ty.void_(),
-         {Decl(Let(Source{{56, 78}}, "common_name", nullptr, Expr(1)))});
+         {Decl(Let(Source{{56, 78}}, "common_name", nullptr, Expr(1_i)))});
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), R"(56:78 error: redeclaration of 'common_name'
@@ -58,18 +60,18 @@
 TEST_F(ResolverFunctionValidationTest, NestedLocalMayShadowParameter) {
     // fn func(common_name : f32) {
     //   {
-    //     let common_name = 1;
+    //     let common_name = 1i;
     //   }
     // }
     Func("func", {Param(Source{{12, 34}}, "common_name", ty.f32())}, ty.void_(),
-         {Block(Decl(Let(Source{{56, 78}}, "common_name", nullptr, Expr(1))))});
+         {Block(Decl(Let(Source{{56, 78}}, "common_name", nullptr, Expr(1_i))))});
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverFunctionValidationTest, VoidFunctionEndWithoutReturnStatement_Pass) {
-    // fn func { var a:i32 = 2; }
-    auto* var = Var("a", ty.i32(), Expr(2));
+    // fn func { var a:i32 = 2i; }
+    auto* var = Var("a", ty.i32(), Expr(2_i));
 
     Func(Source{{12, 34}}, "func", ast::VariableList{}, ty.void_(),
          ast::StatementList{
@@ -81,11 +83,11 @@
 
 TEST_F(ResolverFunctionValidationTest, FunctionUsingSameVariableName_Pass) {
     // fn func() -> i32 {
-    //   var func:i32 = 0;
+    //   var func:i32 = 0i;
     //   return func;
     // }
 
-    auto* var = Var("func", ty.i32(), Expr(0));
+    auto* var = Var("func", ty.i32(), Expr(0_i));
     Func("func", ast::VariableList{}, ty.i32(),
          ast::StatementList{
              Decl(var),
@@ -97,10 +99,10 @@
 }
 
 TEST_F(ResolverFunctionValidationTest, FunctionNameSameAsFunctionScopeVariableName_Pass) {
-    // fn a() -> void { var b:i32 = 0; }
+    // fn a() -> void { var b:i32 = 0i; }
     // fn b() -> i32 { return 2; }
 
-    auto* var = Var("b", ty.i32(), Expr(0));
+    auto* var = Var("b", ty.i32(), Expr(0_i));
     Func("a", ast::VariableList{}, ty.void_(),
          ast::StatementList{
              Decl(var),
@@ -109,7 +111,7 @@
 
     Func(Source{{12, 34}}, "b", ast::VariableList{}, ty.i32(),
          ast::StatementList{
-             Return(2),
+             Return(2_i),
          },
          ast::AttributeList{});
 
@@ -120,12 +122,12 @@
     // fn func() -> {
     //  var a : i32;
     //  return;
-    //  a = 2;
+    //  a = 2i;
     //}
 
     auto* decl_a = Decl(Var("a", ty.i32()));
     auto* ret = Return();
-    auto* assign_a = Assign(Source{{12, 34}}, "a", 2);
+    auto* assign_a = Assign(Source{{12, 34}}, "a", 2_i);
 
     Func("func", ast::VariableList{}, ty.void_(), {decl_a, ret, assign_a});
 
@@ -141,12 +143,12 @@
     // fn func() -> {
     //  var a : i32;
     //  {{{return;}}}
-    //  a = 2;
+    //  a = 2i;
     //}
 
     auto* decl_a = Decl(Var("a", ty.i32()));
     auto* ret = Return();
-    auto* assign_a = Assign(Source{{12, 34}}, "a", 2);
+    auto* assign_a = Assign(Source{{12, 34}}, "a", 2_i);
 
     Func("func", ast::VariableList{}, ty.void_(), {decl_a, Block(Block(Block(ret))), assign_a});
 
@@ -161,12 +163,12 @@
     // fn func() -> {
     //  var a : i32;
     //  discard;
-    //  a = 2;
+    //  a = 2i;
     //}
 
     auto* decl_a = Decl(Var("a", ty.i32()));
     auto* discard = Discard();
-    auto* assign_a = Assign(Source{{12, 34}}, "a", 2);
+    auto* assign_a = Assign(Source{{12, 34}}, "a", 2_i);
 
     Func("func", ast::VariableList{}, ty.void_(), {decl_a, discard, assign_a});
 
@@ -181,12 +183,12 @@
     // fn func() -> {
     //  var a : i32;
     //  {{{discard;}}}
-    //  a = 2;
+    //  a = 2i;
     //}
 
     auto* decl_a = Decl(Var("a", ty.i32()));
     auto* discard = Discard();
-    auto* assign_a = Assign(Source{{12, 34}}, "a", 2);
+    auto* assign_a = Assign(Source{{12, 34}}, "a", 2_i);
 
     Func("func", ast::VariableList{}, ty.void_(), {decl_a, Block(Block(Block(discard))), assign_a});
 
@@ -198,9 +200,9 @@
 }
 
 TEST_F(ResolverFunctionValidationTest, FunctionEndWithoutReturnStatement_Fail) {
-    // fn func() -> int { var a:i32 = 2; }
+    // fn func() -> int { var a:i32 = 2i; }
 
-    auto* var = Var("a", ty.i32(), Expr(2));
+    auto* var = Var("a", ty.i32(), Expr(2_i));
 
     Func(Source{{12, 34}}, "func", ast::VariableList{}, ty.i32(),
          ast::StatementList{
@@ -242,10 +244,10 @@
 }
 
 TEST_F(ResolverFunctionValidationTest, FunctionTypeMustMatchReturnStatementType_fail) {
-    // fn func { return 2; }
+    // fn func { return 2i; }
     Func("func", ast::VariableList{}, ty.void_(),
          ast::StatementList{
-             Return(Source{{12, 34}}, Expr(2)),
+             Return(Source{{12, 34}}, Expr(2_i)),
          },
          ast::AttributeList{});
 
@@ -294,10 +296,10 @@
 }
 
 TEST_F(ResolverFunctionValidationTest, FunctionTypeMustMatchReturnStatementTypeF32_fail) {
-    // fn func() -> f32 { return 2; }
+    // fn func() -> f32 { return 2i; }
     Func("func", ast::VariableList{}, ty.f32(),
          ast::StatementList{
-             Return(Source{{12, 34}}, Expr(2)),
+             Return(Source{{12, 34}}, Expr(2_i)),
          },
          ast::AttributeList{});
 
@@ -322,11 +324,11 @@
 
 TEST_F(ResolverFunctionValidationTest, FunctionTypeMustMatchReturnStatementTypeF32Alias_fail) {
     // type myf32 = f32;
-    // fn func() -> myf32 { return 2; }
+    // fn func() -> myf32 { return 2u; }
     auto* myf32 = Alias("myf32", ty.f32());
     Func("func", ast::VariableList{}, ty.Of(myf32),
          ast::StatementList{
-             Return(Source{{12, 34}}, Expr(2u)),
+             Return(Source{{12, 34}}, Expr(2_u)),
          },
          ast::AttributeList{});
 
@@ -340,7 +342,7 @@
     // @stage(compute) @workgroup_size(1) fn entrypoint() {}
     // fn func() { return entrypoint(); }
     Func("entrypoint", ast::VariableList{}, ty.void_(), {},
-         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     Func("func", ast::VariableList{}, ty.void_(),
          {
@@ -412,7 +414,7 @@
 
 TEST_F(ResolverFunctionValidationTest, FunctionParamsConst) {
     Func("foo", {Param(Sym("arg"), ty.i32())}, ty.void_(),
-         {Assign(Expr(Source{{12, 34}}, "arg"), Expr(1)), Return()});
+         {Assign(Expr(Source{{12, 34}}, "arg"), Expr(1_i)), Return()});
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -425,11 +427,11 @@
     // let x = 8u;
     // @stage(compute) @workgroup_size(x, y, 16u)
     // fn main() {}
-    auto* x = GlobalConst("x", ty.u32(), Expr(4u));
-    auto* y = GlobalConst("y", ty.u32(), Expr(8u));
-    auto* func =
-        Func("main", {}, ty.void_(), {},
-             {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Expr("x"), Expr("y"), Expr(16u))});
+    auto* x = GlobalConst("x", ty.u32(), Expr(4_u));
+    auto* y = GlobalConst("y", ty.u32(), Expr(8_u));
+    auto* func = Func(
+        "main", {}, ty.void_(), {},
+        {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Expr("x"), Expr("y"), Expr(16_u))});
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 
@@ -451,18 +453,18 @@
 
     Func("main", {}, ty.void_(), {},
          {Stage(ast::PipelineStage::kCompute),
-          WorkgroupSize(Source{{12, 34}}, Expr(1u), Expr(2u), Expr(3u))});
+          WorkgroupSize(Source{{12, 34}}, Expr(1_u), Expr(2_u), Expr(3_u))});
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverFunctionValidationTest, WorkgroupSize_MismatchTypeU32) {
-    // @stage(compute) @workgroup_size(1u, 2u, 3)
+    // @stage(compute) @workgroup_size(1u, 2u, 3_i)
     // fn main() {}
 
     Func("main", {}, ty.void_(), {},
          {Stage(ast::PipelineStage::kCompute),
-          WorkgroupSize(Expr(1u), Expr(2u), Expr(Source{{12, 34}}, 3))});
+          WorkgroupSize(Expr(1_u), Expr(2_u), Expr(Source{{12, 34}}, 3_i))});
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -471,12 +473,12 @@
 }
 
 TEST_F(ResolverFunctionValidationTest, WorkgroupSize_MismatchTypeI32) {
-    // @stage(compute) @workgroup_size(1, 2u, 3)
+    // @stage(compute) @workgroup_size(1_i, 2u, 3_i)
     // fn main() {}
 
     Func("main", {}, ty.void_(), {},
          {Stage(ast::PipelineStage::kCompute),
-          WorkgroupSize(Expr(1), Expr(Source{{12, 34}}, 2u), Expr(3))});
+          WorkgroupSize(Expr(1_i), Expr(Source{{12, 34}}, 2_u), Expr(3_i))});
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -486,12 +488,12 @@
 
 TEST_F(ResolverFunctionValidationTest, WorkgroupSize_Const_TypeMismatch) {
     // let x = 64u;
-    // @stage(compute) @workgroup_size(1, x)
+    // @stage(compute) @workgroup_size(1i, x)
     // fn main() {}
-    GlobalConst("x", ty.u32(), Expr(64u));
-    Func(
-        "main", {}, ty.void_(), {},
-        {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Expr(1), Expr(Source{{12, 34}}, "x"))});
+    GlobalConst("x", ty.u32(), Expr(64_u));
+    Func("main", {}, ty.void_(), {},
+         {Stage(ast::PipelineStage::kCompute),
+          WorkgroupSize(Expr(1_i), Expr(Source{{12, 34}}, "x"))});
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -501,11 +503,11 @@
 
 TEST_F(ResolverFunctionValidationTest, WorkgroupSize_Const_TypeMismatch2) {
     // let x = 64u;
-    // let y = 32;
+    // let y = 32i;
     // @stage(compute) @workgroup_size(x, y)
     // fn main() {}
-    GlobalConst("x", ty.u32(), Expr(64u));
-    GlobalConst("y", ty.i32(), Expr(32));
+    GlobalConst("x", ty.u32(), Expr(64_u));
+    GlobalConst("y", ty.i32(), Expr(32_i));
     Func("main", {}, ty.void_(), {},
          {Stage(ast::PipelineStage::kCompute),
           WorkgroupSize(Expr("x"), Expr(Source{{12, 34}}, "y"))});
@@ -518,13 +520,13 @@
 TEST_F(ResolverFunctionValidationTest, WorkgroupSize_Mismatch_ConstU32) {
     // let x = 4u;
     // let x = 8u;
-    // @stage(compute) @workgroup_size(x, y, 16
+    // @stage(compute) @workgroup_size(x, y, 16i)
     // fn main() {}
-    GlobalConst("x", ty.u32(), Expr(4u));
-    GlobalConst("y", ty.u32(), Expr(8u));
+    GlobalConst("x", ty.u32(), Expr(4_u));
+    GlobalConst("y", ty.u32(), Expr(8_u));
     Func("main", {}, ty.void_(), {},
          {Stage(ast::PipelineStage::kCompute),
-          WorkgroupSize(Expr("x"), Expr("y"), Expr(Source{{12, 34}}, 16))});
+          WorkgroupSize(Expr("x"), Expr("y"), Expr(Source{{12, 34}}, 16_i))});
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -546,22 +548,22 @@
 }
 
 TEST_F(ResolverFunctionValidationTest, WorkgroupSize_Literal_Negative) {
-    // @stage(compute) @workgroup_size(-2)
+    // @stage(compute) @workgroup_size(-2i)
     // fn main() {}
 
     Func("main", {}, ty.void_(), {},
-         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Expr(Source{{12, 34}}, -2))});
+         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Expr(Source{{12, 34}}, i32(-2)))});
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: workgroup_size argument must be at least 1");
 }
 
 TEST_F(ResolverFunctionValidationTest, WorkgroupSize_Literal_Zero) {
-    // @stage(compute) @workgroup_size(0)
+    // @stage(compute) @workgroup_size(0i)
     // fn main() {}
 
     Func("main", {}, ty.void_(), {},
-         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Expr(Source{{12, 34}}, 0))});
+         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Expr(Source{{12, 34}}, 0_i))});
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: workgroup_size argument must be at least 1");
@@ -582,10 +584,10 @@
 }
 
 TEST_F(ResolverFunctionValidationTest, WorkgroupSize_Const_Negative) {
-    // let x = -2;
+    // let x = -2i;
     // @stage(compute) @workgroup_size(x)
     // fn main() {}
-    GlobalConst("x", ty.i32(), Expr(-2));
+    GlobalConst("x", ty.i32(), Expr(i32(-2)));
     Func("main", {}, ty.void_(), {},
          {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Expr(Source{{12, 34}}, "x"))});
 
@@ -594,10 +596,10 @@
 }
 
 TEST_F(ResolverFunctionValidationTest, WorkgroupSize_Const_Zero) {
-    // let x = 0;
+    // let x = 0i;
     // @stage(compute) @workgroup_size(x)
     // fn main() {}
-    GlobalConst("x", ty.i32(), Expr(0));
+    GlobalConst("x", ty.i32(), Expr(0_i));
     Func("main", {}, ty.void_(), {},
          {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Expr(Source{{12, 34}}, "x"))});
 
@@ -618,10 +620,10 @@
 }
 
 TEST_F(ResolverFunctionValidationTest, WorkgroupSize_NonConst) {
-    // var<private> x = 0;
+    // var<private> x = 64i;
     // @stage(compute) @workgroup_size(x)
     // fn main() {}
-    Global("x", ty.i32(), ast::StorageClass::kPrivate, Expr(64));
+    Global("x", ty.i32(), ast::StorageClass::kPrivate, Expr(64_i));
     Func("main", {}, ty.void_(), {},
          {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Expr(Source{{12, 34}}, "x"))});
 
@@ -636,7 +638,7 @@
     // fn main() {}
     Func("main", {}, ty.void_(), {},
          {Stage(ast::PipelineStage::kCompute),
-          WorkgroupSize(Construct(Source{{12, 34}}, ty.i32(), 1))});
+          WorkgroupSize(Construct(Source{{12, 34}}, ty.i32(), 1_i))});
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -661,7 +663,7 @@
 }
 
 TEST_F(ResolverFunctionValidationTest, ReturnIsConstructible_ArrayOfAtomic) {
-    auto* ret_type = ty.array(Source{{12, 34}}, ty.atomic(ty.i32()), 10);
+    auto* ret_type = ty.array(Source{{12, 34}}, ty.atomic(ty.i32()), 10_u);
     Func("f", {}, ret_type, {});
 
     EXPECT_FALSE(r()->Resolve());
diff --git a/src/tint/resolver/increment_decrement_validation_test.cc b/src/tint/resolver/increment_decrement_validation_test.cc
index e6f760b..37033c5 100644
--- a/src/tint/resolver/increment_decrement_validation_test.cc
+++ b/src/tint/resolver/increment_decrement_validation_test.cc
@@ -17,6 +17,8 @@
 #include "gmock/gmock.h"
 #include "src/tint/resolver/resolver_test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -25,7 +27,7 @@
 TEST_F(ResolverIncrementDecrementValidationTest, Increment_Signed) {
     // var a : i32 = 2;
     // a++;
-    auto* var = Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2));
+    auto* var = Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2_i));
     WrapInFunction(var, Increment(Source{{12, 34}}, "a"));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -34,7 +36,7 @@
 TEST_F(ResolverIncrementDecrementValidationTest, Decrement_Signed) {
     // var a : i32 = 2;
     // a--;
-    auto* var = Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2));
+    auto* var = Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2_i));
     WrapInFunction(var, Decrement(Source{{12, 34}}, "a"));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -43,7 +45,7 @@
 TEST_F(ResolverIncrementDecrementValidationTest, Increment_Unsigned) {
     // var a : u32 = 2u;
     // a++;
-    auto* var = Var("a", ty.u32(), ast::StorageClass::kNone, Expr(2u));
+    auto* var = Var("a", ty.u32(), ast::StorageClass::kNone, Expr(2_u));
     WrapInFunction(var, Increment(Source{{12, 34}}, "a"));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -52,7 +54,7 @@
 TEST_F(ResolverIncrementDecrementValidationTest, Decrement_Unsigned) {
     // var a : u32 = 2u;
     // a--;
-    auto* var = Var("a", ty.u32(), ast::StorageClass::kNone, Expr(2u));
+    auto* var = Var("a", ty.u32(), ast::StorageClass::kNone, Expr(2_u));
     WrapInFunction(var, Decrement(Source{{12, 34}}, "a"));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -63,26 +65,26 @@
     // let b : ptr<function,i32> = &a;
     // *b++;
     auto* var_a = Var("a", ty.i32(), ast::StorageClass::kFunction);
-    auto* var_b = Let("b", ty.pointer<int>(ast::StorageClass::kFunction), AddressOf(Expr("a")));
+    auto* var_b = Let("b", ty.pointer<i32>(ast::StorageClass::kFunction), AddressOf(Expr("a")));
     WrapInFunction(var_a, var_b, Increment(Source{{12, 34}}, Deref("b")));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverIncrementDecrementValidationTest, ThroughArray) {
-    // var a : array<i32, 4>;
-    // a[1]++;
-    auto* var_a = Var("a", ty.array(ty.i32(), 4), ast::StorageClass::kNone);
-    WrapInFunction(var_a, Increment(Source{{12, 34}}, IndexAccessor("a", 1)));
+    // var a : array<i32, 4_u>;
+    // a[1i]++;
+    auto* var_a = Var("a", ty.array(ty.i32(), 4_u), ast::StorageClass::kNone);
+    WrapInFunction(var_a, Increment(Source{{12, 34}}, IndexAccessor("a", 1_i)));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverIncrementDecrementValidationTest, ThroughVector_Index) {
     // var a : vec4<i32>;
-    // a.y++;
+    // a[1i]++;
     auto* var_a = Var("a", ty.vec4(ty.i32()), ast::StorageClass::kNone);
-    WrapInFunction(var_a, Increment(Source{{12, 34}}, IndexAccessor("a", 1)));
+    WrapInFunction(var_a, Increment(Source{{12, 34}}, IndexAccessor("a", 1_i)));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -136,7 +138,7 @@
 
 TEST_F(ResolverIncrementDecrementValidationTest, Literal) {
     // 1++;
-    WrapInFunction(Increment(Expr(Source{{56, 78}}, 1)));
+    WrapInFunction(Increment(Expr(Source{{56, 78}}, 1_i)));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "56:78 error: cannot modify value of type 'i32'");
@@ -145,7 +147,7 @@
 TEST_F(ResolverIncrementDecrementValidationTest, Constant) {
     // let a = 1;
     // a++;
-    auto* a = Let(Source{{12, 34}}, "a", nullptr, Expr(1));
+    auto* a = Let(Source{{12, 34}}, "a", nullptr, Expr(1_i));
     WrapInFunction(a, Increment(Expr(Source{{56, 78}}, "a")));
 
     EXPECT_FALSE(r()->Resolve());
@@ -173,7 +175,7 @@
     // {
     //   a++;
     // }
-    Func("func", {}, ty.i32(), {Return(0)});
+    Func("func", {}, ty.i32(), {Return(0_i)});
     WrapInFunction(Increment(Call(Source{{56, 78}}, "func")));
 
     EXPECT_FALSE(r()->Resolve());
@@ -205,7 +207,7 @@
     // for (a++; ; ) {
     //   break;
     // }
-    auto* a = Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2));
+    auto* a = Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2_i));
     auto* loop = For(Increment(Source{{56, 78}}, "a"), nullptr, nullptr, Block(Break()));
     WrapInFunction(a, loop);
 
@@ -217,7 +219,7 @@
     // for (; ; a++) {
     //   break;
     // }
-    auto* a = Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2));
+    auto* a = Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2_i));
     auto* loop = For(nullptr, nullptr, Increment(Source{{56, 78}}, "a"), Block(Break()));
     WrapInFunction(a, loop);
 
diff --git a/src/tint/resolver/inferred_type_test.cc b/src/tint/resolver/inferred_type_test.cc
index bafdd80..d8cc649 100644
--- a/src/tint/resolver/inferred_type_test.cc
+++ b/src/tint/resolver/inferred_type_test.cc
@@ -17,6 +17,8 @@
 
 #include "gmock/gmock.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -37,9 +39,6 @@
 using mat4x4 = builder::mat4x4<T>;
 template <typename T>
 using alias = builder::alias<T>;
-using f32 = builder::f32;
-using i32 = builder::i32;
-using u32 = builder::u32;
 
 struct ResolverInferredTypeTest : public resolver::TestHelper, public testing::Test {};
 
@@ -133,7 +132,7 @@
 INSTANTIATE_TEST_SUITE_P(ResolverTest, ResolverInferredTypeParamTest, testing::ValuesIn(all_cases));
 
 TEST_F(ResolverInferredTypeTest, InferArray_Pass) {
-    auto* type = ty.array(ty.u32(), 10);
+    auto* type = ty.array(ty.u32(), 10_u);
     auto* expected_type = create<sem::Array>(create<sem::U32>(), 10u, 4u, 4u * 10u, 4u, 4u);
 
     auto* ctor_expr = Construct(type);
diff --git a/src/tint/resolver/ptr_ref_validation_test.cc b/src/tint/resolver/ptr_ref_validation_test.cc
index 328b35d..b011dd0 100644
--- a/src/tint/resolver/ptr_ref_validation_test.cc
+++ b/src/tint/resolver/ptr_ref_validation_test.cc
@@ -19,6 +19,8 @@
 
 #include "gmock/gmock.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -27,7 +29,7 @@
 TEST_F(ResolverPtrRefValidationTest, AddressOfLiteral) {
     // &1
 
-    auto* expr = AddressOf(Expr(Source{{12, 34}}, 1));
+    auto* expr = AddressOf(Expr(Source{{12, 34}}, 1_i));
 
     WrapInFunction(expr);
 
@@ -39,7 +41,7 @@
 TEST_F(ResolverPtrRefValidationTest, AddressOfLet) {
     // let l : i32 = 1;
     // &l
-    auto* l = Let("l", ty.i32(), Expr(1));
+    auto* l = Let("l", ty.i32(), Expr(1_i));
     auto* expr = AddressOf(Expr(Source{{12, 34}}, "l"));
 
     WrapInFunction(l, expr);
@@ -77,9 +79,9 @@
 
 TEST_F(ResolverPtrRefValidationTest, AddressOfVectorComponent_IndexAccessor) {
     // var v : vec4<i32>;
-    // &v[2]
+    // &v[2i]
     auto* v = Var("v", ty.vec4<i32>());
-    auto* expr = AddressOf(IndexAccessor(Source{{12, 34}}, "v", 2));
+    auto* expr = AddressOf(IndexAccessor(Source{{12, 34}}, "v", 2_i));
 
     WrapInFunction(v, expr);
 
@@ -104,7 +106,7 @@
 TEST_F(ResolverPtrRefValidationTest, DerefOfLiteral) {
     // *1
 
-    auto* expr = Deref(Expr(Source{{12, 34}}, 1));
+    auto* expr = Deref(Expr(Source{{12, 34}}, 1_i));
 
     WrapInFunction(expr);
 
@@ -114,8 +116,8 @@
 }
 
 TEST_F(ResolverPtrRefValidationTest, DerefOfVar) {
-    // var v : i32 = 1;
-    // *1
+    // var v : i32;
+    // *v
     auto* v = Var("v", ty.i32());
     auto* expr = Deref(Expr(Source{{12, 34}}, "v"));
 
@@ -128,14 +130,14 @@
 
 TEST_F(ResolverPtrRefValidationTest, InferredPtrAccessMismatch) {
     // struct Inner {
-    //    arr: array<i32, 4>;
+    //    arr: array<i32, 4u>;
     // }
     // struct S {
     //    inner: Inner;
     // }
     // @group(0) @binding(0) var<storage, read_write> s : S;
     // fn f() {
-    //   let p : pointer<storage, i32> = &s.inner.arr[2];
+    //   let p : pointer<storage, i32> = &s.inner.arr[2i];
     // }
     auto* inner = Structure("Inner", {Member("arr", ty.array<i32, 4>())});
     auto* buf = Structure("S", {Member("inner", ty.Of(inner))});
@@ -145,7 +147,7 @@
                                create<ast::GroupAttribute>(0),
                            });
 
-    auto* expr = IndexAccessor(MemberAccessor(MemberAccessor(storage, "inner"), "arr"), 4);
+    auto* expr = IndexAccessor(MemberAccessor(MemberAccessor(storage, "inner"), "arr"), 2_i);
     auto* ptr =
         Let(Source{{12, 34}}, "p", ty.pointer<i32>(ast::StorageClass::kStorage), AddressOf(expr));
 
diff --git a/src/tint/resolver/resolver_behavior_test.cc b/src/tint/resolver/resolver_behavior_test.cc
index 03729c5..9cb26dc 100644
--- a/src/tint/resolver/resolver_behavior_test.cc
+++ b/src/tint/resolver/resolver_behavior_test.cc
@@ -20,6 +20,8 @@
 #include "src/tint/sem/for_loop_statement.h"
 #include "src/tint/sem/if_statement.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -32,13 +34,13 @@
         Func("DiscardOrNext", {}, ty.i32(),
              {
                  If(true, Block(Discard())),
-                 Return(1),
+                 Return(1_i),
              });
     }
 };
 
 TEST_F(ResolverBehaviorTest, ExprBinaryOp_LHS) {
-    auto* stmt = Decl(Var("lhs", ty.i32(), Add(Call("DiscardOrNext"), 1)));
+    auto* stmt = Decl(Var("lhs", ty.i32(), Add(Call("DiscardOrNext"), 1_i)));
     WrapInFunction(stmt);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -48,7 +50,7 @@
 }
 
 TEST_F(ResolverBehaviorTest, ExprBinaryOp_RHS) {
-    auto* stmt = Decl(Var("lhs", ty.i32(), Add(1, Call("DiscardOrNext"))));
+    auto* stmt = Decl(Var("lhs", ty.i32(), Add(1_i, Call("DiscardOrNext"))));
     WrapInFunction(stmt);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -74,7 +76,7 @@
              Return(Construct(ty.array<i32, 4>())),
          });
 
-    auto* stmt = Decl(Var("lhs", ty.i32(), IndexAccessor(Call("ArrayDiscardOrNext"), 1)));
+    auto* stmt = Decl(Var("lhs", ty.i32(), IndexAccessor(Call("ArrayDiscardOrNext"), 1_i)));
     WrapInFunction(stmt);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -119,7 +121,7 @@
 }
 
 TEST_F(ResolverBehaviorTest, StmtAssign_LHSDiscardOrNext) {
-    auto* stmt = Assign(IndexAccessor("lhs", Call("DiscardOrNext")), 1);
+    auto* stmt = Assign(IndexAccessor("lhs", Call("DiscardOrNext")), 1_i);
     WrapInFunction(Decl(Var("lhs", ty.array<i32, 4>())),  //
                    stmt);
 
@@ -302,7 +304,7 @@
 }
 
 TEST_F(ResolverBehaviorTest, StmtForLoopEmpty_CondCallFuncMayDiscard) {
-    auto* stmt = For(nullptr, Equal(Call("DiscardOrNext"), 1), nullptr, Block());
+    auto* stmt = For(nullptr, Equal(Call("DiscardOrNext"), 1_i), nullptr, Block());
     WrapInFunction(stmt);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -352,7 +354,7 @@
 }
 
 TEST_F(ResolverBehaviorTest, StmtIfCallFuncMayDiscard_ThenEmptyBlock) {
-    auto* stmt = If(Equal(Call("DiscardOrNext"), 1), Block());
+    auto* stmt = If(Equal(Call("DiscardOrNext"), 1_i), Block());
     WrapInFunction(stmt);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -363,7 +365,7 @@
 
 TEST_F(ResolverBehaviorTest, StmtIfTrue_ThenEmptyBlock_ElseCallFuncMayDiscard) {
     auto* stmt = If(true, Block(),  //
-                    Else(If(Equal(Call("DiscardOrNext"), 1), Block())));
+                    Else(If(Equal(Call("DiscardOrNext"), 1_i), Block())));
     WrapInFunction(stmt);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -373,7 +375,7 @@
 }
 
 TEST_F(ResolverBehaviorTest, StmtLetDecl) {
-    auto* stmt = Decl(Let("v", ty.i32(), Expr(1)));
+    auto* stmt = Decl(Let("v", ty.i32(), Expr(1_i)));
     WrapInFunction(stmt);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -477,7 +479,7 @@
 }
 
 TEST_F(ResolverBehaviorTest, StmtSwitch_CondTrue_DefaultEmpty) {
-    auto* stmt = Switch(1, DefaultCase(Block()));
+    auto* stmt = Switch(1_i, DefaultCase(Block()));
     WrapInFunction(stmt);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -487,7 +489,7 @@
 }
 
 TEST_F(ResolverBehaviorTest, StmtSwitch_CondLiteral_DefaultEmpty) {
-    auto* stmt = Switch(1, DefaultCase(Block()));
+    auto* stmt = Switch(1_i, DefaultCase(Block()));
     WrapInFunction(stmt);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -497,7 +499,7 @@
 }
 
 TEST_F(ResolverBehaviorTest, StmtSwitch_CondLiteral_DefaultDiscard) {
-    auto* stmt = Switch(1, DefaultCase(Block(Discard())));
+    auto* stmt = Switch(1_i, DefaultCase(Block(Discard())));
     WrapInFunction(stmt);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -507,7 +509,7 @@
 }
 
 TEST_F(ResolverBehaviorTest, StmtSwitch_CondLiteral_DefaultReturn) {
-    auto* stmt = Switch(1, DefaultCase(Block(Return())));
+    auto* stmt = Switch(1_i, DefaultCase(Block(Return())));
     WrapInFunction(stmt);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -517,7 +519,7 @@
 }
 
 TEST_F(ResolverBehaviorTest, StmtSwitch_CondLiteral_Case0Empty_DefaultEmpty) {
-    auto* stmt = Switch(1, Case(Expr(0), Block()), DefaultCase(Block()));
+    auto* stmt = Switch(1_i, Case(Expr(0_i), Block()), DefaultCase(Block()));
     WrapInFunction(stmt);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -527,7 +529,7 @@
 }
 
 TEST_F(ResolverBehaviorTest, StmtSwitch_CondLiteral_Case0Empty_DefaultDiscard) {
-    auto* stmt = Switch(1, Case(Expr(0), Block()), DefaultCase(Block(Discard())));
+    auto* stmt = Switch(1_i, Case(Expr(0_i), Block()), DefaultCase(Block(Discard())));
     WrapInFunction(stmt);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -537,7 +539,7 @@
 }
 
 TEST_F(ResolverBehaviorTest, StmtSwitch_CondLiteral_Case0Empty_DefaultReturn) {
-    auto* stmt = Switch(1, Case(Expr(0), Block()), DefaultCase(Block(Return())));
+    auto* stmt = Switch(1_i, Case(Expr(0_i), Block()), DefaultCase(Block(Return())));
     WrapInFunction(stmt);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -547,7 +549,7 @@
 }
 
 TEST_F(ResolverBehaviorTest, StmtSwitch_CondLiteral_Case0Discard_DefaultEmpty) {
-    auto* stmt = Switch(1, Case(Expr(0), Block(Discard())), DefaultCase(Block()));
+    auto* stmt = Switch(1_i, Case(Expr(0_i), Block(Discard())), DefaultCase(Block()));
     WrapInFunction(stmt);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -557,7 +559,7 @@
 }
 
 TEST_F(ResolverBehaviorTest, StmtSwitch_CondLiteral_Case0Discard_DefaultDiscard) {
-    auto* stmt = Switch(1, Case(Expr(0), Block(Discard())), DefaultCase(Block(Discard())));
+    auto* stmt = Switch(1_i, Case(Expr(0_i), Block(Discard())), DefaultCase(Block(Discard())));
     WrapInFunction(stmt);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -567,7 +569,7 @@
 }
 
 TEST_F(ResolverBehaviorTest, StmtSwitch_CondLiteral_Case0Discard_DefaultReturn) {
-    auto* stmt = Switch(1, Case(Expr(0), Block(Discard())), DefaultCase(Block(Return())));
+    auto* stmt = Switch(1_i, Case(Expr(0_i), Block(Discard())), DefaultCase(Block(Return())));
     WrapInFunction(stmt);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -577,9 +579,9 @@
 }
 
 TEST_F(ResolverBehaviorTest, StmtSwitch_CondLiteral_Case0Discard_Case1Return_DefaultEmpty) {
-    auto* stmt = Switch(1,                                //
-                        Case(Expr(0), Block(Discard())),  //
-                        Case(Expr(1), Block(Return())),   //
+    auto* stmt = Switch(1_i,                                //
+                        Case(Expr(0_i), Block(Discard())),  //
+                        Case(Expr(1_i), Block(Return())),   //
                         DefaultCase(Block()));
     WrapInFunction(stmt);
 
diff --git a/src/tint/resolver/resolver_constants.cc b/src/tint/resolver/resolver_constants.cc
index 69ee798..f5346d1 100644
--- a/src/tint/resolver/resolver_constants.cc
+++ b/src/tint/resolver/resolver_constants.cc
@@ -18,14 +18,9 @@
 #include "src/tint/sem/type_constructor.h"
 #include "src/tint/utils/map.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
-namespace {
-
-using i32 = ProgramBuilder::i32;
-using u32 = ProgramBuilder::u32;
-using f32 = ProgramBuilder::f32;
-
-}  // namespace
 
 sem::Constant Resolver::EvaluateConstantValue(const ast::Expression* expr, const sem::Type* type) {
     if (auto* e = expr->As<ast::LiteralExpression>()) {
@@ -43,9 +38,9 @@
         literal,
         [&](const ast::IntLiteralExpression* lit) {
             if (lit->suffix == ast::IntLiteralExpression::Suffix::kU) {
-                return sem::Constant{type, {static_cast<uint32_t>(lit->value)}};
+                return sem::Constant{type, {u32(static_cast<uint32_t>(lit->value))}};
             }
-            return sem::Constant{type, {static_cast<int32_t>(lit->value)}};
+            return sem::Constant{type, {i32(static_cast<int32_t>(lit->value))}};
         },
         [&](const ast::FloatLiteralExpression* lit) {
             return sem::Constant{type, {lit->value}};
@@ -70,10 +65,10 @@
     // For zero value init, return 0s
     if (call->args.empty()) {
         if (elem_type->Is<sem::I32>()) {
-            return sem::Constant(type, sem::Constant::Scalars(result_size, 0));
+            return sem::Constant(type, sem::Constant::Scalars(result_size, 0_i));
         }
         if (elem_type->Is<sem::U32>()) {
-            return sem::Constant(type, sem::Constant::Scalars(result_size, 0u));
+            return sem::Constant(type, sem::Constant::Scalars(result_size, 0_u));
         }
         if (elem_type->Is<sem::F32>()) {
             return sem::Constant(type, sem::Constant::Scalars(result_size, 0.f));
@@ -113,16 +108,34 @@
 
     sem::Constant::Scalars elems;
     for (size_t i = 0; i < value.Elements().size(); ++i) {
-        if (target_elem_type->Is<sem::I32>()) {
-            elems.emplace_back(value.WithScalarAt(i, [](auto&& s) { return static_cast<i32>(s); }));
-        } else if (target_elem_type->Is<sem::U32>()) {
-            elems.emplace_back(value.WithScalarAt(i, [](auto&& s) { return static_cast<u32>(s); }));
-        } else if (target_elem_type->Is<sem::F32>()) {
-            elems.emplace_back(value.WithScalarAt(i, [](auto&& s) { return static_cast<f32>(s); }));
-        } else if (target_elem_type->Is<sem::Bool>()) {
-            elems.emplace_back(
-                value.WithScalarAt(i, [](auto&& s) { return static_cast<bool>(s); }));
-        }
+        elems.emplace_back(Switch<sem::Constant::Scalar>(
+            target_elem_type,
+            [&](const sem::I32*) {
+                return value.WithScalarAt(i, [](auto&& s) {  //
+                    return i32(static_cast<int32_t>(s));
+                });
+            },
+            [&](const sem::U32*) {
+                return value.WithScalarAt(i, [](auto&& s) {  //
+                    return u32(static_cast<uint32_t>(s));
+                });
+            },
+            [&](const sem::F32*) {
+                return value.WithScalarAt(i, [](auto&& s) {  //
+                    return static_cast<f32>(s);
+                });
+            },
+            [&](const sem::Bool*) {
+                return value.WithScalarAt(i, [](auto&& s) {  //
+                    return static_cast<bool>(s);
+                });
+            },
+            [&](Default) {
+                diag::List diags;
+                TINT_UNREACHABLE(Semantic, diags)
+                    << "invalid element type " << target_elem_type->TypeInfo().name;
+                return sem::Constant::Scalar(false);
+            }));
     }
 
     auto* target_type =
diff --git a/src/tint/resolver/resolver_constants_test.cc b/src/tint/resolver/resolver_constants_test.cc
index ceb0822..798de0a 100644
--- a/src/tint/resolver/resolver_constants_test.cc
+++ b/src/tint/resolver/resolver_constants_test.cc
@@ -18,6 +18,8 @@
 #include "src/tint/resolver/resolver_test_helper.h"
 #include "src/tint/sem/expression.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -26,7 +28,7 @@
 using ResolverConstantsTest = ResolverTest;
 
 TEST_F(ResolverConstantsTest, Scalar_i32) {
-    auto* expr = Expr(99);
+    auto* expr = Expr(99_i);
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -41,7 +43,7 @@
 }
 
 TEST_F(ResolverConstantsTest, Scalar_u32) {
-    auto* expr = Expr(99u);
+    auto* expr = Expr(99_u);
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -162,7 +164,7 @@
 }
 
 TEST_F(ResolverConstantsTest, Vec3_Splat_i32) {
-    auto* expr = vec3<i32>(99);
+    auto* expr = vec3<i32>(99_i);
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -181,7 +183,7 @@
 }
 
 TEST_F(ResolverConstantsTest, Vec3_Splat_u32) {
-    auto* expr = vec3<u32>(99u);
+    auto* expr = vec3<u32>(99_u);
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -238,7 +240,7 @@
 }
 
 TEST_F(ResolverConstantsTest, Vec3_FullConstruct_i32) {
-    auto* expr = vec3<i32>(1, 2, 3);
+    auto* expr = vec3<i32>(1_i, 2_i, 3_i);
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -257,7 +259,7 @@
 }
 
 TEST_F(ResolverConstantsTest, Vec3_FullConstruct_u32) {
-    auto* expr = vec3<u32>(1u, 2u, 3u);
+    auto* expr = vec3<u32>(1_u, 2_u, 3_u);
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -314,7 +316,7 @@
 }
 
 TEST_F(ResolverConstantsTest, Vec3_MixConstruct_i32) {
-    auto* expr = vec3<i32>(1, vec2<i32>(2, 3));
+    auto* expr = vec3<i32>(1_i, vec2<i32>(2_i, 3_i));
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -333,7 +335,7 @@
 }
 
 TEST_F(ResolverConstantsTest, Vec3_MixConstruct_u32) {
-    auto* expr = vec3<u32>(vec2<u32>(1u, 2u), 3u);
+    auto* expr = vec3<u32>(vec2<u32>(1_u, 2_u), 3_u);
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -409,7 +411,7 @@
 }
 
 TEST_F(ResolverConstantsTest, Vec3_Cast_u32_to_f32) {
-    auto* expr = vec3<f32>(vec3<u32>(10u, 20u, 30u));
+    auto* expr = vec3<f32>(vec3<u32>(10_u, 20_u, 30_u));
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
diff --git a/src/tint/resolver/resolver_test.cc b/src/tint/resolver/resolver_test.cc
index 45b5694..f9055fd 100644
--- a/src/tint/resolver/resolver_test.cc
+++ b/src/tint/resolver/resolver_test.cc
@@ -47,6 +47,8 @@
 using ::testing::ElementsAre;
 using ::testing::HasSubstr;
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -81,9 +83,6 @@
 using alias2 = builder::alias2<T>;
 template <typename T>
 using alias3 = builder::alias3<T>;
-using f32 = builder::f32;
-using i32 = builder::i32;
-using u32 = builder::u32;
 using Op = ast::BinaryOp;
 
 TEST_F(ResolverTest, Stmt_Assign) {
@@ -113,7 +112,7 @@
     auto* assign = Assign(lhs, rhs);
     auto* block = Block(assign);
     ast::CaseSelectorList lit;
-    lit.push_back(Expr(3));
+    lit.push_back(Expr(3_i));
     auto* cse = create<ast::CaseStatement>(lit, block);
     auto* cond_var = Var("c", ty.i32());
     auto* sw = Switch(cond_var, cse, DefaultCase());
@@ -223,7 +222,7 @@
 }
 
 TEST_F(ResolverTest, Stmt_Return) {
-    auto* cond = Expr(2);
+    auto* cond = Expr(2_i);
 
     auto* ret = Return(cond);
     Func("test", {}, ty.i32(), {ret}, {});
@@ -246,7 +245,7 @@
     auto* lhs = Expr("v");
     auto* rhs = Expr(2.3f);
     auto* case_block = Block(Assign(lhs, rhs));
-    auto* stmt = Switch(Expr(2), Case(Expr(3), case_block), DefaultCase());
+    auto* stmt = Switch(Expr(2_i), Case(Expr(3_i), case_block), DefaultCase());
     WrapInFunction(v, stmt);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -279,7 +278,7 @@
 }
 
 TEST_F(ResolverTest, Stmt_VariableDecl) {
-    auto* var = Var("my_var", ty.i32(), ast::StorageClass::kNone, Expr(2));
+    auto* var = Var("my_var", ty.i32(), ast::StorageClass::kNone, Expr(2_i));
     auto* init = var->constructor;
 
     auto* decl = Decl(var);
@@ -293,7 +292,7 @@
 
 TEST_F(ResolverTest, Stmt_VariableDecl_Alias) {
     auto* my_int = Alias("MyInt", ty.i32());
-    auto* var = Var("my_var", ty.Of(my_int), ast::StorageClass::kNone, Expr(2));
+    auto* var = Var("my_var", ty.Of(my_int), ast::StorageClass::kNone, Expr(2_i));
     auto* init = var->constructor;
 
     auto* decl = Decl(var);
@@ -306,7 +305,7 @@
 }
 
 TEST_F(ResolverTest, Stmt_VariableDecl_ModuleScope) {
-    auto* init = Expr(2);
+    auto* init = Expr(2_i);
     Global("my_var", ty.i32(), ast::StorageClass::kPrivate, init);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -329,7 +328,7 @@
     ast::VariableList params;
 
     // Declare i32 "foo" inside a block
-    auto* foo_i32 = Var("foo", ty.i32(), ast::StorageClass::kNone, Expr(2));
+    auto* foo_i32 = Var("foo", ty.i32(), ast::StorageClass::kNone, Expr(2_i));
     auto* foo_i32_init = foo_i32->constructor;
     auto* foo_i32_decl = Decl(foo_i32);
 
@@ -385,7 +384,7 @@
     ast::VariableList params;
 
     // Declare i32 "foo" inside a function
-    auto* fn_i32 = Var("foo", ty.i32(), ast::StorageClass::kNone, Expr(2));
+    auto* fn_i32 = Var("foo", ty.i32(), ast::StorageClass::kNone, Expr(2_i));
     auto* fn_i32_init = fn_i32->constructor;
     auto* fn_i32_decl = Decl(fn_i32);
     Func("func_i32", params, ty.void_(), {fn_i32_decl}, ast::AttributeList{});
@@ -419,7 +418,7 @@
 
 TEST_F(ResolverTest, ArraySize_UnsignedLiteral) {
     // var<private> a : array<f32, 10u>;
-    auto* a = Global("a", ty.array(ty.f32(), Expr(10u)), ast::StorageClass::kPrivate);
+    auto* a = Global("a", ty.array(ty.f32(), Expr(10_u)), ast::StorageClass::kPrivate);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
@@ -431,8 +430,8 @@
 }
 
 TEST_F(ResolverTest, ArraySize_SignedLiteral) {
-    // var<private> a : array<f32, 10>;
-    auto* a = Global("a", ty.array(ty.f32(), Expr(10)), ast::StorageClass::kPrivate);
+    // var<private> a : array<f32, 10i>;
+    auto* a = Global("a", ty.array(ty.f32(), Expr(10_i)), ast::StorageClass::kPrivate);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
@@ -445,8 +444,8 @@
 
 TEST_F(ResolverTest, ArraySize_UnsignedConstant) {
     // let size = 0u;
-    // var<private> a : array<f32, 10u>;
-    GlobalConst("size", nullptr, Expr(10u));
+    // var<private> a : array<f32, size>;
+    GlobalConst("size", nullptr, Expr(10_u));
     auto* a = Global("a", ty.array(ty.f32(), Expr("size")), ast::StorageClass::kPrivate);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -460,8 +459,8 @@
 
 TEST_F(ResolverTest, ArraySize_SignedConstant) {
     // let size = 0;
-    // var<private> a : array<f32, 10>;
-    GlobalConst("size", nullptr, Expr(10));
+    // var<private> a : array<f32, size>;
+    GlobalConst("size", nullptr, Expr(10_i));
     auto* a = Global("a", ty.array(ty.f32(), Expr("size")), ast::StorageClass::kPrivate);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -650,7 +649,7 @@
 }
 
 TEST_F(ResolverTest, IndexAccessor_Dynamic_Ref_F32) {
-    // var a : array<bool, 10> = 0;
+    // var a : array<bool, 10u> = 0;
     // var idx : f32 = f32();
     // var f : f32 = a[idx];
     auto* a = Var("a", ty.array<bool, 10>(), array<bool, 10>());
@@ -926,7 +925,7 @@
     // @stage(compute) @workgroup_size(8, 2, 3)
     // fn main() {}
     auto* func = Func("main", ast::VariableList{}, ty.void_(), {},
-                      {Stage(ast::PipelineStage::kCompute), WorkgroupSize(8, 2, 3)});
+                      {Stage(ast::PipelineStage::kCompute), WorkgroupSize(8_i, 2_i, 3_i)});
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
@@ -942,14 +941,14 @@
 }
 
 TEST_F(ResolverTest, Function_WorkgroupSize_Consts) {
-    // let width = 16;
-    // let height = 8;
-    // let depth = 2;
+    // let width = 16i;
+    // let height = 8i;
+    // let depth = 2i;
     // @stage(compute) @workgroup_size(width, height, depth)
     // fn main() {}
-    GlobalConst("width", ty.i32(), Expr(16));
-    GlobalConst("height", ty.i32(), Expr(8));
-    GlobalConst("depth", ty.i32(), Expr(2));
+    GlobalConst("width", ty.i32(), Expr(16_i));
+    GlobalConst("height", ty.i32(), Expr(8_i));
+    GlobalConst("depth", ty.i32(), Expr(2_i));
     auto* func =
         Func("main", ast::VariableList{}, ty.void_(), {},
              {Stage(ast::PipelineStage::kCompute), WorkgroupSize("width", "height", "depth")});
@@ -968,14 +967,14 @@
 }
 
 TEST_F(ResolverTest, Function_WorkgroupSize_Consts_NestedInitializer) {
-    // let width = i32(i32(i32(8)));
-    // let height = i32(i32(i32(4)));
+    // let width = i32(i32(i32(8i)));
+    // let height = i32(i32(i32(4i)));
     // @stage(compute) @workgroup_size(width, height)
     // fn main() {}
     GlobalConst("width", ty.i32(),
-                Construct(ty.i32(), Construct(ty.i32(), Construct(ty.i32(), 8))));
+                Construct(ty.i32(), Construct(ty.i32(), Construct(ty.i32(), 8_i))));
     GlobalConst("height", ty.i32(),
-                Construct(ty.i32(), Construct(ty.i32(), Construct(ty.i32(), 4))));
+                Construct(ty.i32(), Construct(ty.i32(), Construct(ty.i32(), 4_i))));
     auto* func = Func("main", ast::VariableList{}, ty.void_(), {},
                       {Stage(ast::PipelineStage::kCompute), WorkgroupSize("width", "height")});
 
@@ -993,14 +992,14 @@
 }
 
 TEST_F(ResolverTest, Function_WorkgroupSize_OverridableConsts) {
-    // @id(0) override width = 16;
-    // @id(1) override height = 8;
-    // @id(2) override depth = 2;
+    // @id(0) override width = 16i;
+    // @id(1) override height = 8i;
+    // @id(2) override depth = 2i;
     // @stage(compute) @workgroup_size(width, height, depth)
     // fn main() {}
-    auto* width = Override("width", ty.i32(), Expr(16), {Id(0)});
-    auto* height = Override("height", ty.i32(), Expr(8), {Id(1)});
-    auto* depth = Override("depth", ty.i32(), Expr(2), {Id(2)});
+    auto* width = Override("width", ty.i32(), Expr(16_i), {Id(0)});
+    auto* height = Override("height", ty.i32(), Expr(8_i), {Id(1)});
+    auto* depth = Override("depth", ty.i32(), Expr(2_i), {Id(2)});
     auto* func =
         Func("main", ast::VariableList{}, ty.void_(), {},
              {Stage(ast::PipelineStage::kCompute), WorkgroupSize("width", "height", "depth")});
@@ -1045,14 +1044,14 @@
 }
 
 TEST_F(ResolverTest, Function_WorkgroupSize_Mixed) {
-    // @id(1) override height = 2;
-    // let depth = 3;
+    // @id(1) override height = 2i;
+    // let depth = 3i;
     // @stage(compute) @workgroup_size(8, height, depth)
     // fn main() {}
-    auto* height = Override("height", ty.i32(), Expr(2), {Id(0)});
-    GlobalConst("depth", ty.i32(), Expr(3));
+    auto* height = Override("height", ty.i32(), Expr(2_i), {Id(0)});
+    GlobalConst("depth", ty.i32(), Expr(3_i));
     auto* func = Func("main", ast::VariableList{}, ty.void_(), {},
-                      {Stage(ast::PipelineStage::kCompute), WorkgroupSize(8, "height", "depth")});
+                      {Stage(ast::PipelineStage::kCompute), WorkgroupSize(8_i, "height", "depth")});
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
@@ -1149,7 +1148,7 @@
     //   vec4<f32> foo
     // }
     // struct A {
-    //   array<b, 3> mem
+    //   array<b, 3u> mem
     // }
     // var c : A
     // c.mem[0].foo.yx
@@ -1161,11 +1160,11 @@
     //
 
     auto* stB = Structure("B", {Member("foo", ty.vec4<f32>())});
-    auto* stA = Structure("A", {Member("mem", ty.array(ty.Of(stB), 3))});
+    auto* stA = Structure("A", {Member("mem", ty.array(ty.Of(stB), 3_i))});
     Global("c", ty.Of(stA), ast::StorageClass::kPrivate);
 
     auto* mem =
-        MemberAccessor(MemberAccessor(IndexAccessor(MemberAccessor("c", "mem"), 0), "foo"), "yx");
+        MemberAccessor(MemberAccessor(IndexAccessor(MemberAccessor("c", "mem"), 0_i), "foo"), "yx");
     WrapInFunction(mem);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1820,13 +1819,13 @@
                           Assign("call_a", Call("a")),
                           Assign("call_b", Call("b")),
                       },
-                      ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+                      ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     auto* ep_2 = Func("ep_2", params, ty.void_(),
                       {
                           Assign("call_c", Call("c")),
                       },
-                      ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+                      ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 
@@ -1903,7 +1902,7 @@
              CallStmt(Call(fn_a(0))),
              CallStmt(Call(fn_b(0))),
          },
-         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -1930,7 +1929,7 @@
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b;
-            auto* expr = b.Expr(1);
+            auto* expr = b.Expr(1_i);
             b.Global("a", b.ty.i32(), ast::StorageClass::kPrivate, expr);
             b.Global("b", b.ty.i32(), ast::StorageClass::kPrivate, expr);
             Resolver(&b).Resolve();
diff --git a/src/tint/resolver/resolver_test_helper.h b/src/tint/resolver/resolver_test_helper.h
index e6dcf96..d54e57c 100644
--- a/src/tint/resolver/resolver_test_helper.h
+++ b/src/tint/resolver/resolver_test_helper.h
@@ -119,10 +119,6 @@
 
 namespace builder {
 
-using i32 = ProgramBuilder::i32;
-using u32 = ProgramBuilder::u32;
-using f32 = ProgramBuilder::f32;
-
 template <uint32_t N, typename T>
 struct vec {};
 
@@ -409,7 +405,7 @@
     /// @param b the ProgramBuilder
     /// @return a new AST array type
     static inline const ast::Type* AST(ProgramBuilder& b) {
-        return b.ty.array(DataType<T>::AST(b), N);
+        return b.ty.array(DataType<T>::AST(b), u32(N));
     }
     /// @param b the ProgramBuilder
     /// @return the semantic array type
diff --git a/src/tint/resolver/side_effects_test.cc b/src/tint/resolver/side_effects_test.cc
index 4057e6a..a50d904 100644
--- a/src/tint/resolver/side_effects_test.cc
+++ b/src/tint/resolver/side_effects_test.cc
@@ -19,6 +19,8 @@
 #include "src/tint/sem/expression.h"
 #include "src/tint/sem/member_accessor_expression.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -52,7 +54,7 @@
 
 TEST_F(SideEffectsTest, Phony) {
     auto* expr = Phony();
-    auto* body = Assign(expr, 1);
+    auto* body = Assign(expr, 1_i);
     WrapInFunction(body);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -62,7 +64,7 @@
 }
 
 TEST_F(SideEffectsTest, Literal) {
-    auto* expr = Expr(1);
+    auto* expr = Expr(1_i);
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -111,7 +113,7 @@
 
 TEST_F(SideEffectsTest, Call_Builtin_SE) {
     Global("a", ty.atomic(ty.i32()), ast::StorageClass::kWorkgroup);
-    auto* expr = Call("atomicAdd", AddressOf("a"), 1);
+    auto* expr = Call("atomicAdd", AddressOf("a"), 1_i);
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -122,7 +124,7 @@
 }
 
 TEST_F(SideEffectsTest, Call_Function) {
-    Func("f", {}, ty.i32(), {Return(1)});
+    Func("f", {}, ty.i32(), {Return(1_i)});
     auto* expr = Call("f");
     WrapInFunction(expr);
 
@@ -313,7 +315,7 @@
 
 TEST_F(SideEffectsTest, IndexAccessor_NoSE) {
     auto* var = Decl(Var("a", ty.array<i32, 10>()));
-    auto* expr = IndexAccessor("a", 0);
+    auto* expr = IndexAccessor("a", 0_i);
     WrapInFunction(var, expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -324,7 +326,7 @@
 
 TEST_F(SideEffectsTest, IndexAccessor_ObjSE) {
     MakeSideEffectFunc("se", [&] { return ty.array<i32, 10>(); });
-    auto* expr = IndexAccessor(Call("se"), 0);
+    auto* expr = IndexAccessor(Call("se"), 0_i);
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
diff --git a/src/tint/resolver/source_variable_test.cc b/src/tint/resolver/source_variable_test.cc
index 6d10f84..f9fe2fb 100644
--- a/src/tint/resolver/source_variable_test.cc
+++ b/src/tint/resolver/source_variable_test.cc
@@ -17,6 +17,8 @@
 #include "src/tint/resolver/resolver_test_helper.h"
 #include "src/tint/sem/member_accessor_expression.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -190,12 +192,12 @@
 }
 
 TEST_F(ResolverSourceVariableTest, ThroughIndexAccessor) {
-    // var<private> a : array<f32, 4>;
+    // var<private> a : array<f32, 4u>;
     // {
-    //   a[2]
+    //   a[2i]
     // }
-    auto* a = Global("a", ty.array(ty.f32(), 4), ast::StorageClass::kPrivate);
-    auto* expr = IndexAccessor(a, 2);
+    auto* a = Global("a", ty.array(ty.f32(), 4_u), ast::StorageClass::kPrivate);
+    auto* expr = IndexAccessor(a, 2_i);
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
diff --git a/src/tint/resolver/storage_class_layout_validation_test.cc b/src/tint/resolver/storage_class_layout_validation_test.cc
index e5f8a40..db379a0 100644
--- a/src/tint/resolver/storage_class_layout_validation_test.cc
+++ b/src/tint/resolver/storage_class_layout_validation_test.cc
@@ -17,6 +17,8 @@
 #include "gmock/gmock.h"
 #include "src/tint/resolver/resolver_test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -140,7 +142,7 @@
 
 // Detect unaligned array member for uniform buffers
 TEST_F(ResolverStorageClassLayoutValidationTest, UniformBuffer_UnalignedMember_Array) {
-    // type Inner = @stride(16) array<f32, 10>;
+    // type Inner = @stride(16) array<f32, 10u>;
     //
     // struct Outer {
     //   scalar : f32;
@@ -149,7 +151,7 @@
     //
     // @group(0) @binding(0)
     // var<uniform> a : Outer;
-    Alias("Inner", ty.array(ty.f32(), 10, 16));
+    Alias("Inner", ty.array(ty.f32(), 10_u, 16));
 
     Structure(Source{{12, 34}}, "Outer",
               {
@@ -173,7 +175,7 @@
 }
 
 TEST_F(ResolverStorageClassLayoutValidationTest, UniformBuffer_UnalignedMember_Array_SuggestedFix) {
-    // type Inner = @stride(16) array<f32, 10>;
+    // type Inner = @stride(16) array<f32, 10u>;
     //
     // struct Outer {
     //   scalar : f32;
@@ -182,7 +184,7 @@
     //
     // @group(0) @binding(0)
     // var<uniform> a : Outer;
-    Alias("Inner", ty.array(ty.f32(), 10, 16));
+    Alias("Inner", ty.array(ty.f32(), 10_u, 16));
 
     Structure(Source{{12, 34}}, "Outer",
               {
@@ -347,7 +349,7 @@
 
 // Detect array stride must be a multiple of 16 bytes for uniform buffers
 TEST_F(ResolverStorageClassLayoutValidationTest, UniformBuffer_InvalidArrayStride_Scalar) {
-    // type Inner = array<f32, 10>;
+    // type Inner = array<f32, 10u>;
     //
     // struct Outer {
     //   inner : Inner;
@@ -357,7 +359,7 @@
     // @group(0) @binding(0)
     // var<uniform> a : Outer;
 
-    Alias("Inner", ty.array(ty.f32(), 10));
+    Alias("Inner", ty.array(ty.f32(), 10_u));
 
     Structure(Source{{12, 34}}, "Outer",
               {
@@ -381,7 +383,7 @@
 }
 
 TEST_F(ResolverStorageClassLayoutValidationTest, UniformBuffer_InvalidArrayStride_Vector) {
-    // type Inner = array<vec2<f32>, 10>;
+    // type Inner = array<vec2<f32>, 10u>;
     //
     // struct Outer {
     //   inner : Inner;
@@ -391,7 +393,7 @@
     // @group(0) @binding(0)
     // var<uniform> a : Outer;
 
-    Alias("Inner", ty.array(ty.vec2<f32>(), 10));
+    Alias("Inner", ty.array(ty.vec2<f32>(), 10_u));
 
     Structure(Source{{12, 34}}, "Outer",
               {
@@ -420,7 +422,7 @@
     //   a : f32;
     //   b : i32;
     // }
-    // type Inner = array<ArrayElem, 10>;
+    // type Inner = array<ArrayElem, 10u>;
     //
     // struct Outer {
     //   inner : Inner;
@@ -434,7 +436,7 @@
                                                   Member("a", ty.f32()),
                                                   Member("b", ty.i32()),
                                               });
-    Alias("Inner", ty.array(ty.Of(array_elem), 10));
+    Alias("Inner", ty.array(ty.Of(array_elem), 10_u));
 
     Structure(Source{{12, 34}}, "Outer",
               {
@@ -459,8 +461,8 @@
 
 TEST_F(ResolverStorageClassLayoutValidationTest, UniformBuffer_InvalidArrayStride_TopLevelArray) {
     // @group(0) @binding(0)
-    // var<uniform> a : array<f32, 4>;
-    Global(Source{{78, 90}}, "a", ty.array(Source{{34, 56}}, ty.f32(), 4),
+    // var<uniform> a : array<f32, 4u>;
+    Global(Source{{78, 90}}, "a", ty.array(Source{{34, 56}}, ty.f32(), 4_u),
            ast::StorageClass::kUniform, GroupAndBinding(0, 0));
 
     ASSERT_FALSE(r()->Resolve());
@@ -471,15 +473,15 @@
 
 TEST_F(ResolverStorageClassLayoutValidationTest, UniformBuffer_InvalidArrayStride_NestedArray) {
     // struct Outer {
-    //   inner : array<array<f32, 4>, 4>
+    //   inner : array<array<f32, 4u>, 4u>
     // };
     //
     // @group(0) @binding(0)
-    // var<uniform> a : array<Outer, 4>;
+    // var<uniform> a : array<Outer, 4u>;
 
     Structure(Source{{12, 34}}, "Outer",
               {
-                  Member("inner", ty.array(Source{{34, 56}}, ty.array(ty.f32(), 4), 4)),
+                  Member("inner", ty.array(Source{{34, 56}}, ty.array(ty.f32(), 4_u), 4_u)),
               });
 
     Global(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform,
@@ -497,7 +499,7 @@
 }
 
 TEST_F(ResolverStorageClassLayoutValidationTest, UniformBuffer_InvalidArrayStride_SuggestedFix) {
-    // type Inner = @stride(16) array<f32, 10>;
+    // type Inner = @stride(16) array<f32, 10u>;
     //
     // struct Outer {
     //   inner : Inner;
@@ -507,7 +509,7 @@
     // @group(0) @binding(0)
     // var<uniform> a : Outer;
 
-    Alias("Inner", ty.array(ty.f32(), 10, 16));
+    Alias("Inner", ty.array(ty.f32(), 10_u, 16));
 
     Structure(Source{{12, 34}}, "Outer",
               {
diff --git a/src/tint/resolver/storage_class_validation_test.cc b/src/tint/resolver/storage_class_validation_test.cc
index ed4e6b8..2d75167 100644
--- a/src/tint/resolver/storage_class_validation_test.cc
+++ b/src/tint/resolver/storage_class_validation_test.cc
@@ -18,6 +18,8 @@
 #include "src/tint/resolver/resolver_test_helper.h"
 #include "src/tint/sem/struct.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -137,9 +139,9 @@
 }
 
 TEST_F(ResolverStorageClassValidationTest, StorageBufferArray) {
-    // var<storage, read> g : array<S, 3>;
+    // var<storage, read> g : array<S, 3u>;
     auto* s = Structure("S", {Member("a", ty.f32())});
-    auto* a = ty.array(ty.Of(s), 3);
+    auto* a = ty.array(ty.Of(s), 3_u);
     Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage, ast::Access::kRead,
            ast::AttributeList{
                create<ast::BindingAttribute>(0),
@@ -285,9 +287,9 @@
     // struct S {
     //   @size(16) f : f32;
     // }
-    // var<uniform> g : array<S, 3>;
+    // var<uniform> g : array<S, 3u>;
     auto* s = Structure("S", {Member("a", ty.f32(), {MemberSize(16)})});
-    auto* a = ty.array(ty.Of(s), 3);
+    auto* a = ty.array(ty.Of(s), 3_u);
     Global(Source{{56, 78}}, "g", a, ast::StorageClass::kUniform,
            ast::AttributeList{
                create<ast::BindingAttribute>(0),
diff --git a/src/tint/resolver/struct_layout_test.cc b/src/tint/resolver/struct_layout_test.cc
index 04b1389..854e87a 100644
--- a/src/tint/resolver/struct_layout_test.cc
+++ b/src/tint/resolver/struct_layout_test.cc
@@ -18,6 +18,8 @@
 #include "src/tint/resolver/resolver_test_helper.h"
 #include "src/tint/sem/struct.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -164,7 +166,7 @@
 
 TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayOfExplicitStrideArray) {
     auto* inner = ty.array<i32, 2>(/*stride*/ 16);  // size: 32
-    auto* outer = ty.array(inner, 12);              // size: 12 * 32
+    auto* outer = ty.array(inner, 12_u);            // size: 12 * 32
     auto* s = Structure("S", {
                                  Member("c", outer),
                              });
@@ -187,8 +189,8 @@
                                          Member("a", ty.vec2<i32>()),
                                          Member("b", ty.vec3<i32>()),
                                          Member("c", ty.vec4<i32>()),
-                                     });       // size: 48
-    auto* outer = ty.array(ty.Of(inner), 12);  // size: 12 * 48
+                                     });         // size: 48
+    auto* outer = ty.array(ty.Of(inner), 12_u);  // size: 12 * 48
     auto* s = Structure("S", {
                                  Member("c", outer),
                              });
diff --git a/src/tint/resolver/struct_pipeline_stage_use_test.cc b/src/tint/resolver/struct_pipeline_stage_use_test.cc
index 2857ec8..6b9ede9 100644
--- a/src/tint/resolver/struct_pipeline_stage_use_test.cc
+++ b/src/tint/resolver/struct_pipeline_stage_use_test.cc
@@ -21,6 +21,8 @@
 
 using ::testing::UnorderedElementsAre;
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -120,7 +122,7 @@
         Structure("S", {Member("a", ty.u32(), {Builtin(ast::Builtin::kLocalInvocationIndex)})});
 
     Func("main", {Param("param", ty.Of(s))}, ty.void_(), {},
-         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 
diff --git a/src/tint/resolver/struct_storage_class_use_test.cc b/src/tint/resolver/struct_storage_class_use_test.cc
index 8971bae..72ed546 100644
--- a/src/tint/resolver/struct_storage_class_use_test.cc
+++ b/src/tint/resolver/struct_storage_class_use_test.cc
@@ -20,6 +20,8 @@
 
 using ::testing::UnorderedElementsAre;
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -97,7 +99,7 @@
 
 TEST_F(ResolverStorageClassUseTest, StructReachableViaGlobalArray) {
     auto* s = Structure("S", {Member("a", ty.f32())});
-    auto* a = ty.array(ty.Of(s), 3);
+    auto* a = ty.array(ty.Of(s), 3_u);
     Global("g", a, ast::StorageClass::kPrivate);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -145,7 +147,7 @@
 
 TEST_F(ResolverStorageClassUseTest, StructReachableViaLocalArray) {
     auto* s = Structure("S", {Member("a", ty.f32())});
-    auto* a = ty.array(ty.Of(s), 3);
+    auto* a = ty.array(ty.Of(s), 3_u);
     WrapInFunction(Var("g", a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
diff --git a/src/tint/resolver/type_constructor_validation_test.cc b/src/tint/resolver/type_constructor_validation_test.cc
index d886b2e..edfce46 100644
--- a/src/tint/resolver/type_constructor_validation_test.cc
+++ b/src/tint/resolver/type_constructor_validation_test.cc
@@ -18,6 +18,8 @@
 #include "src/tint/sem/type_constructor.h"
 #include "src/tint/sem/type_conversion.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -31,14 +33,11 @@
 using builder::CreatePtrs;
 using builder::CreatePtrsFor;
 using builder::DataType;
-using builder::f32;
-using builder::i32;
 using builder::mat2x2;
 using builder::mat2x3;
 using builder::mat3x2;
 using builder::mat3x3;
 using builder::mat4x4;
-using builder::u32;
 using builder::vec2;
 using builder::vec3;
 using builder::vec4;
@@ -60,7 +59,7 @@
 TEST_F(ResolverTypeConstructorValidationTest, InferTypeTest_Simple) {
     // var a = 1;
     // var b = a;
-    auto* a = Var("a", nullptr, ast::StorageClass::kNone, Expr(1));
+    auto* a = Var("a", nullptr, ast::StorageClass::kNone, Expr(1_i));
     auto* b = Var("b", nullptr, ast::StorageClass::kNone, Expr("a"));
     auto* a_ident = Expr("a");
     auto* b_ident = Expr("b");
@@ -428,7 +427,7 @@
 namespace ArrayConstructor {
 
 TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Array_ZeroValue_Pass) {
-    // array<u32, 10>();
+    // array<u32, 10u>();
     auto* tc = array<u32, 10>();
     WrapInFunction(tc);
 
@@ -444,8 +443,8 @@
 }
 
 TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Array_type_match) {
-    // array<u32, 3>(0u, 10u. 20u);
-    auto* tc = array<u32, 3>(Expr(0u), Expr(10u), Expr(20u));
+    // array<u32, 3u>(0u, 10u. 20u);
+    auto* tc = array<u32, 3>(Expr(0_u), Expr(10_u), Expr(20_u));
     WrapInFunction(tc);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -463,8 +462,8 @@
 }
 
 TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Array_type_Mismatch_U32F32) {
-    // array<u32, 3>(0u, 1.0f, 20u);
-    auto* tc = array<u32, 3>(Expr(0u), Expr(Source{{12, 34}}, 1.0f), Expr(20u));
+    // array<u32, 3u>(0u, 1.0f, 20u);
+    auto* tc = array<u32, 3>(Expr(0_u), Expr(Source{{12, 34}}, 1.0f), Expr(20_u));
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -475,8 +474,8 @@
 
 TEST_F(ResolverTypeConstructorValidationTest,
        Expr_Constructor_Array_ScalarArgumentTypeMismatch_F32I32) {
-    // array<f32, 1>(1);
-    auto* tc = array<f32, 1>(Expr(Source{{12, 34}}, 1));
+    // array<f32, 1u>(1i);
+    auto* tc = array<f32, 1>(Expr(Source{{12, 34}}, 1_i));
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -487,8 +486,9 @@
 
 TEST_F(ResolverTypeConstructorValidationTest,
        Expr_Constructor_Array_ScalarArgumentTypeMismatch_U32I32) {
-    // array<u32, 6>(1, 0u, 0u, 0u, 0u, 0u);
-    auto* tc = array<u32, 1>(Expr(Source{{12, 34}}, 1), Expr(0u), Expr(0u), Expr(0u), Expr(0u));
+    // array<u32, 1u>(1i, 0u, 0u, 0u, 0u, 0u);
+    auto* tc =
+        array<u32, 1>(Expr(Source{{12, 34}}, 1_i), Expr(0_u), Expr(0_u), Expr(0_u), Expr(0_u));
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -499,8 +499,8 @@
 
 TEST_F(ResolverTypeConstructorValidationTest,
        Expr_Constructor_Array_ScalarArgumentTypeMismatch_Vec2) {
-    // array<i32, 3>(1, vec2<i32>());
-    auto* tc = array<i32, 3>(Expr(1), Construct(Source{{12, 34}}, ty.vec2<i32>()));
+    // array<i32, 3u>(1i, vec2<i32>());
+    auto* tc = array<i32, 3>(Expr(1_i), Construct(Source{{12, 34}}, ty.vec2<i32>()));
     WrapInFunction(tc);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -510,11 +510,11 @@
 
 TEST_F(ResolverTypeConstructorValidationTest,
        Expr_Constructor_ArrayOfVector_SubElemTypeMismatch_I32U32) {
-    // array<vec3<i32>, 2>(vec3<i32>(), vec3<u32>());
+    // array<vec3<i32>, 2u>(vec3<i32>(), vec3<u32>());
     auto* e0 = vec3<i32>();
     SetSource(Source::Location({12, 34}));
     auto* e1 = vec3<u32>();
-    auto* t = Construct(ty.array(ty.vec3<i32>(), 2), e0, e1);
+    auto* t = Construct(ty.array(ty.vec3<i32>(), 2_i), e0, e1);
     WrapInFunction(t);
 
     EXPECT_FALSE(r()->Resolve());
@@ -525,11 +525,11 @@
 
 TEST_F(ResolverTypeConstructorValidationTest,
        Expr_Constructor_ArrayOfVector_SubElemTypeMismatch_I32Bool) {
-    // array<vec3<i32>, 2>(vec3<i32>(), vec3<bool>(true, true, false));
+    // array<vec3<i32>, 2u>(vec3<i32>(), vec3<bool>(true, true, false));
     SetSource(Source::Location({12, 34}));
     auto* e0 = vec3<bool>(true, true, false);
     auto* e1 = vec3<i32>();
-    auto* t = Construct(ty.array(ty.vec3<i32>(), 2), e0, e1);
+    auto* t = Construct(ty.array(ty.vec3<i32>(), 2_i), e0, e1);
     WrapInFunction(t);
 
     EXPECT_FALSE(r()->Resolve());
@@ -539,11 +539,11 @@
 }
 
 TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_ArrayOfArray_SubElemSizeMismatch) {
-    // array<array<i32, 2>, 2>(array<i32, 3>(), array<i32, 2>());
+    // array<array<i32, 2u>, 2u>(array<i32, 3u>(), array<i32, 2u>());
     SetSource(Source::Location({12, 34}));
     auto* e0 = array<i32, 3>();
     auto* e1 = array<i32, 2>();
-    auto* t = Construct(ty.array(ty.array<i32, 2>(), 2), e0, e1);
+    auto* t = Construct(ty.array(ty.array<i32, 2>(), 2_i), e0, e1);
     WrapInFunction(t);
 
     EXPECT_FALSE(r()->Resolve());
@@ -553,11 +553,11 @@
 }
 
 TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_ArrayOfArray_SubElemTypeMismatch) {
-    // array<array<i32, 2>, 2>(array<i32, 2>(), array<u32, 2>());
+    // array<array<i32, 2u>, 2u>(array<i32, 2u>(), array<u32, 2u>());
     auto* e0 = array<i32, 2>();
     SetSource(Source::Location({12, 34}));
     auto* e1 = array<u32, 2>();
-    auto* t = Construct(ty.array(ty.array<i32, 2>(), 2), e0, e1);
+    auto* t = Construct(ty.array(ty.array<i32, 2>(), 2_i), e0, e1);
     WrapInFunction(t);
 
     EXPECT_FALSE(r()->Resolve());
@@ -567,9 +567,9 @@
 }
 
 TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Array_TooFewElements) {
-    // array<i32, 4>(1, 2, 3);
+    // array<i32, 4u>(1i, 2i, 3i);
     SetSource(Source::Location({12, 34}));
-    auto* tc = array<i32, 4>(Expr(1), Expr(2), Expr(3));
+    auto* tc = array<i32, 4>(Expr(1_i), Expr(2_i), Expr(3_i));
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -579,9 +579,9 @@
 }
 
 TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Array_TooManyElements) {
-    // array<i32, 4>(1, 2, 3, 4, 5);
+    // array<i32, 4u>(1i, 2i, 3i, 4i, 5i);
     SetSource(Source::Location({12, 34}));
-    auto* tc = array<i32, 4>(Expr(1), Expr(2), Expr(3), Expr(4), Expr(5));
+    auto* tc = array<i32, 4>(Expr(1_i), Expr(2_i), Expr(3_i), Expr(4_i), Expr(5_i));
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -592,8 +592,8 @@
 }
 
 TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Array_Runtime) {
-    // array<i32>(1);
-    auto* tc = array(ty.i32(), nullptr, Expr(Source{{12, 34}}, 1));
+    // array<i32>(1i);
+    auto* tc = array(ty.i32(), nullptr, Expr(Source{{12, 34}}, 1_i));
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -614,7 +614,7 @@
 namespace ScalarConstructor {
 
 TEST_F(ResolverTypeConstructorValidationTest, Expr_Construct_i32_Success) {
-    auto* expr = Construct<i32>(Expr(123));
+    auto* expr = Construct<i32>(Expr(123_i));
     WrapInFunction(expr);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -632,7 +632,7 @@
 }
 
 TEST_F(ResolverTypeConstructorValidationTest, Expr_Construct_u32_Success) {
-    auto* expr = Construct<u32>(Expr(123u));
+    auto* expr = Construct<u32>(Expr(123_u));
     WrapInFunction(expr);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -686,7 +686,7 @@
 }
 
 TEST_F(ResolverTypeConstructorValidationTest, Expr_Convert_i32_to_u32_Success) {
-    auto* expr = Construct<u32>(123);
+    auto* expr = Construct<u32>(123_i);
     WrapInFunction(expr);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -704,7 +704,7 @@
 }
 
 TEST_F(ResolverTypeConstructorValidationTest, Expr_Convert_u32_to_f32_Success) {
-    auto* expr = Construct<f32>(123u);
+    auto* expr = Construct<f32>(123_u);
     WrapInFunction(expr);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -727,7 +727,7 @@
 
 TEST_F(ResolverTypeConstructorValidationTest,
        Expr_Constructor_Vec2F32_Error_ScalarArgumentTypeMismatch) {
-    auto* tc = vec2<f32>(Expr(Source{{12, 34}}, 1), 1.0f);
+    auto* tc = vec2<f32>(Expr(Source{{12, 34}}, 1_i), 1.0f);
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -738,7 +738,7 @@
 
 TEST_F(ResolverTypeConstructorValidationTest,
        Expr_Constructor_Vec2U32_Error_ScalarArgumentTypeMismatch) {
-    auto* tc = vec2<u32>(1u, Expr(Source{{12, 34}}, 1));
+    auto* tc = vec2<u32>(1_u, Expr(Source{{12, 34}}, 1_i));
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -749,7 +749,7 @@
 
 TEST_F(ResolverTypeConstructorValidationTest,
        Expr_Constructor_Vec2I32_Error_ScalarArgumentTypeMismatch) {
-    auto* tc = vec2<i32>(Expr(Source{{12, 34}}, 1u), 1);
+    auto* tc = vec2<i32>(Expr(Source{{12, 34}}, 1_u), 1_i);
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -760,7 +760,7 @@
 
 TEST_F(ResolverTypeConstructorValidationTest,
        Expr_Constructor_Vec2Bool_Error_ScalarArgumentTypeMismatch) {
-    auto* tc = vec2<bool>(true, Expr(Source{{12, 34}}, 1));
+    auto* tc = vec2<bool>(true, Expr(Source{{12, 34}}, 1_i));
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -865,7 +865,7 @@
 }
 
 TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec2U32_Success_Scalar) {
-    auto* tc = vec2<u32>(1u, 1u);
+    auto* tc = vec2<u32>(1_u, 1_u);
     WrapInFunction(tc);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -886,7 +886,7 @@
 }
 
 TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec2I32_Success_Scalar) {
-    auto* tc = vec2<i32>(1, 1);
+    auto* tc = vec2<i32>(1_i, 1_i);
     WrapInFunction(tc);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -969,7 +969,7 @@
 
 TEST_F(ResolverTypeConstructorValidationTest,
        Expr_Constructor_Vec3F32_Error_ScalarArgumentTypeMismatch) {
-    auto* tc = vec3<f32>(1.0f, 1.0f, Expr(Source{{12, 34}}, 1));
+    auto* tc = vec3<f32>(1.0f, 1.0f, Expr(Source{{12, 34}}, 1_i));
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -980,7 +980,7 @@
 
 TEST_F(ResolverTypeConstructorValidationTest,
        Expr_Constructor_Vec3U32_Error_ScalarArgumentTypeMismatch) {
-    auto* tc = vec3<u32>(1u, Expr(Source{{12, 34}}, 1), 1u);
+    auto* tc = vec3<u32>(1_u, Expr(Source{{12, 34}}, 1_i), 1_u);
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -991,7 +991,7 @@
 
 TEST_F(ResolverTypeConstructorValidationTest,
        Expr_Constructor_Vec3I32_Error_ScalarArgumentTypeMismatch) {
-    auto* tc = vec3<i32>(1, Expr(Source{{12, 34}}, 1u), 1);
+    auto* tc = vec3<i32>(1_i, Expr(Source{{12, 34}}, 1_u), 1_i);
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -1002,7 +1002,7 @@
 
 TEST_F(ResolverTypeConstructorValidationTest,
        Expr_Constructor_Vec3Bool_Error_ScalarArgumentTypeMismatch) {
-    auto* tc = vec3<bool>(true, Expr(Source{{12, 34}}, 1), false);
+    auto* tc = vec3<bool>(true, Expr(Source{{12, 34}}, 1_i), false);
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -1124,7 +1124,7 @@
 }
 
 TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec3U32_Success_Scalar) {
-    auto* tc = vec3<u32>(1u, 1u, 1u);
+    auto* tc = vec3<u32>(1_u, 1_u, 1_u);
     WrapInFunction(tc);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -1146,7 +1146,7 @@
 }
 
 TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec3I32_Success_Scalar) {
-    auto* tc = vec3<i32>(1, 1, 1);
+    auto* tc = vec3<i32>(1_i, 1_i, 1_i);
     WrapInFunction(tc);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -1273,7 +1273,7 @@
 
 TEST_F(ResolverTypeConstructorValidationTest,
        Expr_Constructor_Vec4F32_Error_ScalarArgumentTypeMismatch) {
-    auto* tc = vec4<f32>(1.0f, 1.0f, Expr(Source{{12, 34}}, 1), 1.0f);
+    auto* tc = vec4<f32>(1.0f, 1.0f, Expr(Source{{12, 34}}, 1_i), 1.0f);
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -1284,7 +1284,7 @@
 
 TEST_F(ResolverTypeConstructorValidationTest,
        Expr_Constructor_Vec4U32_Error_ScalarArgumentTypeMismatch) {
-    auto* tc = vec4<u32>(1u, 1u, Expr(Source{{12, 34}}, 1), 1u);
+    auto* tc = vec4<u32>(1_u, 1_u, Expr(Source{{12, 34}}, 1_i), 1_u);
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -1295,7 +1295,7 @@
 
 TEST_F(ResolverTypeConstructorValidationTest,
        Expr_Constructor_Vec4I32_Error_ScalarArgumentTypeMismatch) {
-    auto* tc = vec4<i32>(1, 1, Expr(Source{{12, 34}}, 1u), 1);
+    auto* tc = vec4<i32>(1_i, 1_i, Expr(Source{{12, 34}}, 1_u), 1_i);
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -1306,7 +1306,7 @@
 
 TEST_F(ResolverTypeConstructorValidationTest,
        Expr_Constructor_Vec4Bool_Error_ScalarArgumentTypeMismatch) {
-    auto* tc = vec4<bool>(true, false, Expr(Source{{12, 34}}, 1), true);
+    auto* tc = vec4<bool>(true, false, Expr(Source{{12, 34}}, 1_i), true);
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -1457,7 +1457,7 @@
 }
 
 TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec4U32_Success_Scalar) {
-    auto* tc = vec4<u32>(1u, 1u, 1u, 1u);
+    auto* tc = vec4<u32>(1_u, 1_u, 1_u, 1_u);
     WrapInFunction(tc);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -1469,7 +1469,7 @@
 }
 
 TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec4I32_Success_Scalar) {
-    auto* tc = vec4<i32>(1, 1, 1, 1);
+    auto* tc = vec4<i32>(1_i, 1_i, 1_i, 1_i);
     WrapInFunction(tc);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -1641,7 +1641,7 @@
 
     // vec2<Float32>(1.0f, 1u)
     auto* vec_type = ty.vec(ty.Of(f32_alias), 2);
-    auto* tc = Construct(Source{{12, 34}}, vec_type, 1.0f, Expr(Source{{12, 40}}, 1u));
+    auto* tc = Construct(Source{{12, 34}}, vec_type, 1.0f, Expr(Source{{12, 40}}, 1_u));
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -1690,8 +1690,8 @@
 
 TEST_F(ResolverTypeConstructorValidationTest, InferVec2ElementTypeFromScalars) {
     auto* vec2_bool = Construct(create<ast::Vector>(nullptr, 2), Expr(true), Expr(false));
-    auto* vec2_i32 = Construct(create<ast::Vector>(nullptr, 2), Expr(1), Expr(2));
-    auto* vec2_u32 = Construct(create<ast::Vector>(nullptr, 2), Expr(1u), Expr(2u));
+    auto* vec2_i32 = Construct(create<ast::Vector>(nullptr, 2), Expr(1_i), Expr(2_i));
+    auto* vec2_u32 = Construct(create<ast::Vector>(nullptr, 2), Expr(1_u), Expr(2_u));
     auto* vec2_f32 = Construct(create<ast::Vector>(nullptr, 2), Expr(1.0f), Expr(2.0f));
     WrapInFunction(vec2_bool, vec2_i32, vec2_u32, vec2_f32);
 
@@ -1717,8 +1717,8 @@
 
 TEST_F(ResolverTypeConstructorValidationTest, InferVec2ElementTypeFromVec2) {
     auto* vec2_bool = Construct(create<ast::Vector>(nullptr, 2), vec2<bool>(true, false));
-    auto* vec2_i32 = Construct(create<ast::Vector>(nullptr, 2), vec2<i32>(1, 2));
-    auto* vec2_u32 = Construct(create<ast::Vector>(nullptr, 2), vec2<u32>(1u, 2u));
+    auto* vec2_i32 = Construct(create<ast::Vector>(nullptr, 2), vec2<i32>(1_i, 2_i));
+    auto* vec2_u32 = Construct(create<ast::Vector>(nullptr, 2), vec2<u32>(1_u, 2_u));
     auto* vec2_f32 = Construct(create<ast::Vector>(nullptr, 2), vec2<f32>(1.0f, 2.0f));
     WrapInFunction(vec2_bool, vec2_i32, vec2_u32, vec2_f32);
 
@@ -1745,8 +1745,8 @@
 TEST_F(ResolverTypeConstructorValidationTest, InferVec3ElementTypeFromScalars) {
     auto* vec3_bool =
         Construct(create<ast::Vector>(nullptr, 3), Expr(true), Expr(false), Expr(true));
-    auto* vec3_i32 = Construct(create<ast::Vector>(nullptr, 3), Expr(1), Expr(2), Expr(3));
-    auto* vec3_u32 = Construct(create<ast::Vector>(nullptr, 3), Expr(1u), Expr(2u), Expr(3u));
+    auto* vec3_i32 = Construct(create<ast::Vector>(nullptr, 3), Expr(1_i), Expr(2_i), Expr(3_i));
+    auto* vec3_u32 = Construct(create<ast::Vector>(nullptr, 3), Expr(1_u), Expr(2_u), Expr(3_u));
     auto* vec3_f32 = Construct(create<ast::Vector>(nullptr, 3), Expr(1.0f), Expr(2.0f), Expr(3.0f));
     WrapInFunction(vec3_bool, vec3_i32, vec3_u32, vec3_f32);
 
@@ -1772,8 +1772,8 @@
 
 TEST_F(ResolverTypeConstructorValidationTest, InferVec3ElementTypeFromVec3) {
     auto* vec3_bool = Construct(create<ast::Vector>(nullptr, 3), vec3<bool>(true, false, true));
-    auto* vec3_i32 = Construct(create<ast::Vector>(nullptr, 3), vec3<i32>(1, 2, 3));
-    auto* vec3_u32 = Construct(create<ast::Vector>(nullptr, 3), vec3<u32>(1u, 2u, 3u));
+    auto* vec3_i32 = Construct(create<ast::Vector>(nullptr, 3), vec3<i32>(1_i, 2_i, 3_i));
+    auto* vec3_u32 = Construct(create<ast::Vector>(nullptr, 3), vec3<u32>(1_u, 2_u, 3_u));
     auto* vec3_f32 = Construct(create<ast::Vector>(nullptr, 3), vec3<f32>(1.0f, 2.0f, 3.0f));
     WrapInFunction(vec3_bool, vec3_i32, vec3_u32, vec3_f32);
 
@@ -1800,8 +1800,8 @@
 TEST_F(ResolverTypeConstructorValidationTest, InferVec3ElementTypeFromScalarAndVec2) {
     auto* vec3_bool =
         Construct(create<ast::Vector>(nullptr, 3), Expr(true), vec2<bool>(false, true));
-    auto* vec3_i32 = Construct(create<ast::Vector>(nullptr, 3), Expr(1), vec2<i32>(2, 3));
-    auto* vec3_u32 = Construct(create<ast::Vector>(nullptr, 3), Expr(1u), vec2<u32>(2u, 3u));
+    auto* vec3_i32 = Construct(create<ast::Vector>(nullptr, 3), Expr(1_i), vec2<i32>(2_i, 3_i));
+    auto* vec3_u32 = Construct(create<ast::Vector>(nullptr, 3), Expr(1_u), vec2<u32>(2_u, 3_u));
     auto* vec3_f32 = Construct(create<ast::Vector>(nullptr, 3), Expr(1.0f), vec2<f32>(2.0f, 3.0f));
     WrapInFunction(vec3_bool, vec3_i32, vec3_u32, vec3_f32);
 
@@ -1828,9 +1828,10 @@
 TEST_F(ResolverTypeConstructorValidationTest, InferVec4ElementTypeFromScalars) {
     auto* vec4_bool = Construct(create<ast::Vector>(nullptr, 4), Expr(true), Expr(false),
                                 Expr(true), Expr(false));
-    auto* vec4_i32 = Construct(create<ast::Vector>(nullptr, 4), Expr(1), Expr(2), Expr(3), Expr(4));
+    auto* vec4_i32 =
+        Construct(create<ast::Vector>(nullptr, 4), Expr(1_i), Expr(2_i), Expr(3_i), Expr(4_i));
     auto* vec4_u32 =
-        Construct(create<ast::Vector>(nullptr, 4), Expr(1u), Expr(2u), Expr(3u), Expr(4u));
+        Construct(create<ast::Vector>(nullptr, 4), Expr(1_u), Expr(2_u), Expr(3_u), Expr(4_u));
     auto* vec4_f32 =
         Construct(create<ast::Vector>(nullptr, 4), Expr(1.0f), Expr(2.0f), Expr(3.0f), Expr(4.0f));
     WrapInFunction(vec4_bool, vec4_i32, vec4_u32, vec4_f32);
@@ -1858,8 +1859,8 @@
 TEST_F(ResolverTypeConstructorValidationTest, InferVec4ElementTypeFromVec4) {
     auto* vec4_bool =
         Construct(create<ast::Vector>(nullptr, 4), vec4<bool>(true, false, true, false));
-    auto* vec4_i32 = Construct(create<ast::Vector>(nullptr, 4), vec4<i32>(1, 2, 3, 4));
-    auto* vec4_u32 = Construct(create<ast::Vector>(nullptr, 4), vec4<u32>(1u, 2u, 3u, 4u));
+    auto* vec4_i32 = Construct(create<ast::Vector>(nullptr, 4), vec4<i32>(1_i, 2_i, 3_i, 4_i));
+    auto* vec4_u32 = Construct(create<ast::Vector>(nullptr, 4), vec4<u32>(1_u, 2_u, 3_u, 4_u));
     auto* vec4_f32 = Construct(create<ast::Vector>(nullptr, 4), vec4<f32>(1.0f, 2.0f, 3.0f, 4.0f));
     WrapInFunction(vec4_bool, vec4_i32, vec4_u32, vec4_f32);
 
@@ -1886,8 +1887,10 @@
 TEST_F(ResolverTypeConstructorValidationTest, InferVec4ElementTypeFromScalarAndVec3) {
     auto* vec4_bool =
         Construct(create<ast::Vector>(nullptr, 4), Expr(true), vec3<bool>(false, true, false));
-    auto* vec4_i32 = Construct(create<ast::Vector>(nullptr, 4), Expr(1), vec3<i32>(2, 3, 4));
-    auto* vec4_u32 = Construct(create<ast::Vector>(nullptr, 4), Expr(1u), vec3<u32>(2u, 3u, 4u));
+    auto* vec4_i32 =
+        Construct(create<ast::Vector>(nullptr, 4), Expr(1_i), vec3<i32>(2_i, 3_i, 4_i));
+    auto* vec4_u32 =
+        Construct(create<ast::Vector>(nullptr, 4), Expr(1_u), vec3<u32>(2_u, 3_u, 4_u));
     auto* vec4_f32 =
         Construct(create<ast::Vector>(nullptr, 4), Expr(1.0f), vec3<f32>(2.0f, 3.0f, 4.0f));
     WrapInFunction(vec4_bool, vec4_i32, vec4_u32, vec4_f32);
@@ -1915,9 +1918,10 @@
 TEST_F(ResolverTypeConstructorValidationTest, InferVec4ElementTypeFromVec2AndVec2) {
     auto* vec4_bool = Construct(create<ast::Vector>(nullptr, 4), vec2<bool>(true, false),
                                 vec2<bool>(true, false));
-    auto* vec4_i32 = Construct(create<ast::Vector>(nullptr, 4), vec2<i32>(1, 2), vec2<i32>(3, 4));
+    auto* vec4_i32 =
+        Construct(create<ast::Vector>(nullptr, 4), vec2<i32>(1_i, 2_i), vec2<i32>(3_i, 4_i));
     auto* vec4_u32 =
-        Construct(create<ast::Vector>(nullptr, 4), vec2<u32>(1u, 2u), vec2<u32>(3u, 4u));
+        Construct(create<ast::Vector>(nullptr, 4), vec2<u32>(1_u, 2_u), vec2<u32>(3_u, 4_u));
     auto* vec4_f32 =
         Construct(create<ast::Vector>(nullptr, 4), vec2<f32>(1.0f, 2.0f), vec2<f32>(3.0f, 4.0f));
     WrapInFunction(vec4_bool, vec4_i32, vec4_u32, vec4_f32);
@@ -1951,8 +1955,8 @@
 
 TEST_F(ResolverTypeConstructorValidationTest, CannotInferVec2ElementTypeFromScalarsMismatch) {
     WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 2),
-                             Expr(Source{{1, 2}}, 1),  //
-                             Expr(Source{{1, 3}}, 2u)));
+                             Expr(Source{{1, 2}}, 1_i),  //
+                             Expr(Source{{1, 3}}, 2_u)));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -1964,9 +1968,9 @@
 
 TEST_F(ResolverTypeConstructorValidationTest, CannotInferVec3ElementTypeFromScalarsMismatch) {
     WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 3),
-                             Expr(Source{{1, 2}}, 1),   //
-                             Expr(Source{{1, 3}}, 2u),  //
-                             Expr(Source{{1, 4}}, 3)));
+                             Expr(Source{{1, 2}}, 1_i),  //
+                             Expr(Source{{1, 3}}, 2_u),  //
+                             Expr(Source{{1, 4}}, 3_i)));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -1979,7 +1983,7 @@
 
 TEST_F(ResolverTypeConstructorValidationTest, CannotInferVec3ElementTypeFromScalarAndVec2Mismatch) {
     WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 3),
-                             Expr(Source{{1, 2}}, 1),  //
+                             Expr(Source{{1, 2}}, 1_i),  //
                              Construct(Source{{1, 3}}, ty.vec2<f32>(), 2.0f, 3.0f)));
 
     EXPECT_FALSE(r()->Resolve());
@@ -1992,10 +1996,10 @@
 
 TEST_F(ResolverTypeConstructorValidationTest, CannotInferVec4ElementTypeFromScalarsMismatch) {
     WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 4),
-                             Expr(Source{{1, 2}}, 1),     //
-                             Expr(Source{{1, 3}}, 2),     //
+                             Expr(Source{{1, 2}}, 1_i),   //
+                             Expr(Source{{1, 3}}, 2_i),   //
                              Expr(Source{{1, 4}}, 3.0f),  //
-                             Expr(Source{{1, 5}}, 4)));
+                             Expr(Source{{1, 5}}, 4_i)));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -2009,8 +2013,8 @@
 
 TEST_F(ResolverTypeConstructorValidationTest, CannotInferVec4ElementTypeFromScalarAndVec3Mismatch) {
     WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 4),
-                             Expr(Source{{1, 2}}, 1),  //
-                             Construct(Source{{1, 3}}, ty.vec3<u32>(), 2u, 3u, 4u)));
+                             Expr(Source{{1, 2}}, 1_i),  //
+                             Construct(Source{{1, 3}}, ty.vec3<u32>(), 2_u, 3_u, 4_u)));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -2022,8 +2026,8 @@
 
 TEST_F(ResolverTypeConstructorValidationTest, CannotInferVec4ElementTypeFromVec2AndVec2Mismatch) {
     WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 4),
-                             Construct(Source{{1, 2}}, ty.vec2<i32>(), 3, 4),  //
-                             Construct(Source{{1, 3}}, ty.vec2<u32>(), 3u, 4u)));
+                             Construct(Source{{1, 2}}, ty.vec2<i32>(), 3_i, 4_i),  //
+                             Construct(Source{{1, 3}}, ty.vec2<u32>(), 3_u, 4_u)));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -2179,7 +2183,7 @@
     std::stringstream args_tys;
     ast::ExpressionList args;
     for (uint32_t i = 1; i <= param.columns; i++) {
-        args.push_back(Expr(Source{{12, i}}, 1u));
+        args.push_back(Expr(Source{{12, i}}, 1_u));
         if (i > 1) {
             args_tys << ", ";
         }
@@ -2527,12 +2531,9 @@
 namespace StructConstructor {
 using builder::CreatePtrs;
 using builder::CreatePtrsFor;
-using builder::f32;
-using builder::i32;
 using builder::mat2x2;
 using builder::mat3x3;
 using builder::mat4x4;
-using builder::u32;
 using builder::vec2;
 using builder::vec3;
 using builder::vec4;
@@ -2659,7 +2660,7 @@
     auto* m2 = Member("m2", ty.i32());
     auto* s = Structure("s", {m0, m1, m2});
 
-    auto* tc = Construct(Source{{12, 34}}, ty.Of(s), 1, 1, 1);
+    auto* tc = Construct(Source{{12, 34}}, ty.Of(s), 1_i, 1_i, 1_i);
     WrapInFunction(tc);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -2695,7 +2696,8 @@
 }
 
 TEST_F(ResolverTypeConstructorValidationTest, NonConstructibleType_AtomicArray) {
-    WrapInFunction(Assign(Phony(), Construct(Source{{12, 34}}, ty.array(ty.atomic(ty.i32()), 4))));
+    WrapInFunction(
+        Assign(Phony(), Construct(Source{{12, 34}}, ty.array(ty.atomic(ty.i32()), 4_i))));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array constructor has non-constructible element type");
@@ -2725,7 +2727,7 @@
 }
 
 TEST_F(ResolverTypeConstructorValidationTest, TypeConversionAsStatement) {
-    WrapInFunction(CallStmt(Construct(Source{{12, 34}}, ty.f32(), 1)));
+    WrapInFunction(CallStmt(Construct(Source{{12, 34}}, ty.f32(), 1_i)));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: type cast evaluated but not used");
diff --git a/src/tint/resolver/type_validation_test.cc b/src/tint/resolver/type_validation_test.cc
index bfd4249..2af2c0e 100644
--- a/src/tint/resolver/type_validation_test.cc
+++ b/src/tint/resolver/type_validation_test.cc
@@ -22,6 +22,8 @@
 
 #include "gmock/gmock.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -50,9 +52,6 @@
 using alias2 = builder::alias2<T>;
 template <typename T>
 using alias3 = builder::alias3<T>;
-using f32 = builder::f32;
-using i32 = builder::i32;
-using u32 = builder::u32;
 
 class ResolverTypeValidationTest : public resolver::TestHelper, public testing::Test {};
 
@@ -63,7 +62,7 @@
     // }
     auto* var = Var("a", ty.i32(), ast::StorageClass::kNone, nullptr);
     auto* lhs = Expr("a");
-    auto* rhs = Expr(2);
+    auto* rhs = Expr(2_i);
 
     auto* body = Block(Decl(var), Assign(Source{Source::Location{12, 34}}, lhs, rhs));
 
@@ -191,49 +190,49 @@
 
 TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedLiteral_Pass) {
     // var<private> a : array<f32, 4u>;
-    Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 4u)), ast::StorageClass::kPrivate);
+    Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 4_u)), ast::StorageClass::kPrivate);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_SignedLiteral_Pass) {
-    // var<private> a : array<f32, 4>;
-    Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 4)), ast::StorageClass::kPrivate);
+    // var<private> a : array<f32, 4i>;
+    Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 4_i)), ast::StorageClass::kPrivate);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedConstant_Pass) {
     // let size = 4u;
     // var<private> a : array<f32, size>;
-    GlobalConst("size", nullptr, Expr(4u));
+    GlobalConst("size", nullptr, Expr(4_u));
     Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_SignedConstant_Pass) {
-    // let size = 4;
+    // let size = 4i;
     // var<private> a : array<f32, size>;
-    GlobalConst("size", nullptr, Expr(4));
+    GlobalConst("size", nullptr, Expr(4_i));
     Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedLiteral_Zero) {
     // var<private> a : array<f32, 0u>;
-    Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0u)), ast::StorageClass::kPrivate);
+    Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_u)), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_SignedLiteral_Zero) {
-    // var<private> a : array<f32, 0>;
-    Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0)), ast::StorageClass::kPrivate);
+    // var<private> a : array<f32, 0i>;
+    Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_i)), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_SignedLiteral_Negative) {
-    // var<private> a : array<f32, -10>;
-    Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, -10)), ast::StorageClass::kPrivate);
+    // var<private> a : array<f32, -10i>;
+    Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, i32(-10))), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1");
 }
@@ -241,25 +240,25 @@
 TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedConstant_Zero) {
     // let size = 0u;
     // var<private> a : array<f32, size>;
-    GlobalConst("size", nullptr, Expr(0u));
+    GlobalConst("size", nullptr, Expr(0_u));
     Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_SignedConstant_Zero) {
-    // let size = 0;
+    // let size = 0i;
     // var<private> a : array<f32, size>;
-    GlobalConst("size", nullptr, Expr(0));
+    GlobalConst("size", nullptr, Expr(0_i));
     Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_SignedConstant_Negative) {
-    // let size = -10;
+    // let size = -10i;
     // var<private> a : array<f32, size>;
-    GlobalConst("size", nullptr, Expr(-10));
+    GlobalConst("size", nullptr, Expr(i32(-10)));
     Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1");
@@ -274,7 +273,7 @@
 
 TEST_F(ResolverTypeValidationTest, ArraySize_IVecLiteral) {
     // var<private> a : array<f32, vec2<i32>(10, 10)>;
-    Global("a", ty.array(ty.f32(), Construct(Source{{12, 34}}, ty.vec2<i32>(), 10, 10)),
+    Global("a", ty.array(ty.f32(), Construct(Source{{12, 34}}, ty.vec2<i32>(), 10_i, 10_i)),
            ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array size must be integer scalar");
@@ -292,15 +291,15 @@
 TEST_F(ResolverTypeValidationTest, ArraySize_IVecConstant) {
     // let size = vec2<i32>(100, 100);
     // var<private> a : array<f32, size>;
-    GlobalConst("size", nullptr, Construct(ty.vec2<i32>(), 100, 100));
+    GlobalConst("size", nullptr, Construct(ty.vec2<i32>(), 100_i, 100_i));
     Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array size must be integer scalar");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_TooBig_ImplicitStride) {
-    // var<private> a : array<f32, 0x40000000>;
-    Global("a", ty.array(Source{{12, 34}}, ty.f32(), 0x40000000), ast::StorageClass::kPrivate);
+    // var<private> a : array<f32, 0x40000000u>;
+    Global("a", ty.array(Source{{12, 34}}, ty.f32(), 0x40000000_u), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "12:34 error: array size in bytes must not exceed 0xffffffff, but "
@@ -308,8 +307,8 @@
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_TooBig_ExplicitStride) {
-    // var<private> a : @stride(8) array<f32, 0x20000000>;
-    Global("a", ty.array(Source{{12, 34}}, ty.f32(), 0x20000000, 8), ast::StorageClass::kPrivate);
+    // var<private> a : @stride(8) array<f32, 0x20000000u>;
+    Global("a", ty.array(Source{{12, 34}}, ty.f32(), 0x20000000_u, 8), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "12:34 error: array size in bytes must not exceed 0xffffffff, but "
@@ -317,18 +316,18 @@
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_OverridableConstant) {
-    // override size = 10;
+    // override size = 10i;
     // var<private> a : array<f32, size>;
-    Override("size", nullptr, Expr(10));
+    Override("size", nullptr, Expr(10_i));
     Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array size expression must not be pipeline-overridable");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_ModuleVar) {
-    // var<private> size : i32 = 10;
+    // var<private> size : i32 = 10i;
     // var<private> a : array<f32, size>;
-    Global("size", ty.i32(), Expr(10), ast::StorageClass::kPrivate);
+    Global("size", ty.i32(), Expr(10_i), ast::StorageClass::kPrivate);
     Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array size identifier must be a module-scope constant");
@@ -339,7 +338,7 @@
     //   let size = 10;
     //   var a : array<f32, size>;
     // }
-    auto* size = Let("size", nullptr, Expr(10));
+    auto* size = Let("size", nullptr, Expr(10_i));
     auto* a = Var("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")));
     WrapInFunction(Block(Decl(size), Decl(a)));
     EXPECT_FALSE(r()->Resolve());
@@ -347,10 +346,9 @@
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_InvalidExpr) {
-    // var a : array<f32, i32(4)>;
-    auto* size = Let("size", nullptr, Expr(10));
-    auto* a = Var("a", ty.array(ty.f32(), Construct(Source{{12, 34}}, ty.i32(), 4)));
-    WrapInFunction(Block(Decl(size), Decl(a)));
+    // var a : array<f32, i32(4i)>;
+    auto* a = Var("a", ty.array(ty.f32(), Construct(Source{{12, 34}}, ty.i32(), 4_i)));
+    WrapInFunction(Block(Decl(a)));
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "12:34 error: array size expression must be either a literal or a "
@@ -457,10 +455,10 @@
 
 TEST_F(ResolverTypeValidationTest, RuntimeArrayInArray) {
     // struct Foo {
-    //   rt : array<array<f32>, 4>;
+    //   rt : array<array<f32>, 4u>;
     // };
 
-    Structure("Foo", {Member("rt", ty.array(Source{{12, 34}}, ty.array<f32>(), 4))});
+    Structure("Foo", {Member("rt", ty.array(Source{{12, 34}}, ty.array<f32>(), 4_u))});
 
     EXPECT_FALSE(r()->Resolve()) << r()->error();
     EXPECT_EQ(r()->error(),
@@ -475,7 +473,7 @@
     // var<private> a : array<Foo, 4>;
 
     auto* foo = Structure("Foo", {Member("rt", ty.array<f32>())});
-    Global("v", ty.array(Source{{12, 34}}, ty.Of(foo), 4), ast::StorageClass::kPrivate);
+    Global("v", ty.array(Source{{12, 34}}, ty.Of(foo), 4_u), ast::StorageClass::kPrivate);
 
     EXPECT_FALSE(r()->Resolve()) << r()->error();
     EXPECT_EQ(r()->error(),
@@ -624,7 +622,7 @@
 
 TEST_F(ResolverTypeValidationTest, ArrayOfNonStorableType) {
     auto* tex_ty = ty.sampled_texture(ast::TextureDimension::k2d, ty.f32());
-    Global("arr", ty.array(Source{{12, 34}}, tex_ty, 4), ast::StorageClass::kPrivate);
+    Global("arr", ty.array(Source{{12, 34}}, tex_ty, 4_i), ast::StorageClass::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
diff --git a/src/tint/resolver/validation_test.cc b/src/tint/resolver/validation_test.cc
index 0e7cfff..65d73c4 100644
--- a/src/tint/resolver/validation_test.cc
+++ b/src/tint/resolver/validation_test.cc
@@ -41,6 +41,8 @@
 using ::testing::ElementsAre;
 using ::testing::HasSubstr;
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -169,7 +171,7 @@
     // normalize = 2;
 
     auto* lhs = Expr(Source{{12, 34}}, "normalize");
-    auto* rhs = Expr(2);
+    auto* rhs = Expr(2_i);
     auto* assign = Assign(lhs, rhs);
     WrapInFunction(assign);
 
@@ -181,7 +183,7 @@
     // b = 2;
 
     auto* lhs = Expr(Source{{12, 34}}, "b");
-    auto* rhs = Expr(2);
+    auto* rhs = Expr(2_i);
     auto* assign = Assign(lhs, rhs);
     WrapInFunction(assign);
 
@@ -195,7 +197,7 @@
     // }
 
     auto* lhs = Expr(Source{{12, 34}}, "b");
-    auto* rhs = Expr(2);
+    auto* rhs = Expr(2_i);
 
     auto* body = Block(Assign(lhs, rhs));
     WrapInFunction(body);
@@ -444,7 +446,7 @@
 
     auto error_loc = Source{{12, 34}};
     auto* body = Block(Continue(), Decl(error_loc, Var("z", ty.i32(), ast::StorageClass::kNone)));
-    auto* continuing = Block(Assign(Expr("z"), 2));
+    auto* continuing = Block(Assign(Expr("z"), 2_i));
     auto* loop_stmt = Loop(body, continuing);
     WrapInFunction(loop_stmt);
 
@@ -464,14 +466,14 @@
     //     continue; // Ok
     //
     //     continuing {
-    //         z = 2;
+    //         z = 2i;
     //     }
     // }
 
     auto* body =
         Block(If(false, Block(Break())),  //
               Decl(Var("z", ty.i32(), ast::StorageClass::kNone)), Block(Block(Block(Continue()))));
-    auto* continuing = Block(Assign(Expr("z"), 2));
+    auto* continuing = Block(Assign(Expr("z"), 2_i));
     auto* loop_stmt = Loop(body, continuing);
     WrapInFunction(loop_stmt);
 
@@ -485,7 +487,7 @@
     //     }
     //     var z : i32;
     //     continuing {
-    //         z = 2;
+    //         z = 2i;
     //     }
     // }
 
@@ -494,7 +496,7 @@
     auto ref_loc = Source{{90, 12}};
     auto* body = Block(If(Expr(true), Block(Continue(cont_loc))),
                        Decl(Var(decl_loc, "z", ty.i32(), ast::StorageClass::kNone)));
-    auto* continuing = Block(Assign(Expr(ref_loc, "z"), 2));
+    auto* continuing = Block(Assign(Expr(ref_loc, "z"), 2_i));
     auto* loop_stmt = Loop(body, continuing);
     WrapInFunction(loop_stmt);
 
@@ -514,7 +516,7 @@
     //     var z : i32;
     //     continuing {
     //         if (true) {
-    //             z = 2; // Must fail even if z is in a sub-scope
+    //             z = 2i; // Must fail even if z is in a sub-scope
     //         }
     //     }
     // }
@@ -525,7 +527,7 @@
     auto* body = Block(If(Expr(true), Block(Continue(cont_loc))),
                        Decl(Var(decl_loc, "z", ty.i32(), ast::StorageClass::kNone)));
 
-    auto* continuing = Block(If(Expr(true), Block(Assign(Expr(ref_loc, "z"), 2))));
+    auto* continuing = Block(If(Expr(true), Block(Assign(Expr(ref_loc, "z"), 2_i))));
     auto* loop_stmt = Loop(body, continuing);
     WrapInFunction(loop_stmt);
 
@@ -545,7 +547,7 @@
     //     continuing {
     //         // Must fail even if z is used in an expression that isn't
     //         // directly contained inside a block.
-    //         if (z < 2) {
+    //         if (z < 2i) {
     //         }
     //     }
     // }
@@ -556,7 +558,7 @@
     auto* body = Block(If(Expr(true), Block(Continue(cont_loc))),
                        Decl(Var(decl_loc, "z", ty.i32(), ast::StorageClass::kNone)));
     auto* compare =
-        create<ast::BinaryExpression>(ast::BinaryOp::kLessThan, Expr(ref_loc, "z"), Expr(2));
+        create<ast::BinaryExpression>(ast::BinaryOp::kLessThan, Expr(ref_loc, "z"), Expr(2_i));
     auto* continuing = Block(If(compare, Block()));
     auto* loop_stmt = Loop(body, continuing);
     WrapInFunction(loop_stmt);
@@ -577,7 +579,7 @@
     //     var z : i32;
     //     continuing {
     //         loop {
-    //             z = 2; // Must fail even if z is in a sub-scope
+    //             z = 2i; // Must fail even if z is in a sub-scope
     //         }
     //     }
     // }
@@ -588,7 +590,7 @@
     auto* body = Block(If(Expr(true), Block(Continue(cont_loc))),
                        Decl(Var(decl_loc, "z", ty.i32(), ast::StorageClass::kNone)));
 
-    auto* continuing = Block(Loop(Block(Assign(Expr(ref_loc, "z"), 2))));
+    auto* continuing = Block(Loop(Block(Assign(Expr(ref_loc, "z"), 2_i))));
     auto* loop_stmt = Loop(body, continuing);
     WrapInFunction(loop_stmt);
 
@@ -608,7 +610,7 @@
     //     var z : i32;
     //     break;
     //     continuing {
-    //         z = 2;
+    //         z = 2i;
     //     }
     // }
 
@@ -618,7 +620,7 @@
     auto* body = Block(inner_loop,                                          //
                        Decl(Var("z", ty.i32(), ast::StorageClass::kNone)),  //
                        Break());
-    auto* continuing = Block(Assign("z", 2));
+    auto* continuing = Block(Assign("z", 2_i));
     auto* loop_stmt = Loop(body, continuing);
     WrapInFunction(loop_stmt);
 
@@ -636,7 +638,7 @@
     //     break;
     //     continuing {
     //         if (true) {
-    //             z = 2;
+    //             z = 2i;
     //         }
     //     }
     // }
@@ -646,7 +648,7 @@
     auto* body = Block(inner_loop,                                          //
                        Decl(Var("z", ty.i32(), ast::StorageClass::kNone)),  //
                        Break());
-    auto* continuing = Block(If(Expr(true), Block(Assign("z", 2))));
+    auto* continuing = Block(If(Expr(true), Block(Assign("z", 2_i))));
     auto* loop_stmt = Loop(body, continuing);
     WrapInFunction(loop_stmt);
 
@@ -663,7 +665,7 @@
     //     break;
     //     continuing {
     //         loop {
-    //             z = 2;
+    //             z = 2i;
     //             break;
     //         }
     //     }
@@ -674,7 +676,7 @@
     auto* body = Block(inner_loop,                                          //
                        Decl(Var("z", ty.i32(), ast::StorageClass::kNone)),  //
                        Break());
-    auto* continuing = Block(Loop(Block(Assign("z", 2),  //
+    auto* continuing = Block(Loop(Block(Assign("z", 2_i),  //
                                         Break())));
     auto* loop_stmt = Loop(body, continuing);
     WrapInFunction(loop_stmt);
@@ -688,7 +690,7 @@
     //     if (true) { continue; }
     //     break;
     //     continuing {
-    //         z = 2;
+    //         z = 2i;
     //     }
     // }
 
@@ -696,7 +698,7 @@
     auto* body =
         Block(Decl(Var("z", ty.i32(), ast::StorageClass::kNone)), If(true, Block(Continue())),  //
               Break());
-    auto* continuing = Block(Assign(Expr(error_loc, "z"), 2));
+    auto* continuing = Block(Assign(Expr(error_loc, "z"), 2_i));
     auto* loop_stmt = Loop(body, continuing);
     WrapInFunction(loop_stmt);
 
@@ -988,8 +990,8 @@
 }
 
 TEST_F(ResolverValidationTest, Stmt_BreakInSwitch) {
-    WrapInFunction(Loop(Block(Switch(Expr(1),               //
-                                     Case(Expr(1),          //
+    WrapInFunction(Loop(Block(Switch(Expr(1_i),             //
+                                     Case(Expr(1_i),        //
                                           Block(Break())),  //
                                      DefaultCase()),        //
                               Break())));                   //
@@ -1051,7 +1053,7 @@
 TEST_F(ResolverValidationTest, Stmt_BreakInIfTrueMultipleStmtsInContinuing) {
     auto* cont = Block(                             // continuing {
         If(true, Block(Source{{56, 78}},            //   if(true) {
-                       Assign(Phony(), 1),          //     _ = 1;
+                       Assign(Phony(), 1_i),        //     _ = 1i;
                        Break(Source{{12, 34}}))));  //     break;
                                                     //   }
                                                     // }
@@ -1068,7 +1070,7 @@
     auto* cont = Block(                             // continuing {
         If(true, Block(),                           //   if(true) {
            Else(Block(Source{{56, 78}},             //   } else {
-                      Assign(Phony(), 1),           //     _ = 1;
+                      Assign(Phony(), 1_i),         //     _ = 1i;
                       Break(Source{{12, 34}})))));  //     break;
                                                     //   }
                                                     // }
@@ -1098,13 +1100,13 @@
 }
 
 TEST_F(ResolverValidationTest, Stmt_BreakInIfNonEmptyElseInContinuing) {
-    auto* cont = Block(                        // continuing {
-        If(true,                               //   if(true) {
-           Block(Break(Source{{12, 34}})),     //     break;
-           Else(Block(Source{{56, 78}},        //   } else {
-                      Assign(Phony(), 1)))));  //     _ = 1;
-                                               //   }
-                                               // }
+    auto* cont = Block(                          // continuing {
+        If(true,                                 //   if(true) {
+           Block(Break(Source{{12, 34}})),       //     break;
+           Else(Block(Source{{56, 78}},          //   } else {
+                      Assign(Phony(), 1_i)))));  //     _ = 1i;
+                                                 //   }
+                                                 // }
     WrapInFunction(Loop(Block(), cont));
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -1115,13 +1117,13 @@
 }
 
 TEST_F(ResolverValidationTest, Stmt_BreakInIfElseNonEmptyTrueInContinuing) {
-    auto* cont = Block(                                  // continuing {
-        If(true,                                         //   if(true) {
-           Block(Source{{56, 78}}, Assign(Phony(), 1)),  //     _ = 1;
-           Else(Block(                                   //   } else {
-               Break(Source{{12, 34}})))));              //     break;
-                                                         //   }
-                                                         // }
+    auto* cont = Block(                                    // continuing {
+        If(true,                                           //   if(true) {
+           Block(Source{{56, 78}}, Assign(Phony(), 1_i)),  //     _ = 1i;
+           Else(Block(                                     //   } else {
+               Break(Source{{12, 34}})))));                //     break;
+                                                           //   }
+                                                           // }
     WrapInFunction(Loop(Block(), cont));
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -1136,7 +1138,7 @@
         If(Source{{56, 78}}, true,           //   if(true) {
            Block(Break(Source{{12, 34}}))),  //     break;
                                              //   }
-        Assign(Phony(), 1));                 //   _ = 1;
+        Assign(Phony(), 1_i));               //   _ = 1i;
                                              // }
     WrapInFunction(Loop(Block(), cont));
     EXPECT_FALSE(r()->Resolve());
diff --git a/src/tint/resolver/var_let_test.cc b/src/tint/resolver/var_let_test.cc
index 4e6eaa7..a59855a 100644
--- a/src/tint/resolver/var_let_test.cc
+++ b/src/tint/resolver/var_let_test.cc
@@ -18,6 +18,8 @@
 
 #include "gmock/gmock.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -95,12 +97,12 @@
     auto* S = Structure("S", {Member("i", ty.i32())});
     auto* A = Alias("A", ty.Of(S));
 
-    auto* i_c = Expr(1);
-    auto* u_c = Expr(1u);
+    auto* i_c = Expr(1_i);
+    auto* u_c = Expr(1_u);
     auto* f_c = Expr(1.f);
     auto* b_c = Expr(true);
-    auto* s_c = Construct(ty.Of(S), Expr(1));
-    auto* a_c = Construct(ty.Of(A), Expr(1));
+    auto* s_c = Construct(ty.Of(S), Expr(1_i));
+    auto* a_c = Construct(ty.Of(A), Expr(1_i));
 
     auto* i = Var("i", ty.i32(), ast::StorageClass::kNone, i_c);
     auto* u = Var("u", ty.u32(), ast::StorageClass::kNone, u_c);
@@ -148,7 +150,7 @@
     // struct S { i : i32; }
     // fn F(){
     //   var v : i32;
-    //   let i : i32 = 1;
+    //   let i : i32 = 1i;
     //   let u : u32 = 1u;
     //   let f : f32 = 1.;
     //   let b : bool = true;
@@ -161,12 +163,12 @@
     auto* A = Alias("A", ty.Of(S));
     auto* v = Var("v", ty.i32(), ast::StorageClass::kNone);
 
-    auto* i_c = Expr(1);
-    auto* u_c = Expr(1u);
+    auto* i_c = Expr(1_i);
+    auto* u_c = Expr(1_u);
     auto* f_c = Expr(1.f);
     auto* b_c = Expr(true);
-    auto* s_c = Construct(ty.Of(S), Expr(1));
-    auto* a_c = Construct(ty.Of(A), Expr(1));
+    auto* s_c = Construct(ty.Of(S), Expr(1_i));
+    auto* a_c = Construct(ty.Of(A), Expr(1_i));
     auto* p_c = AddressOf(v);
 
     auto* i = Let("i", ty.i32(), i_c);
@@ -278,7 +280,7 @@
     // }
     // @group(0) @binding(0) var<storage, read_write> s : S;
     // fn f() {
-    //   let p = &s.inner.arr[2];
+    //   let p = &s.inner.arr[4];
     // }
     auto* inner = Structure("Inner", {Member("arr", ty.array<i32, 4>())});
     auto* buf = Structure("S", {Member("inner", ty.Of(inner))});
@@ -288,7 +290,7 @@
                                create<ast::GroupAttribute>(0),
                            });
 
-    auto* expr = IndexAccessor(MemberAccessor(MemberAccessor(storage, "inner"), "arr"), 4);
+    auto* expr = IndexAccessor(MemberAccessor(MemberAccessor(storage, "inner"), "arr"), 4_i);
     auto* ptr = Let("p", nullptr, AddressOf(expr));
 
     WrapInFunction(ptr);
@@ -444,7 +446,7 @@
     //   let a = (a == 321);
     // }
 
-    auto* g = GlobalConst("a", ty.i32(), Expr(1));
+    auto* g = GlobalConst("a", ty.i32(), Expr(1_i));
     auto* v = Var("a", nullptr, Expr("a"));
     auto* l = Let("a", nullptr, Expr("a"));
     Func("X", {}, ty.void_(), {Decl(v)});
@@ -483,7 +485,7 @@
     //   }
     // }
 
-    auto* s = Var("a", ty.i32(), Expr(1));
+    auto* s = Var("a", ty.i32(), Expr(1_i));
     auto* v = Var("a", nullptr, Expr("a"));
     auto* l = Let("a", nullptr, Expr("a"));
     Func("X", {}, ty.void_(), {Decl(s), Block(Decl(v)), Block(Decl(l))});
@@ -522,7 +524,7 @@
     //   }
     // }
 
-    auto* s = Let("a", ty.i32(), Expr(1));
+    auto* s = Let("a", ty.i32(), Expr(1_i));
     auto* v = Var("a", nullptr, Expr("a"));
     auto* l = Let("a", nullptr, Expr("a"));
     Func("X", {}, ty.void_(), {Decl(s), Block(Decl(v)), Block(Decl(l))});
@@ -633,7 +635,7 @@
     // fn F(a : bool) {
     // }
 
-    auto* g = GlobalConst("a", ty.i32(), Expr(1));
+    auto* g = GlobalConst("a", ty.i32(), Expr(1_i));
     auto* p = Param("a", ty.bool_());
     Func("F", {p}, ty.void_(), {});
 
diff --git a/src/tint/resolver/var_let_validation_test.cc b/src/tint/resolver/var_let_validation_test.cc
index caa47d0..ff63918 100644
--- a/src/tint/resolver/var_let_validation_test.cc
+++ b/src/tint/resolver/var_let_validation_test.cc
@@ -17,6 +17,8 @@
 
 #include "gmock/gmock.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::resolver {
 namespace {
 
@@ -86,7 +88,7 @@
 
 TEST_F(ResolverVarLetValidationTest, LetConstructorWrongType) {
     // var v : i32 = 2u
-    WrapInFunction(Let(Source{{3, 3}}, "v", ty.i32(), Expr(2u)));
+    WrapInFunction(Let(Source{{3, 3}}, "v", ty.i32(), Expr(2_u)));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -95,7 +97,7 @@
 
 TEST_F(ResolverVarLetValidationTest, VarConstructorWrongType) {
     // var v : i32 = 2u
-    WrapInFunction(Var(Source{{3, 3}}, "v", ty.i32(), ast::StorageClass::kNone, Expr(2u)));
+    WrapInFunction(Var(Source{{3, 3}}, "v", ty.i32(), ast::StorageClass::kNone, Expr(2_u)));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -104,7 +106,7 @@
 
 TEST_F(ResolverVarLetValidationTest, LetConstructorWrongTypeViaAlias) {
     auto* a = Alias("I32", ty.i32());
-    WrapInFunction(Let(Source{{3, 3}}, "v", ty.Of(a), Expr(2u)));
+    WrapInFunction(Let(Source{{3, 3}}, "v", ty.Of(a), Expr(2_u)));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -113,7 +115,7 @@
 
 TEST_F(ResolverVarLetValidationTest, VarConstructorWrongTypeViaAlias) {
     auto* a = Alias("I32", ty.i32());
-    WrapInFunction(Var(Source{{3, 3}}, "v", ty.Of(a), ast::StorageClass::kNone, Expr(2u)));
+    WrapInFunction(Var(Source{{3, 3}}, "v", ty.Of(a), ast::StorageClass::kNone, Expr(2_u)));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -139,7 +141,7 @@
     // let l : f32 = 1.;
     // let l : i32 = 0;
     auto* l1 = Let("l", ty.f32(), Expr(1.f));
-    auto* l2 = Let(Source{{12, 34}}, "l", ty.i32(), Expr(0));
+    auto* l2 = Let(Source{{12, 34}}, "l", ty.i32(), Expr(0_i));
     WrapInFunction(l1, l2);
 
     EXPECT_FALSE(r()->Resolve());
@@ -204,7 +206,7 @@
     // }
     // @group(0) @binding(0) var<storage> s : S;
     // fn f() {
-    //   let p : pointer<storage, i32, read_write> = &s.inner.arr[2];
+    //   let p : pointer<storage, i32, read_write> = &s.inner.arr[2i];
     // }
     auto* inner = Structure("Inner", {Member("arr", ty.array<i32, 4>())});
     auto* buf = Structure("S", {Member("inner", ty.Of(inner))});
@@ -214,7 +216,7 @@
                                create<ast::GroupAttribute>(0),
                            });
 
-    auto* expr = IndexAccessor(MemberAccessor(MemberAccessor(storage, "inner"), "arr"), 4);
+    auto* expr = IndexAccessor(MemberAccessor(MemberAccessor(storage, "inner"), "arr"), 2_i);
     auto* ptr =
         Let(Source{{12, 34}}, "p",
             ty.pointer<i32>(ast::StorageClass::kStorage, ast::Access::kReadWrite), AddressOf(expr));
diff --git a/src/tint/sem/constant.cc b/src/tint/sem/constant.cc
index c4374d7..f5c82a2 100644
--- a/src/tint/sem/constant.cc
+++ b/src/tint/sem/constant.cc
@@ -63,9 +63,9 @@
     for (size_t i = 0; i < Elements().size(); ++i) {
         if (WithScalarAt(i, [&](auto&& s) {
                 // Use std::equal_to to work around -Wfloat-equal warnings
-                auto equals_to = std::equal_to<std::remove_reference_t<decltype(s)>>{};
-
-                if (equals_to(s, 0)) {
+                using T = std::remove_reference_t<decltype(s)>;
+                auto equal_to = std::equal_to<T>{};
+                if (equal_to(s, T(0))) {
                     return true;
                 }
                 return false;
diff --git a/src/tint/sem/constant.h b/src/tint/sem/constant.h
index cfb8f13..673446f 100644
--- a/src/tint/sem/constant.h
+++ b/src/tint/sem/constant.h
@@ -25,34 +25,30 @@
 /// A Constant is compile-time known expression value, expressed as a flattened
 /// list of scalar values. Value may be of a scalar or vector type.
 class Constant {
-    using i32 = ProgramBuilder::i32;
-    using u32 = ProgramBuilder::u32;
-    using f32 = ProgramBuilder::f32;
-
   public:
     /// Scalar holds a single constant scalar value, as a union of an i32, u32,
     /// f32 or boolean.
     union Scalar {
         /// The scalar value as a i32
-        int32_t i32;
+        tint::i32 i32;
         /// The scalar value as a u32
-        uint32_t u32;
+        tint::u32 u32;
         /// The scalar value as a f32
-        float f32;
+        tint::f32 f32;
         /// The scalar value as a bool
         bool bool_;
 
         /// Constructs the scalar with the i32 value `v`
         /// @param v the value of the Scalar
-        Scalar(ProgramBuilder::i32 v) : i32(v) {}  // NOLINT
+        Scalar(tint::i32 v) : i32(v) {}  // NOLINT
 
         /// Constructs the scalar with the u32 value `v`
         /// @param v the value of the Scalar
-        Scalar(ProgramBuilder::u32 v) : u32(v) {}  // NOLINT
+        Scalar(tint::u32 v) : u32(v) {}  // NOLINT
 
         /// Constructs the scalar with the f32 value `v`
         /// @param v the value of the Scalar
-        Scalar(ProgramBuilder::f32 v) : f32(v) {}  // NOLINT
+        Scalar(tint::f32 v) : f32(v) {}  // NOLINT
 
         /// Constructs the scalar with the bool value `v`
         /// @param v the value of the Scalar
@@ -106,22 +102,18 @@
     /// @return the value returned by func.
     template <typename Func>
     auto WithScalarAt(size_t index, Func&& func) const {
-        auto* elem_type = ElementType();
-        if (elem_type->Is<I32>()) {
-            return func(elems_[index].i32);
-        }
-        if (elem_type->Is<U32>()) {
-            return func(elems_[index].u32);
-        }
-        if (elem_type->Is<F32>()) {
-            return func(elems_[index].f32);
-        }
-        if (elem_type->Is<Bool>()) {
-            return func(elems_[index].bool_);
-        }
-        diag::List diags;
-        TINT_UNREACHABLE(Semantic, diags) << "invalid scalar type " << type_->TypeInfo().name;
-        return func(~0);
+        return Switch(
+            ElementType(),  //
+            [&](const I32*) { return func(elems_[index].i32); },
+            [&](const U32*) { return func(elems_[index].u32); },
+            [&](const F32*) { return func(elems_[index].f32); },
+            [&](const Bool*) { return func(elems_[index].bool_); },
+            [&](Default) {
+                diag::List diags;
+                TINT_UNREACHABLE(Semantic, diags)
+                    << "invalid scalar type " << type_->TypeInfo().name;
+                return func(u32(0u));
+            });
     }
 
     /// @param index the index of the scalar value
diff --git a/src/tint/transform/add_empty_entry_point.cc b/src/tint/transform/add_empty_entry_point.cc
index 18c5688..f037649 100644
--- a/src/tint/transform/add_empty_entry_point.cc
+++ b/src/tint/transform/add_empty_entry_point.cc
@@ -20,6 +20,8 @@
 
 TINT_INSTANTIATE_TYPEINFO(tint::transform::AddEmptyEntryPoint);
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::transform {
 
 AddEmptyEntryPoint::AddEmptyEntryPoint() = default;
@@ -37,7 +39,7 @@
 
 void AddEmptyEntryPoint::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
     ctx.dst->Func(ctx.dst->Symbols().New("unused_entry_point"), {}, ctx.dst->ty.void_(), {},
-                  {ctx.dst->Stage(ast::PipelineStage::kCompute), ctx.dst->WorkgroupSize(1)});
+                  {ctx.dst->Stage(ast::PipelineStage::kCompute), ctx.dst->WorkgroupSize(1_i)});
     ctx.Clone();
 }
 
diff --git a/src/tint/transform/add_empty_entry_point_test.cc b/src/tint/transform/add_empty_entry_point_test.cc
index cbbd9c3..2f8a7ad 100644
--- a/src/tint/transform/add_empty_entry_point_test.cc
+++ b/src/tint/transform/add_empty_entry_point_test.cc
@@ -42,7 +42,7 @@
     auto* src = R"()";
 
     auto* expect = R"(
-@stage(compute) @workgroup_size(1)
+@stage(compute) @workgroup_size(1i)
 fn unused_entry_point() {
 }
 )";
@@ -70,7 +70,7 @@
     auto* src = R"(var<private> unused_entry_point : f32;)";
 
     auto* expect = R"(
-@stage(compute) @workgroup_size(1)
+@stage(compute) @workgroup_size(1i)
 fn unused_entry_point_1() {
 }
 
diff --git a/src/tint/transform/array_length_from_uniform.cc b/src/tint/transform/array_length_from_uniform.cc
index 0741ee77..dc19c5c 100644
--- a/src/tint/transform/array_length_from_uniform.cc
+++ b/src/tint/transform/array_length_from_uniform.cc
@@ -143,7 +143,7 @@
                 ctx.dst->Sym(),
                 {ctx.dst->Member(kBufferSizeMemberName,
                                  ctx.dst->ty.array(ctx.dst->ty.vec4(ctx.dst->ty.u32()),
-                                                   (max_buffer_size_index / 4) + 1))});
+                                                   u32((max_buffer_size_index / 4) + 1)))});
             buffer_size_ubo = ctx.dst->Global(
                 ctx.dst->Sym(), ctx.dst->ty.Of(buffer_size_struct), ast::StorageClass::kUniform,
                 ast::AttributeList{
@@ -154,50 +154,50 @@
 
     std::unordered_set<uint32_t> used_size_indices;
 
-    IterateArrayLengthOnStorageVar(
-        ctx, [&](const ast::CallExpression* call_expr, const sem::VariableUser* storage_buffer_sem,
-                 const sem::GlobalVariable* var) {
-            auto binding = var->BindingPoint();
-            auto idx_itr = cfg->bindpoint_to_size_index.find(binding);
-            if (idx_itr == cfg->bindpoint_to_size_index.end()) {
-                return;
-            }
+    IterateArrayLengthOnStorageVar(ctx, [&](const ast::CallExpression* call_expr,
+                                            const sem::VariableUser* storage_buffer_sem,
+                                            const sem::GlobalVariable* var) {
+        auto binding = var->BindingPoint();
+        auto idx_itr = cfg->bindpoint_to_size_index.find(binding);
+        if (idx_itr == cfg->bindpoint_to_size_index.end()) {
+            return;
+        }
 
-            uint32_t size_index = idx_itr->second;
-            used_size_indices.insert(size_index);
+        uint32_t size_index = idx_itr->second;
+        used_size_indices.insert(size_index);
 
-            // Load the total storage buffer size from the UBO.
-            uint32_t array_index = size_index / 4;
-            auto* vec_expr = ctx.dst->IndexAccessor(
-                ctx.dst->MemberAccessor(get_ubo()->symbol, kBufferSizeMemberName), array_index);
-            uint32_t vec_index = size_index % 4;
-            auto* total_storage_buffer_size = ctx.dst->IndexAccessor(vec_expr, vec_index);
+        // Load the total storage buffer size from the UBO.
+        uint32_t array_index = size_index / 4;
+        auto* vec_expr = ctx.dst->IndexAccessor(
+            ctx.dst->MemberAccessor(get_ubo()->symbol, kBufferSizeMemberName), u32(array_index));
+        uint32_t vec_index = size_index % 4;
+        auto* total_storage_buffer_size = ctx.dst->IndexAccessor(vec_expr, u32(vec_index));
 
-            // Calculate actual array length
-            //                total_storage_buffer_size - array_offset
-            // array_length = ----------------------------------------
-            //                             array_stride
-            const ast::Expression* total_size = total_storage_buffer_size;
-            auto* storage_buffer_type = storage_buffer_sem->Type()->UnwrapRef();
-            const sem::Array* array_type = nullptr;
-            if (auto* str = storage_buffer_type->As<sem::Struct>()) {
-                // The variable is a struct, so subtract the byte offset of the array
-                // member.
-                auto* array_member_sem = str->Members().back();
-                array_type = array_member_sem->Type()->As<sem::Array>();
-                total_size = ctx.dst->Sub(total_storage_buffer_size, array_member_sem->Offset());
-            } else if (auto* arr = storage_buffer_type->As<sem::Array>()) {
-                array_type = arr;
-            } else {
-                TINT_ICE(Transform, ctx.dst->Diagnostics())
-                    << "expected form of arrayLength argument to be &array_var or "
-                       "&struct_var.array_member";
-                return;
-            }
-            auto* array_length = ctx.dst->Div(total_size, array_type->Stride());
+        // Calculate actual array length
+        //                total_storage_buffer_size - array_offset
+        // array_length = ----------------------------------------
+        //                             array_stride
+        const ast::Expression* total_size = total_storage_buffer_size;
+        auto* storage_buffer_type = storage_buffer_sem->Type()->UnwrapRef();
+        const sem::Array* array_type = nullptr;
+        if (auto* str = storage_buffer_type->As<sem::Struct>()) {
+            // The variable is a struct, so subtract the byte offset of the array
+            // member.
+            auto* array_member_sem = str->Members().back();
+            array_type = array_member_sem->Type()->As<sem::Array>();
+            total_size = ctx.dst->Sub(total_storage_buffer_size, u32(array_member_sem->Offset()));
+        } else if (auto* arr = storage_buffer_type->As<sem::Array>()) {
+            array_type = arr;
+        } else {
+            TINT_ICE(Transform, ctx.dst->Diagnostics())
+                << "expected form of arrayLength argument to be &array_var or "
+                   "&struct_var.array_member";
+            return;
+        }
+        auto* array_length = ctx.dst->Div(total_size, u32(array_type->Stride()));
 
-            ctx.Replace(call_expr, array_length);
-        });
+        ctx.Replace(call_expr, array_length);
+    });
 
     ctx.Clone();
 
diff --git a/src/tint/transform/builtin_polyfill.cc b/src/tint/transform/builtin_polyfill.cc
index ba4be61..9bde1cc 100644
--- a/src/tint/transform/builtin_polyfill.cc
+++ b/src/tint/transform/builtin_polyfill.cc
@@ -21,6 +21,8 @@
 #include "src/tint/sem/call.h"
 #include "src/tint/utils/map.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 TINT_INSTANTIATE_TYPEINFO(tint::transform::BuiltinPolyfill);
 TINT_INSTANTIATE_TYPEINFO(tint::transform::BuiltinPolyfill::Config);
 
@@ -57,7 +59,7 @@
             return b.ty.vec<u32>(width);
         };
         auto V = [&](uint32_t value) -> const ast::Expression* {
-            return ScalarOrVector(width, value);
+            return ScalarOrVector(width, u32(value));
         };
         b.Func(
             name, {b.Param("v", T(ty))}, T(ty),
@@ -112,7 +114,7 @@
             return b.ty.vec<u32>(width);
         };
         auto V = [&](uint32_t value) -> const ast::Expression* {
-            return ScalarOrVector(width, value);
+            return ScalarOrVector(width, u32(value));
         };
         auto B = [&](const ast::Expression* value) -> const ast::Expression* {
             if (width == 1) {
@@ -175,13 +177,13 @@
         };
 
         ast::StatementList body = {
-            b.Decl(b.Let("s", nullptr, b.Call("min", "offset", W))),
-            b.Decl(b.Let("e", nullptr, b.Call("min", W, b.Add("s", "count")))),
+            b.Decl(b.Let("s", nullptr, b.Call("min", "offset", u32(W)))),
+            b.Decl(b.Let("e", nullptr, b.Call("min", u32(W), b.Add("s", "count")))),
         };
 
         switch (polyfill.extract_bits) {
             case Level::kFull:
-                body.emplace_back(b.Decl(b.Let("shl", nullptr, b.Sub(W, "e"))));
+                body.emplace_back(b.Decl(b.Let("shl", nullptr, b.Sub(u32(W), "e"))));
                 body.emplace_back(b.Decl(b.Let("shr", nullptr, b.Add("shl", "s"))));
                 body.emplace_back(
                     b.Return(b.Shr(b.Shl("v", vecN_u32(b.Expr("shl"))), vecN_u32(b.Expr("shr")))));
@@ -221,7 +223,7 @@
             return b.ty.vec<u32>(width);
         };
         auto V = [&](uint32_t value) -> const ast::Expression* {
-            return ScalarOrVector(width, value);
+            return ScalarOrVector(width, u32(value));
         };
         auto B = [&](const ast::Expression* value) -> const ast::Expression* {
             if (width == 1) {
@@ -238,7 +240,7 @@
             x = b.Call("select",                             //
                        b.Construct(U(), "v"),                //
                        b.Construct(U(), b.Complement("v")),  //
-                       b.LessThan("v", ScalarOrVector(width, 0)));
+                       b.LessThan("v", ScalarOrVector(width, 0_i)));
         }
 
         b.Func(
@@ -295,7 +297,7 @@
             return b.ty.vec<u32>(width);
         };
         auto V = [&](uint32_t value) -> const ast::Expression* {
-            return ScalarOrVector(width, value);
+            return ScalarOrVector(width, u32(value));
         };
         auto B = [&](const ast::Expression* value) -> const ast::Expression* {
             if (width == 1) {
@@ -368,15 +370,16 @@
         };
 
         ast::StatementList body = {
-            b.Decl(b.Let("s", nullptr, b.Call("min", "offset", W))),
-            b.Decl(b.Let("e", nullptr, b.Call("min", W, b.Add("s", "count")))),
+            b.Decl(b.Let("s", nullptr, b.Call("min", "offset", u32(W)))),
+            b.Decl(b.Let("e", nullptr, b.Call("min", u32(W), b.Add("s", "count")))),
         };
 
         switch (polyfill.insert_bits) {
             case Level::kFull:
                 // let mask = ((1 << s) - 1) ^ ((1 << e) - 1)
-                body.emplace_back(b.Decl(b.Let(
-                    "mask", nullptr, b.Xor(b.Sub(b.Shl(1u, "s"), 1u), b.Sub(b.Shl(1u, "e"), 1u)))));
+                body.emplace_back(
+                    b.Decl(b.Let("mask", nullptr,
+                                 b.Xor(b.Sub(b.Shl(1_u, "s"), 1_u), b.Sub(b.Shl(1_u, "e"), 1_u)))));
                 // return ((n << s) & mask) | (v & ~mask)
                 body.emplace_back(b.Return(b.Or(b.And(b.Shl("n", U("s")), V("mask")),
                                                 b.And("v", V(b.Complement("mask"))))));
@@ -403,10 +406,6 @@
     }
 
   private:
-    /// Aliases
-    using u32 = ProgramBuilder::u32;
-    using i32 = ProgramBuilder::i32;
-
     /// @returns the AST type for the given sem type
     const ast::Type* T(const sem::Type* ty) const { return CreateASTTypeFor(ctx, ty); }
 
diff --git a/src/tint/transform/builtin_polyfill_test.cc b/src/tint/transform/builtin_polyfill_test.cc
index e3a4eae..bc3dda8 100644
--- a/src/tint/transform/builtin_polyfill_test.cc
+++ b/src/tint/transform/builtin_polyfill_test.cc
@@ -604,7 +604,7 @@
 
     auto* expect = R"(
 fn tint_first_leading_bit(v : i32) -> i32 {
-  var x = select(u32(v), u32(~(v)), (v < 0));
+  var x = select(u32(v), u32(~(v)), (v < 0i));
   let b16 = select(0u, 16u, bool((x & 4294901760u)));
   x = (x >> b16);
   let b8 = select(0u, 8u, bool((x & 65280u)));
@@ -670,7 +670,7 @@
 
     auto* expect = R"(
 fn tint_first_leading_bit(v : vec3<i32>) -> vec3<i32> {
-  var x = select(vec3<u32>(v), vec3<u32>(~(v)), (v < vec3<i32>(0)));
+  var x = select(vec3<u32>(v), vec3<u32>(~(v)), (v < vec3<i32>(0i)));
   let b16 = select(vec3<u32>(0u), vec3<u32>(16u), vec3<bool>((x & vec3<u32>(4294901760u))));
   x = (x >> b16);
   let b8 = select(vec3<u32>(0u), vec3<u32>(8u), vec3<bool>((x & vec3<u32>(65280u))));
diff --git a/src/tint/transform/calculate_array_length.cc b/src/tint/transform/calculate_array_length.cc
index c2128c7..42a212c 100644
--- a/src/tint/transform/calculate_array_length.cc
+++ b/src/tint/transform/calculate_array_length.cc
@@ -33,6 +33,8 @@
 TINT_INSTANTIATE_TYPEINFO(tint::transform::CalculateArrayLength);
 TINT_INSTANTIATE_TYPEINFO(tint::transform::CalculateArrayLength::BufferSizeIntrinsic);
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::transform {
 
 namespace {
@@ -168,7 +170,7 @@
                             // RWByteAddressBuffer.GetDimensions()
                             auto* buffer_size_result = ctx.dst->Decl(
                                 ctx.dst->Var(ctx.dst->Sym(), ctx.dst->ty.u32(),
-                                             ast::StorageClass::kNone, ctx.dst->Expr(0u)));
+                                             ast::StorageClass::kNone, ctx.dst->Expr(0_u)));
 
                             // Call storage_buffer.GetDimensions(&buffer_size_result)
                             auto* call_get_dims = ctx.dst->CallStmt(ctx.dst->Call(
@@ -192,7 +194,8 @@
                                 // the array member.
                                 auto* array_member_sem = str->Members().back();
                                 array_type = array_member_sem->Type()->As<sem::Array>();
-                                total_size = ctx.dst->Sub(total_size, array_member_sem->Offset());
+                                total_size =
+                                    ctx.dst->Sub(total_size, u32(array_member_sem->Offset()));
                             } else if (auto* arr = storage_buffer_type->As<sem::Array>()) {
                                 array_type = arr;
                             } else {
@@ -202,8 +205,9 @@
                                 return name;
                             }
                             uint32_t array_stride = array_type->Size();
-                            auto* array_length_var = ctx.dst->Decl(ctx.dst->Let(
-                                name, ctx.dst->ty.u32(), ctx.dst->Div(total_size, array_stride)));
+                            auto* array_length_var = ctx.dst->Decl(
+                                ctx.dst->Let(name, ctx.dst->ty.u32(),
+                                             ctx.dst->Div(total_size, u32(array_stride))));
 
                             // Insert the array length calculations at the top of the block
                             ctx.InsertBefore(block->statements, block->statements[0],
diff --git a/src/tint/transform/canonicalize_entry_point_io.cc b/src/tint/transform/canonicalize_entry_point_io.cc
index 06f9f6b..aeafa1b 100644
--- a/src/tint/transform/canonicalize_entry_point_io.cc
+++ b/src/tint/transform/canonicalize_entry_point_io.cc
@@ -25,6 +25,8 @@
 #include "src/tint/sem/function.h"
 #include "src/tint/transform/unshadow.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 TINT_INSTANTIATE_TYPEINFO(tint::transform::CanonicalizeEntryPointIO);
 TINT_INSTANTIATE_TYPEINFO(tint::transform::CanonicalizeEntryPointIO::Config);
 
@@ -190,8 +192,8 @@
                 } else if (builtin->builtin == ast::Builtin::kSampleMask) {
                     // Vulkan requires the type of a SampleMask builtin to be an array.
                     // Declare it as array<u32, 1> and then load the first element.
-                    ast_type = ctx.dst->ty.array(ast_type, 1);
-                    value = ctx.dst->IndexAccessor(value, 0);
+                    ast_type = ctx.dst->ty.array(ast_type, 1_u);
+                    value = ctx.dst->IndexAccessor(value, 0_i);
                 }
             }
             ctx.dst->Global(symbol, ast_type, ast::StorageClass::kInput, std::move(attributes));
@@ -356,7 +358,7 @@
         for (auto& outval : wrapper_output_values) {
             if (HasSampleMask(outval.attributes)) {
                 // Combine the authored sample mask with the fixed mask.
-                outval.value = ctx.dst->And(outval.value, cfg.fixed_sample_mask);
+                outval.value = ctx.dst->And(outval.value, u32(cfg.fixed_sample_mask));
                 return;
             }
         }
@@ -365,7 +367,7 @@
         // using the fixed sample mask.
         AddOutput("fixed_sample_mask", ctx.dst->create<sem::U32>(),
                   {ctx.dst->Builtin(ast::Builtin::kSampleMask)},
-                  ctx.dst->Expr(cfg.fixed_sample_mask));
+                  ctx.dst->Expr(u32(cfg.fixed_sample_mask)));
     }
 
     /// Add a point size builtin to the wrapper function output.
@@ -458,8 +460,8 @@
             if (HasSampleMask(attributes)) {
                 // Vulkan requires the type of a SampleMask builtin to be an array.
                 // Declare it as array<u32, 1> and then store to the first element.
-                type = ctx.dst->ty.array(type, 1);
-                lhs = ctx.dst->IndexAccessor(lhs, 0);
+                type = ctx.dst->ty.array(type, 1_u);
+                lhs = ctx.dst->IndexAccessor(lhs, 0_i);
             }
             ctx.dst->Global(name, type, ast::StorageClass::kOutput, std::move(attributes));
             wrapper_body.push_back(ctx.dst->Assign(lhs, outval.value));
@@ -668,9 +670,9 @@
             case ast::Builtin::kSampleMask:
                 // gl_SampleMask is an array of i32. Retrieve the first element and
                 // bitcast it to u32.
-                value = ctx.dst->IndexAccessor(value, 0);
+                value = ctx.dst->IndexAccessor(value, 0_i);
                 value = ctx.dst->Bitcast(ast_type, value);
-                ast_type = ctx.dst->ty.array(ctx.dst->ty.i32(), 1);
+                ast_type = ctx.dst->ty.array(ctx.dst->ty.i32(), 1_u);
                 break;
             default:
                 break;
diff --git a/src/tint/transform/canonicalize_entry_point_io_test.cc b/src/tint/transform/canonicalize_entry_point_io_test.cc
index 70a3ad5..d3fe95a 100644
--- a/src/tint/transform/canonicalize_entry_point_io_test.cc
+++ b/src/tint/transform/canonicalize_entry_point_io_test.cc
@@ -678,7 +678,7 @@
 
 @builtin(frag_depth) @internal(disable_validation__ignore_storage_class) var<out> depth_1 : f32;
 
-@builtin(sample_mask) @internal(disable_validation__ignore_storage_class) var<out> mask_1 : array<u32, 1>;
+@builtin(sample_mask) @internal(disable_validation__ignore_storage_class) var<out> mask_1 : array<u32, 1u>;
 
 struct FragOutput {
   color : vec4<f32>,
@@ -699,7 +699,7 @@
   let inner_result = frag_main_inner();
   color_1 = inner_result.color;
   depth_1 = inner_result.depth;
-  mask_1[0] = inner_result.mask;
+  mask_1[0i] = inner_result.mask;
 }
 )";
 
@@ -733,7 +733,7 @@
 
 @builtin(frag_depth) @internal(disable_validation__ignore_storage_class) var<out> depth_1 : f32;
 
-@builtin(sample_mask) @internal(disable_validation__ignore_storage_class) var<out> mask_1 : array<u32, 1>;
+@builtin(sample_mask) @internal(disable_validation__ignore_storage_class) var<out> mask_1 : array<u32, 1u>;
 
 fn frag_main_inner() -> FragOutput {
   var output : FragOutput;
@@ -748,7 +748,7 @@
   let inner_result = frag_main_inner();
   color_1 = inner_result.color;
   depth_1 = inner_result.depth;
-  mask_1[0] = inner_result.mask;
+  mask_1[0i] = inner_result.mask;
 }
 
 struct FragOutput {
@@ -3870,9 +3870,9 @@
     auto* expect = R"(
 @builtin(sample_index) @internal(disable_validation__ignore_storage_class) var<in> sample_index_1 : u32;
 
-@builtin(sample_mask) @internal(disable_validation__ignore_storage_class) var<in> mask_in_1 : array<u32, 1>;
+@builtin(sample_mask) @internal(disable_validation__ignore_storage_class) var<in> mask_in_1 : array<u32, 1u>;
 
-@builtin(sample_mask) @internal(disable_validation__ignore_storage_class) var<out> value : array<u32, 1>;
+@builtin(sample_mask) @internal(disable_validation__ignore_storage_class) var<out> value : array<u32, 1u>;
 
 fn main_inner(sample_index : u32, mask_in : u32) -> u32 {
   return mask_in;
@@ -3880,8 +3880,8 @@
 
 @stage(fragment)
 fn main() {
-  let inner_result = main_inner(sample_index_1, mask_in_1[0]);
-  value[0] = inner_result;
+  let inner_result = main_inner(sample_index_1, mask_in_1[0i]);
+  value[0i] = inner_result;
 }
 )";
 
@@ -3905,9 +3905,9 @@
     auto* expect = R"(
 @builtin(sample_index) @internal(disable_validation__ignore_storage_class) var<in> gl_SampleID : i32;
 
-@builtin(sample_mask) @internal(disable_validation__ignore_storage_class) var<in> gl_SampleMaskIn : array<i32, 1>;
+@builtin(sample_mask) @internal(disable_validation__ignore_storage_class) var<in> gl_SampleMaskIn : array<i32, 1u>;
 
-@builtin(sample_mask) @internal(disable_validation__ignore_storage_class) var<out> gl_SampleMask : array<i32, 1>;
+@builtin(sample_mask) @internal(disable_validation__ignore_storage_class) var<out> gl_SampleMask : array<i32, 1u>;
 
 fn fragment_main(sample_index : u32, mask_in : u32) -> u32 {
   return mask_in;
@@ -3915,8 +3915,8 @@
 
 @stage(fragment)
 fn main() {
-  let inner_result = fragment_main(bitcast<u32>(gl_SampleID), bitcast<u32>(gl_SampleMaskIn[0]));
-  gl_SampleMask[0] = bitcast<i32>(inner_result);
+  let inner_result = fragment_main(bitcast<u32>(gl_SampleID), bitcast<u32>(gl_SampleMaskIn[0i]));
+  gl_SampleMask[0i] = bitcast<i32>(inner_result);
 }
 )";
 
diff --git a/src/tint/transform/decompose_memory_access.cc b/src/tint/transform/decompose_memory_access.cc
index 6387d68..66c6073 100644
--- a/src/tint/transform/decompose_memory_access.cc
+++ b/src/tint/transform/decompose_memory_access.cc
@@ -38,6 +38,8 @@
 #include "src/tint/utils/hash.h"
 #include "src/tint/utils/map.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 TINT_INSTANTIATE_TYPEINFO(tint::transform::DecomposeMemoryAccess);
 TINT_INSTANTIATE_TYPEINFO(tint::transform::DecomposeMemoryAccess::Intrinsic);
 
@@ -63,7 +65,7 @@
         auto* type = ctx.src->Sem().Get(expr)->Type()->UnwrapRef();
         auto* res = ctx.Clone(expr);
         if (!type->Is<sem::U32>()) {
-            res = ctx.dst->Construct<ProgramBuilder::u32>(res);
+            res = ctx.dst->Construct<u32>(res);
         }
         return res;
     }
@@ -77,7 +79,7 @@
     explicit OffsetLiteral(uint32_t lit) : literal(lit) {}
 
     const ast::Expression* Build(CloneContext& ctx) const override {
-        return ctx.dst->Expr(literal);
+        return ctx.dst->Expr(u32(literal));
     }
 };
 
@@ -467,13 +469,13 @@
                 // }
                 auto load = LoadFunc(buf_ty, arr_ty->ElemType()->UnwrapRef(), var_user);
                 auto* arr = b.Var(b.Symbols().New("arr"), CreateASTTypeFor(ctx, arr_ty));
-                auto* i = b.Var(b.Symbols().New("i"), nullptr, b.Expr(0u));
+                auto* i = b.Var(b.Symbols().New("i"), nullptr, b.Expr(0_u));
                 auto* for_init = b.Decl(i);
                 auto* for_cond = b.create<ast::BinaryExpression>(
-                    ast::BinaryOp::kLessThan, b.Expr(i), b.Expr(arr_ty->Count()));
-                auto* for_cont = b.Assign(i, b.Add(i, 1u));
+                    ast::BinaryOp::kLessThan, b.Expr(i), b.Expr(u32(arr_ty->Count())));
+                auto* for_cont = b.Assign(i, b.Add(i, 1_u));
                 auto* arr_el = b.IndexAccessor(arr, i);
-                auto* el_offset = b.Add(b.Expr("offset"), b.Mul(i, arr_ty->Stride()));
+                auto* el_offset = b.Add(b.Expr("offset"), b.Mul(i, u32(arr_ty->Stride())));
                 auto* el_val = b.Call(load, "buffer", el_offset);
                 auto* for_loop =
                     b.For(for_init, for_cond, for_cont, b.Block(b.Assign(arr_el, el_val)));
@@ -490,12 +492,12 @@
                     auto* vec_ty = mat_ty->ColumnType();
                     Symbol load = LoadFunc(buf_ty, vec_ty, var_user);
                     for (uint32_t i = 0; i < mat_ty->columns(); i++) {
-                        auto* offset = b.Add("offset", i * mat_ty->ColumnStride());
+                        auto* offset = b.Add("offset", u32(i * mat_ty->ColumnStride()));
                         values.emplace_back(b.Call(load, "buffer", offset));
                     }
                 } else if (auto* str = el_ty->As<sem::Struct>()) {
                     for (auto* member : str->Members()) {
-                        auto* offset = b.Add("offset", member->Offset());
+                        auto* offset = b.Add("offset", u32(member->Offset()));
                         Symbol load = LoadFunc(buf_ty, member->Type()->UnwrapRef(), var_user);
                         values.emplace_back(b.Call(load, "buffer", offset));
                     }
@@ -561,13 +563,13 @@
                     // }
                     auto* array = b.Var(b.Symbols().New("array"), nullptr, b.Expr("value"));
                     auto store = StoreFunc(buf_ty, arr_ty->ElemType()->UnwrapRef(), var_user);
-                    auto* i = b.Var(b.Symbols().New("i"), nullptr, b.Expr(0u));
+                    auto* i = b.Var(b.Symbols().New("i"), nullptr, b.Expr(0_u));
                     auto* for_init = b.Decl(i);
                     auto* for_cond = b.create<ast::BinaryExpression>(
-                        ast::BinaryOp::kLessThan, b.Expr(i), b.Expr(arr_ty->Count()));
-                    auto* for_cont = b.Assign(i, b.Add(i, 1u));
+                        ast::BinaryOp::kLessThan, b.Expr(i), b.Expr(u32(arr_ty->Count())));
+                    auto* for_cont = b.Assign(i, b.Add(i, 1_u));
                     auto* arr_el = b.IndexAccessor(array, i);
-                    auto* el_offset = b.Add(b.Expr("offset"), b.Mul(i, arr_ty->Stride()));
+                    auto* el_offset = b.Add(b.Expr("offset"), b.Mul(i, u32(arr_ty->Stride())));
                     auto* store_stmt = b.CallStmt(b.Call(store, "buffer", el_offset, arr_el));
                     auto* for_loop = b.For(for_init, for_cond, for_cont, b.Block(store_stmt));
 
@@ -576,14 +578,14 @@
                     auto* vec_ty = mat_ty->ColumnType();
                     Symbol store = StoreFunc(buf_ty, vec_ty, var_user);
                     for (uint32_t i = 0; i < mat_ty->columns(); i++) {
-                        auto* offset = b.Add("offset", i * mat_ty->ColumnStride());
-                        auto* access = b.IndexAccessor("value", i);
+                        auto* offset = b.Add("offset", u32(i * mat_ty->ColumnStride()));
+                        auto* access = b.IndexAccessor("value", u32(i));
                         auto* call = b.Call(store, "buffer", offset, access);
                         body.emplace_back(b.CallStmt(call));
                     }
                 } else if (auto* str = el_ty->As<sem::Struct>()) {
                     for (auto* member : str->Members()) {
-                        auto* offset = b.Add("offset", member->Offset());
+                        auto* offset = b.Add("offset", u32(member->Offset()));
                         auto* access =
                             b.MemberAccessor("value", ctx.Clone(member->Declaration()->symbol));
                         Symbol store = StoreFunc(buf_ty, member->Type()->UnwrapRef(), var_user);
diff --git a/src/tint/transform/decompose_strided_array_test.cc b/src/tint/transform/decompose_strided_array_test.cc
index 1891527..cd9d63c 100644
--- a/src/tint/transform/decompose_strided_array_test.cc
+++ b/src/tint/transform/decompose_strided_array_test.cc
@@ -23,11 +23,12 @@
 #include "src/tint/transform/test_helper.h"
 #include "src/tint/transform/unshadow.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::transform {
 namespace {
 
 using DecomposeStridedArrayTest = TransformTest;
-using f32 = ProgramBuilder::f32;
 
 TEST_F(DecomposeStridedArrayTest, ShouldRunEmptyModule) {
     ProgramBuilder b;
@@ -35,26 +36,26 @@
 }
 
 TEST_F(DecomposeStridedArrayTest, ShouldRunNonStridedArray) {
-    // var<private> arr : array<f32, 4>
+    // var<private> arr : array<f32, 4u>
 
     ProgramBuilder b;
-    b.Global("arr", b.ty.array<f32, 4>(), ast::StorageClass::kPrivate);
+    b.Global("arr", b.ty.array<f32, 4u>(), ast::StorageClass::kPrivate);
     EXPECT_FALSE(ShouldRun<DecomposeStridedArray>(Program(std::move(b))));
 }
 
 TEST_F(DecomposeStridedArrayTest, ShouldRunDefaultStridedArray) {
-    // var<private> arr : @stride(4) array<f32, 4>
+    // var<private> arr : @stride(4) array<f32, 4u>
 
     ProgramBuilder b;
-    b.Global("arr", b.ty.array<f32, 4>(4), ast::StorageClass::kPrivate);
+    b.Global("arr", b.ty.array<f32, 4u>(4), ast::StorageClass::kPrivate);
     EXPECT_TRUE(ShouldRun<DecomposeStridedArray>(Program(std::move(b))));
 }
 
 TEST_F(DecomposeStridedArrayTest, ShouldRunExplicitStridedArray) {
-    // var<private> arr : @stride(16) array<f32, 4>
+    // var<private> arr : @stride(16) array<f32, 4u>
 
     ProgramBuilder b;
-    b.Global("arr", b.ty.array<f32, 4>(16), ast::StorageClass::kPrivate);
+    b.Global("arr", b.ty.array<f32, 4u>(16), ast::StorageClass::kPrivate);
     EXPECT_TRUE(ShouldRun<DecomposeStridedArray>(Program(std::move(b))));
 }
 
@@ -68,33 +69,33 @@
 }
 
 TEST_F(DecomposeStridedArrayTest, PrivateDefaultStridedArray) {
-    // var<private> arr : @stride(4) array<f32, 4>
+    // var<private> arr : @stride(4) array<f32, 4u>
     //
     // @stage(compute) @workgroup_size(1)
     // fn f() {
-    //   let a : @stride(4) array<f32, 4> = a;
+    //   let a : @stride(4) array<f32, 4u> = a;
     //   let b : f32 = arr[1];
     // }
 
     ProgramBuilder b;
-    b.Global("arr", b.ty.array<f32, 4>(4), ast::StorageClass::kPrivate);
+    b.Global("arr", b.ty.array<f32, 4u>(4), ast::StorageClass::kPrivate);
     b.Func("f", {}, b.ty.void_(),
            {
-               b.Decl(b.Let("a", b.ty.array<f32, 4>(4), b.Expr("arr"))),
-               b.Decl(b.Let("b", b.ty.f32(), b.IndexAccessor("arr", 1))),
+               b.Decl(b.Let("a", b.ty.array<f32, 4u>(4), b.Expr("arr"))),
+               b.Decl(b.Let("b", b.ty.f32(), b.IndexAccessor("arr", 1_i))),
            },
            {
                b.Stage(ast::PipelineStage::kCompute),
-               b.WorkgroupSize(1),
+               b.WorkgroupSize(1_i),
            });
 
     auto* expect = R"(
-var<private> arr : array<f32, 4>;
+var<private> arr : array<f32, 4u>;
 
-@stage(compute) @workgroup_size(1)
+@stage(compute) @workgroup_size(1i)
 fn f() {
-  let a : array<f32, 4> = arr;
-  let b : f32 = arr[1];
+  let a : array<f32, 4u> = arr;
+  let b : f32 = arr[1i];
 }
 )";
 
@@ -104,24 +105,24 @@
 }
 
 TEST_F(DecomposeStridedArrayTest, PrivateStridedArray) {
-    // var<private> arr : @stride(32) array<f32, 4>
+    // var<private> arr : @stride(32) array<f32, 4u>
     //
     // @stage(compute) @workgroup_size(1)
     // fn f() {
-    //   let a : @stride(32) array<f32, 4> = a;
+    //   let a : @stride(32) array<f32, 4u> = a;
     //   let b : f32 = arr[1];
     // }
 
     ProgramBuilder b;
-    b.Global("arr", b.ty.array<f32, 4>(32), ast::StorageClass::kPrivate);
+    b.Global("arr", b.ty.array<f32, 4u>(32), ast::StorageClass::kPrivate);
     b.Func("f", {}, b.ty.void_(),
            {
-               b.Decl(b.Let("a", b.ty.array<f32, 4>(32), b.Expr("arr"))),
-               b.Decl(b.Let("b", b.ty.f32(), b.IndexAccessor("arr", 1))),
+               b.Decl(b.Let("a", b.ty.array<f32, 4u>(32), b.Expr("arr"))),
+               b.Decl(b.Let("b", b.ty.f32(), b.IndexAccessor("arr", 1_i))),
            },
            {
                b.Stage(ast::PipelineStage::kCompute),
-               b.WorkgroupSize(1),
+               b.WorkgroupSize(1_i),
            });
 
     auto* expect = R"(
@@ -130,12 +131,12 @@
   el : f32,
 }
 
-var<private> arr : array<strided_arr, 4>;
+var<private> arr : array<strided_arr, 4u>;
 
-@stage(compute) @workgroup_size(1)
+@stage(compute) @workgroup_size(1i)
 fn f() {
-  let a : array<strided_arr, 4> = arr;
-  let b : f32 = arr[1].el;
+  let a : array<strided_arr, 4u> = arr;
+  let b : f32 = arr[1i].el;
 }
 )";
 
@@ -146,26 +147,26 @@
 
 TEST_F(DecomposeStridedArrayTest, ReadUniformStridedArray) {
     // struct S {
-    //   a : @stride(32) array<f32, 4>,
+    //   a : @stride(32) array<f32, 4u>,
     // };
     // @group(0) @binding(0) var<uniform> s : S;
     //
     // @stage(compute) @workgroup_size(1)
     // fn f() {
-    //   let a : @stride(32) array<f32, 4> = s.a;
+    //   let a : @stride(32) array<f32, 4u> = s.a;
     //   let b : f32 = s.a[1];
     // }
     ProgramBuilder b;
-    auto* S = b.Structure("S", {b.Member("a", b.ty.array<f32, 4>(32))});
+    auto* S = b.Structure("S", {b.Member("a", b.ty.array<f32, 4u>(32))});
     b.Global("s", b.ty.Of(S), ast::StorageClass::kUniform, b.GroupAndBinding(0, 0));
     b.Func("f", {}, b.ty.void_(),
            {
-               b.Decl(b.Let("a", b.ty.array<f32, 4>(32), b.MemberAccessor("s", "a"))),
-               b.Decl(b.Let("b", b.ty.f32(), b.IndexAccessor(b.MemberAccessor("s", "a"), 1))),
+               b.Decl(b.Let("a", b.ty.array<f32, 4u>(32), b.MemberAccessor("s", "a"))),
+               b.Decl(b.Let("b", b.ty.f32(), b.IndexAccessor(b.MemberAccessor("s", "a"), 1_i))),
            },
            {
                b.Stage(ast::PipelineStage::kCompute),
-               b.WorkgroupSize(1),
+               b.WorkgroupSize(1_i),
            });
 
     auto* expect = R"(
@@ -175,15 +176,15 @@
 }
 
 struct S {
-  a : array<strided_arr, 4>,
+  a : array<strided_arr, 4u>,
 }
 
 @group(0) @binding(0) var<uniform> s : S;
 
-@stage(compute) @workgroup_size(1)
+@stage(compute) @workgroup_size(1i)
 fn f() {
-  let a : array<strided_arr, 4> = s.a;
-  let b : f32 = s.a[1].el;
+  let a : array<strided_arr, 4u> = s.a;
+  let b : f32 = s.a[1i].el;
 }
 )";
 
@@ -194,41 +195,42 @@
 
 TEST_F(DecomposeStridedArrayTest, ReadUniformDefaultStridedArray) {
     // struct S {
-    //   a : @stride(16) array<vec4<f32>, 4>,
+    //   a : @stride(16) array<vec4<f32>, 4u>,
     // };
     // @group(0) @binding(0) var<uniform> s : S;
     //
     // @stage(compute) @workgroup_size(1)
     // fn f() {
-    //   let a : @stride(16) array<vec4<f32>, 4> = s.a;
+    //   let a : @stride(16) array<vec4<f32>, 4u> = s.a;
     //   let b : f32 = s.a[1][2];
     // }
     ProgramBuilder b;
-    auto* S = b.Structure("S", {b.Member("a", b.ty.array(b.ty.vec4<f32>(), 4, 16))});
+    auto* S = b.Structure("S", {b.Member("a", b.ty.array(b.ty.vec4<f32>(), 4_u, 16))});
     b.Global("s", b.ty.Of(S), ast::StorageClass::kUniform, b.GroupAndBinding(0, 0));
-    b.Func("f", {}, b.ty.void_(),
-           {
-               b.Decl(b.Let("a", b.ty.array(b.ty.vec4<f32>(), 4, 16), b.MemberAccessor("s", "a"))),
-               b.Decl(b.Let("b", b.ty.f32(),
-                            b.IndexAccessor(b.IndexAccessor(b.MemberAccessor("s", "a"), 1), 2))),
-           },
-           {
-               b.Stage(ast::PipelineStage::kCompute),
-               b.WorkgroupSize(1),
-           });
+    b.Func(
+        "f", {}, b.ty.void_(),
+        {
+            b.Decl(b.Let("a", b.ty.array(b.ty.vec4<f32>(), 4_u, 16), b.MemberAccessor("s", "a"))),
+            b.Decl(b.Let("b", b.ty.f32(),
+                         b.IndexAccessor(b.IndexAccessor(b.MemberAccessor("s", "a"), 1_i), 2_i))),
+        },
+        {
+            b.Stage(ast::PipelineStage::kCompute),
+            b.WorkgroupSize(1_i),
+        });
 
     auto* expect =
         R"(
 struct S {
-  a : array<vec4<f32>, 4>,
+  a : array<vec4<f32>, 4u>,
 }
 
 @group(0) @binding(0) var<uniform> s : S;
 
-@stage(compute) @workgroup_size(1)
+@stage(compute) @workgroup_size(1i)
 fn f() {
-  let a : array<vec4<f32>, 4> = s.a;
-  let b : f32 = s.a[1][2];
+  let a : array<vec4<f32>, 4u> = s.a;
+  let b : f32 = s.a[1i][2i];
 }
 )";
 
@@ -239,26 +241,26 @@
 
 TEST_F(DecomposeStridedArrayTest, ReadStorageStridedArray) {
     // struct S {
-    //   a : @stride(32) array<f32, 4>,
+    //   a : @stride(32) array<f32, 4u>,
     // };
     // @group(0) @binding(0) var<storage> s : S;
     //
     // @stage(compute) @workgroup_size(1)
     // fn f() {
-    //   let a : @stride(32) array<f32, 4> = s.a;
+    //   let a : @stride(32) array<f32, 4u> = s.a;
     //   let b : f32 = s.a[1];
     // }
     ProgramBuilder b;
-    auto* S = b.Structure("S", {b.Member("a", b.ty.array<f32, 4>(32))});
+    auto* S = b.Structure("S", {b.Member("a", b.ty.array<f32, 4u>(32))});
     b.Global("s", b.ty.Of(S), ast::StorageClass::kStorage, b.GroupAndBinding(0, 0));
     b.Func("f", {}, b.ty.void_(),
            {
-               b.Decl(b.Let("a", b.ty.array<f32, 4>(32), b.MemberAccessor("s", "a"))),
-               b.Decl(b.Let("b", b.ty.f32(), b.IndexAccessor(b.MemberAccessor("s", "a"), 1))),
+               b.Decl(b.Let("a", b.ty.array<f32, 4u>(32), b.MemberAccessor("s", "a"))),
+               b.Decl(b.Let("b", b.ty.f32(), b.IndexAccessor(b.MemberAccessor("s", "a"), 1_i))),
            },
            {
                b.Stage(ast::PipelineStage::kCompute),
-               b.WorkgroupSize(1),
+               b.WorkgroupSize(1_i),
            });
 
     auto* expect = R"(
@@ -268,15 +270,15 @@
 }
 
 struct S {
-  a : array<strided_arr, 4>,
+  a : array<strided_arr, 4u>,
 }
 
 @group(0) @binding(0) var<storage> s : S;
 
-@stage(compute) @workgroup_size(1)
+@stage(compute) @workgroup_size(1i)
 fn f() {
-  let a : array<strided_arr, 4> = s.a;
-  let b : f32 = s.a[1].el;
+  let a : array<strided_arr, 4u> = s.a;
+  let b : f32 = s.a[1i].el;
 }
 )";
 
@@ -287,39 +289,39 @@
 
 TEST_F(DecomposeStridedArrayTest, ReadStorageDefaultStridedArray) {
     // struct S {
-    //   a : @stride(4) array<f32, 4>,
+    //   a : @stride(4) array<f32, 4u>,
     // };
     // @group(0) @binding(0) var<storage> s : S;
     //
     // @stage(compute) @workgroup_size(1)
     // fn f() {
-    //   let a : @stride(4) array<f32, 4> = s.a;
+    //   let a : @stride(4) array<f32, 4u> = s.a;
     //   let b : f32 = s.a[1];
     // }
     ProgramBuilder b;
-    auto* S = b.Structure("S", {b.Member("a", b.ty.array<f32, 4>(4))});
+    auto* S = b.Structure("S", {b.Member("a", b.ty.array<f32, 4u>(4))});
     b.Global("s", b.ty.Of(S), ast::StorageClass::kStorage, b.GroupAndBinding(0, 0));
     b.Func("f", {}, b.ty.void_(),
            {
-               b.Decl(b.Let("a", b.ty.array<f32, 4>(4), b.MemberAccessor("s", "a"))),
-               b.Decl(b.Let("b", b.ty.f32(), b.IndexAccessor(b.MemberAccessor("s", "a"), 1))),
+               b.Decl(b.Let("a", b.ty.array<f32, 4u>(4), b.MemberAccessor("s", "a"))),
+               b.Decl(b.Let("b", b.ty.f32(), b.IndexAccessor(b.MemberAccessor("s", "a"), 1_i))),
            },
            {
                b.Stage(ast::PipelineStage::kCompute),
-               b.WorkgroupSize(1),
+               b.WorkgroupSize(1_i),
            });
 
     auto* expect = R"(
 struct S {
-  a : array<f32, 4>,
+  a : array<f32, 4u>,
 }
 
 @group(0) @binding(0) var<storage> s : S;
 
-@stage(compute) @workgroup_size(1)
+@stage(compute) @workgroup_size(1i)
 fn f() {
-  let a : array<f32, 4> = s.a;
-  let b : f32 = s.a[1];
+  let a : array<f32, 4u> = s.a;
+  let b : f32 = s.a[1i];
 }
 )";
 
@@ -330,30 +332,30 @@
 
 TEST_F(DecomposeStridedArrayTest, WriteStorageStridedArray) {
     // struct S {
-    //   a : @stride(32) array<f32, 4>,
+    //   a : @stride(32) array<f32, 4u>,
     // };
     // @group(0) @binding(0) var<storage, read_write> s : S;
     //
     // @stage(compute) @workgroup_size(1)
     // fn f() {
-    //   s.a = @stride(32) array<f32, 4>();
-    //   s.a = @stride(32) array<f32, 4>(1.0, 2.0, 3.0, 4.0);
-    //   s.a[1] = 5.0;
+    //   s.a = @stride(32) array<f32, 4u>();
+    //   s.a = @stride(32) array<f32, 4u>(1.0, 2.0, 3.0, 4.0);
+    //   s.a[1i] = 5.0;
     // }
     ProgramBuilder b;
-    auto* S = b.Structure("S", {b.Member("a", b.ty.array<f32, 4>(32))});
+    auto* S = b.Structure("S", {b.Member("a", b.ty.array<f32, 4u>(32))});
     b.Global("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
              b.GroupAndBinding(0, 0));
     b.Func("f", {}, b.ty.void_(),
            {
-               b.Assign(b.MemberAccessor("s", "a"), b.Construct(b.ty.array<f32, 4>(32))),
+               b.Assign(b.MemberAccessor("s", "a"), b.Construct(b.ty.array<f32, 4u>(32))),
                b.Assign(b.MemberAccessor("s", "a"),
-                        b.Construct(b.ty.array<f32, 4>(32), 1.0f, 2.0f, 3.0f, 4.0f)),
-               b.Assign(b.IndexAccessor(b.MemberAccessor("s", "a"), 1), 5.0f),
+                        b.Construct(b.ty.array<f32, 4u>(32), 1.0f, 2.0f, 3.0f, 4.0f)),
+               b.Assign(b.IndexAccessor(b.MemberAccessor("s", "a"), 1_i), 5.0f),
            },
            {
                b.Stage(ast::PipelineStage::kCompute),
-               b.WorkgroupSize(1),
+               b.WorkgroupSize(1_i),
            });
 
     auto* expect =
@@ -364,16 +366,16 @@
 }
 
 struct S {
-  a : array<strided_arr, 4>,
+  a : array<strided_arr, 4u>,
 }
 
 @group(0) @binding(0) var<storage, read_write> s : S;
 
-@stage(compute) @workgroup_size(1)
+@stage(compute) @workgroup_size(1i)
 fn f() {
-  s.a = array<strided_arr, 4>();
-  s.a = array<strided_arr, 4>(strided_arr(1.0), strided_arr(2.0), strided_arr(3.0), strided_arr(4.0));
-  s.a[1].el = 5.0;
+  s.a = array<strided_arr, 4u>();
+  s.a = array<strided_arr, 4u>(strided_arr(1.0), strided_arr(2.0), strided_arr(3.0), strided_arr(4.0));
+  s.a[1i].el = 5.0;
 }
 )";
 
@@ -384,45 +386,45 @@
 
 TEST_F(DecomposeStridedArrayTest, WriteStorageDefaultStridedArray) {
     // struct S {
-    //   a : @stride(4) array<f32, 4>,
+    //   a : @stride(4) array<f32, 4u>,
     // };
     // @group(0) @binding(0) var<storage, read_write> s : S;
     //
     // @stage(compute) @workgroup_size(1)
     // fn f() {
-    //   s.a = @stride(4) array<f32, 4>();
-    //   s.a = @stride(4) array<f32, 4>(1.0, 2.0, 3.0, 4.0);
+    //   s.a = @stride(4) array<f32, 4u>();
+    //   s.a = @stride(4) array<f32, 4u>(1.0, 2.0, 3.0, 4.0);
     //   s.a[1] = 5.0;
     // }
     ProgramBuilder b;
-    auto* S = b.Structure("S", {b.Member("a", b.ty.array<f32, 4>(4))});
+    auto* S = b.Structure("S", {b.Member("a", b.ty.array<f32, 4u>(4))});
     b.Global("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
              b.GroupAndBinding(0, 0));
     b.Func("f", {}, b.ty.void_(),
            {
-               b.Assign(b.MemberAccessor("s", "a"), b.Construct(b.ty.array<f32, 4>(4))),
+               b.Assign(b.MemberAccessor("s", "a"), b.Construct(b.ty.array<f32, 4u>(4))),
                b.Assign(b.MemberAccessor("s", "a"),
-                        b.Construct(b.ty.array<f32, 4>(4), 1.0f, 2.0f, 3.0f, 4.0f)),
-               b.Assign(b.IndexAccessor(b.MemberAccessor("s", "a"), 1), 5.0f),
+                        b.Construct(b.ty.array<f32, 4u>(4), 1.0f, 2.0f, 3.0f, 4.0f)),
+               b.Assign(b.IndexAccessor(b.MemberAccessor("s", "a"), 1_i), 5.0f),
            },
            {
                b.Stage(ast::PipelineStage::kCompute),
-               b.WorkgroupSize(1),
+               b.WorkgroupSize(1_i),
            });
 
     auto* expect =
         R"(
 struct S {
-  a : array<f32, 4>,
+  a : array<f32, 4u>,
 }
 
 @group(0) @binding(0) var<storage, read_write> s : S;
 
-@stage(compute) @workgroup_size(1)
+@stage(compute) @workgroup_size(1i)
 fn f() {
-  s.a = array<f32, 4>();
-  s.a = array<f32, 4>(1.0, 2.0, 3.0, 4.0);
-  s.a[1] = 5.0;
+  s.a = array<f32, 4u>();
+  s.a = array<f32, 4u>(1.0, 2.0, 3.0, 4.0);
+  s.a[1i] = 5.0;
 }
 )";
 
@@ -433,7 +435,7 @@
 
 TEST_F(DecomposeStridedArrayTest, ReadWriteViaPointerLets) {
     // struct S {
-    //   a : @stride(32) array<f32, 4>,
+    //   a : @stride(32) array<f32, 4u>,
     // };
     // @group(0) @binding(0) var<storage, read_write> s : S;
     //
@@ -443,11 +445,11 @@
     //   let b = &*&*(a);
     //   let c = *b;
     //   let d = (*b)[1];
-    //   (*b) = @stride(32) array<f32, 4>(1.0, 2.0, 3.0, 4.0);
+    //   (*b) = @stride(32) array<f32, 4u>(1.0, 2.0, 3.0, 4.0);
     //   (*b)[1] = 5.0;
     // }
     ProgramBuilder b;
-    auto* S = b.Structure("S", {b.Member("a", b.ty.array<f32, 4>(32))});
+    auto* S = b.Structure("S", {b.Member("a", b.ty.array<f32, 4u>(32))});
     b.Global("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
              b.GroupAndBinding(0, 0));
     b.Func("f", {}, b.ty.void_(),
@@ -455,13 +457,13 @@
                b.Decl(b.Let("a", nullptr, b.AddressOf(b.MemberAccessor("s", "a")))),
                b.Decl(b.Let("b", nullptr, b.AddressOf(b.Deref(b.AddressOf(b.Deref("a")))))),
                b.Decl(b.Let("c", nullptr, b.Deref("b"))),
-               b.Decl(b.Let("d", nullptr, b.IndexAccessor(b.Deref("b"), 1))),
-               b.Assign(b.Deref("b"), b.Construct(b.ty.array<f32, 4>(32), 1.0f, 2.0f, 3.0f, 4.0f)),
-               b.Assign(b.IndexAccessor(b.Deref("b"), 1), 5.0f),
+               b.Decl(b.Let("d", nullptr, b.IndexAccessor(b.Deref("b"), 1_i))),
+               b.Assign(b.Deref("b"), b.Construct(b.ty.array<f32, 4u>(32), 1.0f, 2.0f, 3.0f, 4.0f)),
+               b.Assign(b.IndexAccessor(b.Deref("b"), 1_i), 5.0f),
            },
            {
                b.Stage(ast::PipelineStage::kCompute),
-               b.WorkgroupSize(1),
+               b.WorkgroupSize(1_i),
            });
 
     auto* expect =
@@ -472,17 +474,17 @@
 }
 
 struct S {
-  a : array<strided_arr, 4>,
+  a : array<strided_arr, 4u>,
 }
 
 @group(0) @binding(0) var<storage, read_write> s : S;
 
-@stage(compute) @workgroup_size(1)
+@stage(compute) @workgroup_size(1i)
 fn f() {
   let c = s.a;
-  let d = s.a[1].el;
-  s.a = array<strided_arr, 4>(strided_arr(1.0), strided_arr(2.0), strided_arr(3.0), strided_arr(4.0));
-  s.a[1].el = 5.0;
+  let d = s.a[1i].el;
+  s.a = array<strided_arr, 4u>(strided_arr(1.0), strided_arr(2.0), strided_arr(3.0), strided_arr(4.0));
+  s.a[1i].el = 5.0;
 }
 )";
 
@@ -492,7 +494,7 @@
 }
 
 TEST_F(DecomposeStridedArrayTest, PrivateAliasedStridedArray) {
-    // type ARR = @stride(32) array<f32, 4>;
+    // type ARR = @stride(32) array<f32, 4u>;
     // struct S {
     //   a : ARR,
     // };
@@ -507,22 +509,22 @@
     //   s.a[1] = 5.0;
     // }
     ProgramBuilder b;
-    b.Alias("ARR", b.ty.array<f32, 4>(32));
+    b.Alias("ARR", b.ty.array<f32, 4u>(32));
     auto* S = b.Structure("S", {b.Member("a", b.ty.type_name("ARR"))});
     b.Global("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
              b.GroupAndBinding(0, 0));
     b.Func("f", {}, b.ty.void_(),
            {
                b.Decl(b.Let("a", b.ty.type_name("ARR"), b.MemberAccessor("s", "a"))),
-               b.Decl(b.Let("b", b.ty.f32(), b.IndexAccessor(b.MemberAccessor("s", "a"), 1))),
+               b.Decl(b.Let("b", b.ty.f32(), b.IndexAccessor(b.MemberAccessor("s", "a"), 1_i))),
                b.Assign(b.MemberAccessor("s", "a"), b.Construct(b.ty.type_name("ARR"))),
                b.Assign(b.MemberAccessor("s", "a"),
                         b.Construct(b.ty.type_name("ARR"), 1.0f, 2.0f, 3.0f, 4.0f)),
-               b.Assign(b.IndexAccessor(b.MemberAccessor("s", "a"), 1), 5.0f),
+               b.Assign(b.IndexAccessor(b.MemberAccessor("s", "a"), 1_i), 5.0f),
            },
            {
                b.Stage(ast::PipelineStage::kCompute),
-               b.WorkgroupSize(1),
+               b.WorkgroupSize(1_i),
            });
 
     auto* expect = R"(
@@ -531,7 +533,7 @@
   el : f32,
 }
 
-type ARR = array<strided_arr, 4>;
+type ARR = array<strided_arr, 4u>;
 
 struct S {
   a : ARR,
@@ -539,13 +541,13 @@
 
 @group(0) @binding(0) var<storage, read_write> s : S;
 
-@stage(compute) @workgroup_size(1)
+@stage(compute) @workgroup_size(1i)
 fn f() {
   let a : ARR = s.a;
-  let b : f32 = s.a[1].el;
+  let b : f32 = s.a[1i].el;
   s.a = ARR();
   s.a = ARR(strided_arr(1.0), strided_arr(2.0), strided_arr(3.0), strided_arr(4.0));
-  s.a[1].el = 5.0;
+  s.a[1i].el = 5.0;
 }
 )";
 
@@ -555,8 +557,8 @@
 }
 
 TEST_F(DecomposeStridedArrayTest, PrivateNestedStridedArray) {
-    // type ARR_A = @stride(8) array<f32, 2>;
-    // type ARR_B = @stride(128) array<@stride(16) array<ARR_A, 3>, 4>;
+    // type ARR_A = @stride(8) array<f32, 2u>;
+    // type ARR_B = @stride(128) array<@stride(16) array<ARR_A, 3u>, 4u>;
     // struct S {
     //   a : ARR_B,
     // };
@@ -565,7 +567,7 @@
     // @stage(compute) @workgroup_size(1)
     // fn f() {
     //   let a : ARR_B = s.a;
-    //   let b : array<@stride(8) array<f32, 2>, 3> = s.a[3];
+    //   let b : array<@stride(8) array<f32, 2u>, 3u> = s.a[3];
     //   let c = s.a[3][2];
     //   let d = s.a[3][2][1];
     //   s.a = ARR_B();
@@ -575,46 +577,46 @@
     ProgramBuilder b;
     b.Alias("ARR_A", b.ty.array<f32, 2>(8));
     b.Alias("ARR_B",
-            b.ty.array(                                      //
-                b.ty.array(b.ty.type_name("ARR_A"), 3, 16),  //
-                4, 128));
+            b.ty.array(                                        //
+                b.ty.array(b.ty.type_name("ARR_A"), 3_u, 16),  //
+                4_u, 128));
     auto* S = b.Structure("S", {b.Member("a", b.ty.type_name("ARR_B"))});
     b.Global("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
              b.GroupAndBinding(0, 0));
     b.Func("f", {}, b.ty.void_(),
            {
                b.Decl(b.Let("a", b.ty.type_name("ARR_B"), b.MemberAccessor("s", "a"))),
-               b.Decl(b.Let("b", b.ty.array(b.ty.type_name("ARR_A"), 3, 16),
+               b.Decl(b.Let("b", b.ty.array(b.ty.type_name("ARR_A"), 3_u, 16),
                             b.IndexAccessor(                 //
                                 b.MemberAccessor("s", "a"),  //
-                                3))),
+                                3_i))),
                b.Decl(b.Let("c", b.ty.type_name("ARR_A"),
                             b.IndexAccessor(                     //
                                 b.IndexAccessor(                 //
                                     b.MemberAccessor("s", "a"),  //
-                                    3),
-                                2))),
+                                    3_i),
+                                2_i))),
                b.Decl(b.Let("d", b.ty.f32(),
                             b.IndexAccessor(                         //
                                 b.IndexAccessor(                     //
                                     b.IndexAccessor(                 //
                                         b.MemberAccessor("s", "a"),  //
-                                        3),
-                                    2),
-                                1))),
+                                        3_i),
+                                    2_i),
+                                1_i))),
                b.Assign(b.MemberAccessor("s", "a"), b.Construct(b.ty.type_name("ARR_B"))),
                b.Assign(b.IndexAccessor(                         //
                             b.IndexAccessor(                     //
                                 b.IndexAccessor(                 //
                                     b.MemberAccessor("s", "a"),  //
-                                    3),
-                                2),
-                            1),
+                                    3_i),
+                                2_i),
+                            1_i),
                         5.0f),
            },
            {
                b.Stage(ast::PipelineStage::kCompute),
-               b.WorkgroupSize(1),
+               b.WorkgroupSize(1_i),
            });
 
     auto* expect =
@@ -624,14 +626,14 @@
   el : f32,
 }
 
-type ARR_A = array<strided_arr, 2>;
+type ARR_A = array<strided_arr, 2u>;
 
 struct strided_arr_1 {
   @size(128)
-  el : array<ARR_A, 3>,
+  el : array<ARR_A, 3u>,
 }
 
-type ARR_B = array<strided_arr_1, 4>;
+type ARR_B = array<strided_arr_1, 4u>;
 
 struct S {
   a : ARR_B,
@@ -639,14 +641,14 @@
 
 @group(0) @binding(0) var<storage, read_write> s : S;
 
-@stage(compute) @workgroup_size(1)
+@stage(compute) @workgroup_size(1i)
 fn f() {
   let a : ARR_B = s.a;
-  let b : array<ARR_A, 3> = s.a[3].el;
-  let c : ARR_A = s.a[3].el[2];
-  let d : f32 = s.a[3].el[2][1].el;
+  let b : array<ARR_A, 3u> = s.a[3i].el;
+  let c : ARR_A = s.a[3i].el[2i];
+  let d : f32 = s.a[3i].el[2i][1i].el;
   s.a = ARR_B();
-  s.a[3].el[2][1].el = 5.0;
+  s.a[3i].el[2i][1i].el = 5.0;
 }
 )";
 
diff --git a/src/tint/transform/decompose_strided_matrix.cc b/src/tint/transform/decompose_strided_matrix.cc
index 85e8d9e..4f9d6c8 100644
--- a/src/tint/transform/decompose_strided_matrix.cc
+++ b/src/tint/transform/decompose_strided_matrix.cc
@@ -40,8 +40,7 @@
     /// @returns a new ast::Array that holds an vector column for each row of the
     /// matrix.
     const ast::Array* array(ProgramBuilder* b) const {
-        return b->ty.array(b->ty.vec<ProgramBuilder::f32>(matrix->rows()), matrix->columns(),
-                           stride);
+        return b->ty.array(b->ty.vec<f32>(matrix->rows()), u32(matrix->columns()), stride);
     }
 
     /// Equality operator
@@ -172,7 +171,7 @@
                 auto mat = ctx.dst->Sym("m");
                 ast::ExpressionList columns(info.matrix->columns());
                 for (uint32_t i = 0; i < static_cast<uint32_t>(columns.size()); i++) {
-                    columns[i] = ctx.dst->IndexAccessor(mat, i);
+                    columns[i] = ctx.dst->IndexAccessor(mat, u32(i));
                 }
                 ctx.dst->Func(name,
                               {
@@ -213,7 +212,7 @@
                 auto arr = ctx.dst->Sym("arr");
                 ast::ExpressionList columns(info.matrix->columns());
                 for (uint32_t i = 0; i < static_cast<uint32_t>(columns.size()); i++) {
-                    columns[i] = ctx.dst->IndexAccessor(arr, i);
+                    columns[i] = ctx.dst->IndexAccessor(arr, u32(i));
                 }
                 ctx.dst->Func(name,
                               {
diff --git a/src/tint/transform/decompose_strided_matrix_test.cc b/src/tint/transform/decompose_strided_matrix_test.cc
index 8784839..23b30d5 100644
--- a/src/tint/transform/decompose_strided_matrix_test.cc
+++ b/src/tint/transform/decompose_strided_matrix_test.cc
@@ -24,11 +24,12 @@
 #include "src/tint/transform/test_helper.h"
 #include "src/tint/transform/unshadow.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::transform {
 namespace {
 
 using DecomposeStridedMatrixTest = TransformTest;
-using f32 = ProgramBuilder::f32;
 
 TEST_F(DecomposeStridedMatrixTest, ShouldRunEmptyModule) {
     auto* src = R"()";
@@ -82,7 +83,7 @@
            },
            {
                b.Stage(ast::PipelineStage::kCompute),
-               b.WorkgroupSize(1),
+               b.WorkgroupSize(1_i),
            });
 
     auto* expect = R"(
@@ -98,7 +99,7 @@
   return mat2x2<f32>(arr[0u], arr[1u]);
 }
 
-@stage(compute) @workgroup_size(1)
+@stage(compute) @workgroup_size(1i)
 fn f() {
   let x : mat2x2<f32> = arr_to_mat2x2_stride_32(s.m);
 }
@@ -132,14 +133,15 @@
                           }),
              });
     b.Global("s", b.ty.Of(S), ast::StorageClass::kUniform, b.GroupAndBinding(0, 0));
-    b.Func("f", {}, b.ty.void_(),
-           {
-               b.Decl(b.Let("x", b.ty.vec2<f32>(), b.IndexAccessor(b.MemberAccessor("s", "m"), 1))),
-           },
-           {
-               b.Stage(ast::PipelineStage::kCompute),
-               b.WorkgroupSize(1),
-           });
+    b.Func(
+        "f", {}, b.ty.void_(),
+        {
+            b.Decl(b.Let("x", b.ty.vec2<f32>(), b.IndexAccessor(b.MemberAccessor("s", "m"), 1_i))),
+        },
+        {
+            b.Stage(ast::PipelineStage::kCompute),
+            b.WorkgroupSize(1_i),
+        });
 
     auto* expect = R"(
 struct S {
@@ -150,9 +152,9 @@
 
 @group(0) @binding(0) var<uniform> s : S;
 
-@stage(compute) @workgroup_size(1)
+@stage(compute) @workgroup_size(1i)
 fn f() {
-  let x : vec2<f32> = s.m[1];
+  let x : vec2<f32> = s.m[1i];
 }
 )";
 
@@ -190,7 +192,7 @@
            },
            {
                b.Stage(ast::PipelineStage::kCompute),
-               b.WorkgroupSize(1),
+               b.WorkgroupSize(1_i),
            });
 
     auto* expect = R"(
@@ -203,7 +205,7 @@
 
 @group(0) @binding(0) var<uniform> s : S;
 
-@stage(compute) @workgroup_size(1)
+@stage(compute) @workgroup_size(1i)
 fn f() {
   let x : mat2x2<f32> = s.m;
 }
@@ -244,7 +246,7 @@
            },
            {
                b.Stage(ast::PipelineStage::kCompute),
-               b.WorkgroupSize(1),
+               b.WorkgroupSize(1_i),
            });
 
     auto* expect = R"(
@@ -260,7 +262,7 @@
   return mat2x2<f32>(arr[0u], arr[1u]);
 }
 
-@stage(compute) @workgroup_size(1)
+@stage(compute) @workgroup_size(1i)
 fn f() {
   let x : mat2x2<f32> = arr_to_mat2x2_stride_32(s.m);
 }
@@ -295,14 +297,15 @@
              });
     b.Global("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite,
              b.GroupAndBinding(0, 0));
-    b.Func("f", {}, b.ty.void_(),
-           {
-               b.Decl(b.Let("x", b.ty.vec2<f32>(), b.IndexAccessor(b.MemberAccessor("s", "m"), 1))),
-           },
-           {
-               b.Stage(ast::PipelineStage::kCompute),
-               b.WorkgroupSize(1),
-           });
+    b.Func(
+        "f", {}, b.ty.void_(),
+        {
+            b.Decl(b.Let("x", b.ty.vec2<f32>(), b.IndexAccessor(b.MemberAccessor("s", "m"), 1_i))),
+        },
+        {
+            b.Stage(ast::PipelineStage::kCompute),
+            b.WorkgroupSize(1_i),
+        });
 
     auto* expect = R"(
 struct S {
@@ -313,9 +316,9 @@
 
 @group(0) @binding(0) var<storage, read_write> s : S;
 
-@stage(compute) @workgroup_size(1)
+@stage(compute) @workgroup_size(1i)
 fn f() {
-  let x : vec2<f32> = s.m[1];
+  let x : vec2<f32> = s.m[1i];
 }
 )";
 
@@ -355,7 +358,7 @@
            },
            {
                b.Stage(ast::PipelineStage::kCompute),
-               b.WorkgroupSize(1),
+               b.WorkgroupSize(1_i),
            });
 
     auto* expect = R"(
@@ -371,7 +374,7 @@
   return @stride(32) array<vec2<f32>, 2u>(m[0u], m[1u]);
 }
 
-@stage(compute) @workgroup_size(1)
+@stage(compute) @workgroup_size(1i)
 fn f() {
   s.m = mat2x2_stride_32_to_arr(mat2x2<f32>(vec2<f32>(1.0, 2.0), vec2<f32>(3.0, 4.0)));
 }
@@ -408,11 +411,11 @@
              b.GroupAndBinding(0, 0));
     b.Func("f", {}, b.ty.void_(),
            {
-               b.Assign(b.IndexAccessor(b.MemberAccessor("s", "m"), 1), b.vec2<f32>(1.0f, 2.0f)),
+               b.Assign(b.IndexAccessor(b.MemberAccessor("s", "m"), 1_i), b.vec2<f32>(1.0f, 2.0f)),
            },
            {
                b.Stage(ast::PipelineStage::kCompute),
-               b.WorkgroupSize(1),
+               b.WorkgroupSize(1_i),
            });
 
     auto* expect = R"(
@@ -424,9 +427,9 @@
 
 @group(0) @binding(0) var<storage, read_write> s : S;
 
-@stage(compute) @workgroup_size(1)
+@stage(compute) @workgroup_size(1i)
 fn f() {
-  s.m[1] = vec2<f32>(1.0, 2.0);
+  s.m[1i] = vec2<f32>(1.0, 2.0);
 }
 )";
 
@@ -471,14 +474,14 @@
             b.Decl(b.Let("a", nullptr, b.AddressOf(b.MemberAccessor("s", "m")))),
             b.Decl(b.Let("b", nullptr, b.AddressOf(b.Deref(b.AddressOf(b.Deref("a")))))),
             b.Decl(b.Let("x", nullptr, b.Deref("b"))),
-            b.Decl(b.Let("y", nullptr, b.IndexAccessor(b.Deref("b"), 1))),
-            b.Decl(b.Let("z", nullptr, b.IndexAccessor("x", 1))),
+            b.Decl(b.Let("y", nullptr, b.IndexAccessor(b.Deref("b"), 1_i))),
+            b.Decl(b.Let("z", nullptr, b.IndexAccessor("x", 1_i))),
             b.Assign(b.Deref("b"), b.mat2x2<f32>(b.vec2<f32>(1.0f, 2.0f), b.vec2<f32>(3.0f, 4.0f))),
-            b.Assign(b.IndexAccessor(b.Deref("b"), 1), b.vec2<f32>(5.0f, 6.0f)),
+            b.Assign(b.IndexAccessor(b.Deref("b"), 1_i), b.vec2<f32>(5.0f, 6.0f)),
         },
         {
             b.Stage(ast::PipelineStage::kCompute),
-            b.WorkgroupSize(1),
+            b.WorkgroupSize(1_i),
         });
 
     auto* expect = R"(
@@ -498,13 +501,13 @@
   return @stride(32) array<vec2<f32>, 2u>(m[0u], m[1u]);
 }
 
-@stage(compute) @workgroup_size(1)
+@stage(compute) @workgroup_size(1i)
 fn f() {
   let x = arr_to_mat2x2_stride_32(s.m);
-  let y = s.m[1];
-  let z = x[1];
+  let y = s.m[1i];
+  let z = x[1i];
   s.m = mat2x2_stride_32_to_arr(mat2x2<f32>(vec2<f32>(1.0, 2.0), vec2<f32>(3.0, 4.0)));
-  s.m[1] = vec2<f32>(5.0, 6.0);
+  s.m[1i] = vec2<f32>(5.0, 6.0);
 }
 )";
 
@@ -542,7 +545,7 @@
            },
            {
                b.Stage(ast::PipelineStage::kCompute),
-               b.WorkgroupSize(1),
+               b.WorkgroupSize(1_i),
            });
 
     auto* expect = R"(
@@ -555,7 +558,7 @@
 
 var<private> s : S;
 
-@stage(compute) @workgroup_size(1)
+@stage(compute) @workgroup_size(1i)
 fn f() {
   let x : mat2x2<f32> = s.m;
 }
@@ -596,7 +599,7 @@
            },
            {
                b.Stage(ast::PipelineStage::kCompute),
-               b.WorkgroupSize(1),
+               b.WorkgroupSize(1_i),
            });
 
     auto* expect = R"(
@@ -609,7 +612,7 @@
 
 var<private> s : S;
 
-@stage(compute) @workgroup_size(1)
+@stage(compute) @workgroup_size(1i)
 fn f() {
   s.m = mat2x2<f32>(vec2<f32>(1.0, 2.0), vec2<f32>(3.0, 4.0));
 }
diff --git a/src/tint/transform/expand_compound_assignment.cc b/src/tint/transform/expand_compound_assignment.cc
index ccc4f92..2f775ca 100644
--- a/src/tint/transform/expand_compound_assignment.cc
+++ b/src/tint/transform/expand_compound_assignment.cc
@@ -27,6 +27,8 @@
 
 TINT_INSTANTIATE_TYPEINFO(tint::transform::ExpandCompoundAssignment);
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::transform {
 
 ExpandCompoundAssignment::ExpandCompoundAssignment() = default;
@@ -172,8 +174,8 @@
             auto* sem_lhs = ctx.src->Sem().Get(inc_dec->lhs);
             const ast::IntLiteralExpression* one =
                 sem_lhs->Type()->UnwrapRef()->is_signed_integer_scalar()
-                    ? ctx.dst->Expr(1)->As<ast::IntLiteralExpression>()
-                    : ctx.dst->Expr(1u)->As<ast::IntLiteralExpression>();
+                    ? ctx.dst->Expr(1_i)->As<ast::IntLiteralExpression>()
+                    : ctx.dst->Expr(1_u)->As<ast::IntLiteralExpression>();
             auto op = inc_dec->increment ? ast::BinaryOp::kAdd : ast::BinaryOp::kSubtract;
             state.Expand(inc_dec, inc_dec->lhs, one, op);
         }
diff --git a/src/tint/transform/expand_compound_assignment_test.cc b/src/tint/transform/expand_compound_assignment_test.cc
index 2d343b9..613a135 100644
--- a/src/tint/transform/expand_compound_assignment_test.cc
+++ b/src/tint/transform/expand_compound_assignment_test.cc
@@ -473,7 +473,7 @@
     auto* expect = R"(
 fn main() {
   var v : i32;
-  v = (v + 1);
+  v = (v + 1i);
 }
 )";
 
@@ -513,7 +513,7 @@
     auto* expect = R"(
 fn main() {
   var v : i32;
-  v = (v - 1);
+  v = (v - 1i);
 }
 )";
 
@@ -556,7 +556,7 @@
   var v : i32;
   let p = &(v);
   let tint_symbol = &(*(p));
-  *(tint_symbol) = (*(tint_symbol) + 1);
+  *(tint_symbol) = (*(tint_symbol) + 1i);
 }
 )";
 
@@ -584,7 +584,7 @@
 
 fn main() {
   var s : S;
-  s.m = (s.m + 1);
+  s.m = (s.m + 1i);
 }
 )";
 
@@ -617,7 +617,7 @@
 
 fn main() {
   let tint_symbol = &(a[idx()]);
-  *(tint_symbol) = (*(tint_symbol) + 1);
+  *(tint_symbol) = (*(tint_symbol) + 1i);
 }
 )";
 
@@ -651,7 +651,7 @@
 fn main() {
   let tint_symbol = &(v);
   let tint_symbol_1 = idx();
-  (*(tint_symbol))[tint_symbol_1] = ((*(tint_symbol))[tint_symbol_1] + 1);
+  (*(tint_symbol))[tint_symbol_1] = ((*(tint_symbol))[tint_symbol_1] + 1i);
 }
 )";
 
@@ -671,7 +671,7 @@
     auto* expect = R"(
 fn main() {
   var v : vec4<i32>;
-  v.y = (v.y + 1);
+  v.y = (v.y + 1i);
 }
 )";
 
@@ -727,7 +727,7 @@
     continuing {
       let tint_symbol = &(a[idx1()]);
       let tint_symbol_1 = idx2();
-      (*(tint_symbol))[tint_symbol_1] = ((*(tint_symbol))[tint_symbol_1] + 1);
+      (*(tint_symbol))[tint_symbol_1] = ((*(tint_symbol))[tint_symbol_1] + 1i);
     }
   }
 }
diff --git a/src/tint/transform/fold_constants_test.cc b/src/tint/transform/fold_constants_test.cc
index 5c81fb8..f27ede6 100644
--- a/src/tint/transform/fold_constants_test.cc
+++ b/src/tint/transform/fold_constants_test.cc
@@ -37,7 +37,7 @@
 )";
 
     auto* expect = R"(
-var<private> a : i32 = 123;
+var<private> a : i32 = 123i;
 
 var<private> b : u32 = 123u;
 
@@ -66,7 +66,7 @@
 )";
 
     auto* expect = R"(
-var<private> a : i32 = 123;
+var<private> a : i32 = 123i;
 
 var<private> b : u32 = 123u;
 
@@ -95,7 +95,7 @@
 )";
 
     auto* expect = R"(
-var<private> a : i32 = 123;
+var<private> a : i32 = 123i;
 
 var<private> b : u32 = 123u;
 
@@ -124,7 +124,7 @@
 )";
 
     auto* expect = R"(
-var<private> a : vec3<i32> = vec3<i32>(123);
+var<private> a : vec3<i32> = vec3<i32>(123i);
 
 var<private> b : vec3<u32> = vec3<u32>(123u);
 
@@ -153,7 +153,7 @@
 )";
 
     auto* expect = R"(
-var<private> a : vec3<i32> = vec3<i32>(123);
+var<private> a : vec3<i32> = vec3<i32>(123i);
 
 var<private> b : vec3<u32> = vec3<u32>(123u);
 
@@ -182,7 +182,7 @@
 )";
 
     auto* expect = R"(
-var<private> a : vec3<i32> = vec3<i32>(123);
+var<private> a : vec3<i32> = vec3<i32>(123i);
 
 var<private> b : vec3<u32> = vec3<u32>(123u);
 
@@ -212,13 +212,13 @@
 )";
 
     auto* expect = R"(
-var<private> a : vec4<i32> = vec4<i32>(1, 2, 3, 4);
+var<private> a : vec4<i32> = vec4<i32>(1i, 2i, 3i, 4i);
 
-var<private> b : vec4<i32> = vec4<i32>(1, 2, 4, 5);
+var<private> b : vec4<i32> = vec4<i32>(1i, 2i, 4i, 5i);
 
-var<private> c : vec4<i32> = vec4<i32>(1, 2, 3, 4);
+var<private> c : vec4<i32> = vec4<i32>(1i, 2i, 3i, 4i);
 
-var<private> d : vec4<i32> = vec4<i32>(1, 2, 3, 4);
+var<private> d : vec4<i32> = vec4<i32>(1i, 2i, 3i, 4i);
 
 var<private> e : vec4<bool> = vec4<bool>(false, true, false, true);
 
@@ -243,7 +243,7 @@
 
     auto* expect = R"(
 fn f() {
-  var a : i32 = 123;
+  var a : i32 = 123i;
   var b : u32 = 123u;
   var c : f32 = 123.0;
   var d : bool = true;
@@ -267,7 +267,7 @@
 
     auto* expect = R"(
 fn f() {
-  var a : i32 = 123;
+  var a : i32 = 123i;
   var b : u32 = 123u;
   var c : f32 = 123.0;
   var d : bool = true;
@@ -291,7 +291,7 @@
 
     auto* expect = R"(
 fn f() {
-  var a : i32 = 123;
+  var a : i32 = 123i;
   var b : u32 = 123u;
   var c : f32 = 123.0;
   var d : bool = true;
@@ -306,7 +306,7 @@
 TEST_F(FoldConstantsTest, Function_Vector_NoConversion) {
     auto* src = R"(
 fn f() {
-  var a : vec3<i32> = vec3<i32>(123);
+  var a : vec3<i32> = vec3<i32>(123i);
   var b : vec3<u32> = vec3<u32>(123u);
   var c : vec3<f32> = vec3<f32>(123.0);
   var d : vec3<bool> = vec3<bool>(true);
@@ -315,7 +315,7 @@
 
     auto* expect = R"(
 fn f() {
-  var a : vec3<i32> = vec3<i32>(123);
+  var a : vec3<i32> = vec3<i32>(123i);
   var b : vec3<u32> = vec3<u32>(123u);
   var c : vec3<f32> = vec3<f32>(123.0);
   var d : vec3<bool> = vec3<bool>(true);
@@ -339,7 +339,7 @@
 
     auto* expect = R"(
 fn f() {
-  var a : vec3<i32> = vec3<i32>(123);
+  var a : vec3<i32> = vec3<i32>(123i);
   var b : vec3<u32> = vec3<u32>(123u);
   var c : vec3<f32> = vec3<f32>(123.0);
   var d : vec3<bool> = vec3<bool>(true);
@@ -363,7 +363,7 @@
 
     auto* expect = R"(
 fn f() {
-  var a : vec3<i32> = vec3<i32>(123);
+  var a : vec3<i32> = vec3<i32>(123i);
   var b : vec3<u32> = vec3<u32>(123u);
   var c : vec3<f32> = vec3<f32>(123.0);
   var d : vec3<bool> = vec3<bool>(true);
@@ -388,10 +388,10 @@
 
     auto* expect = R"(
 fn f() {
-  var a : vec4<i32> = vec4<i32>(1, 2, 3, 4);
-  var b : vec4<i32> = vec4<i32>(1, 2, 4, 5);
-  var c : vec4<i32> = vec4<i32>(1, 2, 3, 4);
-  var d : vec4<i32> = vec4<i32>(1, 2, 3, 4);
+  var a : vec4<i32> = vec4<i32>(1i, 2i, 3i, 4i);
+  var b : vec4<i32> = vec4<i32>(1i, 2i, 4i, 5i);
+  var c : vec4<i32> = vec4<i32>(1i, 2i, 3i, 4i);
+  var d : vec4<i32> = vec4<i32>(1i, 2i, 3i, 4i);
   var e : vec4<bool> = vec4<bool>(false, true, false, true);
 }
 )";
diff --git a/src/tint/transform/multiplanar_external_texture.cc b/src/tint/transform/multiplanar_external_texture.cc
index 671c6c1..47cc9ce 100644
--- a/src/tint/transform/multiplanar_external_texture.cc
+++ b/src/tint/transform/multiplanar_external_texture.cc
@@ -26,6 +26,8 @@
 TINT_INSTANTIATE_TYPEINFO(tint::transform::MultiplanarExternalTexture);
 TINT_INSTANTIATE_TYPEINFO(tint::transform::MultiplanarExternalTexture::NewBindingPoints);
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::transform {
 namespace {
 
@@ -261,7 +263,6 @@
     /// Creates the gammaCorrection function if needed and returns a call
     /// expression to it.
     void createGammaCorrectionFn() {
-        using f32 = ProgramBuilder::f32;
         ast::VariableList varList = {b.Param("v", b.ty.vec3<f32>()),
                                      b.Param("params", b.ty.type_name(gamma_transfer_struct_sym))};
 
@@ -298,7 +299,6 @@
     /// @param call_type determines which function body to generate
     /// @returns a statement list that makes of the body of the chosen function
     ast::StatementList createTexFnExtStatementList(sem::BuiltinType call_type) {
-        using f32 = ProgramBuilder::f32;
         const ast::CallExpression* single_plane_call = nullptr;
         const ast::CallExpression* plane_0_call = nullptr;
         const ast::CallExpression* plane_1_call = nullptr;
@@ -311,11 +311,11 @@
             plane_1_call = b.Call("textureSampleLevel", "plane1", "smp", "coord", 0.0f);
         } else if (call_type == sem::BuiltinType::kTextureLoad) {
             // textureLoad(plane0, coords.xy, 0);
-            single_plane_call = b.Call("textureLoad", "plane0", "coord", 0);
+            single_plane_call = b.Call("textureLoad", "plane0", "coord", 0_i);
             // textureLoad(plane0, coords.xy, 0);
-            plane_0_call = b.Call("textureLoad", "plane0", "coord", 0);
+            plane_0_call = b.Call("textureLoad", "plane0", "coord", 0_i);
             // textureLoad(plane1, coords.xy, 0);
-            plane_1_call = b.Call("textureLoad", "plane1", "coord", 0);
+            plane_1_call = b.Call("textureLoad", "plane1", "coord", 0_i);
         } else {
             TINT_ICE(Transform, b.Diagnostics()) << "unhandled builtin: " << call_type;
         }
@@ -325,7 +325,7 @@
             b.Decl(b.Var("color", b.ty.vec3(b.ty.f32()))),
             // if ((params.numPlanes == 1u))
             b.If(b.create<ast::BinaryExpression>(
-                     ast::BinaryOp::kEqual, b.MemberAccessor("params", "numPlanes"), b.Expr(1u)),
+                     ast::BinaryOp::kEqual, b.MemberAccessor("params", "numPlanes"), b.Expr(1_u)),
                  b.Block(
                      // color = textureLoad(plane0, coord, 0).rgb;
                      b.Assign("color", b.MemberAccessor(single_plane_call, "rgb"))),
diff --git a/src/tint/transform/multiplanar_external_texture_test.cc b/src/tint/transform/multiplanar_external_texture_test.cc
index ac05545..171df8d 100644
--- a/src/tint/transform/multiplanar_external_texture_test.cc
+++ b/src/tint/transform/multiplanar_external_texture_test.cc
@@ -392,9 +392,9 @@
 fn textureLoadExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, coord : vec2<i32>, params : ExternalTextureParams) -> vec4<f32> {
   var color : vec3<f32>;
   if ((params.numPlanes == 1u)) {
-    color = textureLoad(plane0, coord, 0).rgb;
+    color = textureLoad(plane0, coord, 0i).rgb;
   } else {
-    color = (vec4<f32>(textureLoad(plane0, coord, 0).r, textureLoad(plane1, coord, 0).rg, 1.0) * params.yuvToRgbConversionMatrix);
+    color = (vec4<f32>(textureLoad(plane0, coord, 0i).r, textureLoad(plane1, coord, 0i).rg, 1.0) * params.yuvToRgbConversionMatrix);
   }
   color = gammaCorrection(color, params.gammaDecodeParams);
   color = (params.gamutConversionMatrix * color);
@@ -460,9 +460,9 @@
 fn textureLoadExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, coord : vec2<i32>, params : ExternalTextureParams) -> vec4<f32> {
   var color : vec3<f32>;
   if ((params.numPlanes == 1u)) {
-    color = textureLoad(plane0, coord, 0).rgb;
+    color = textureLoad(plane0, coord, 0i).rgb;
   } else {
-    color = (vec4<f32>(textureLoad(plane0, coord, 0).r, textureLoad(plane1, coord, 0).rg, 1.0) * params.yuvToRgbConversionMatrix);
+    color = (vec4<f32>(textureLoad(plane0, coord, 0i).r, textureLoad(plane1, coord, 0i).rg, 1.0) * params.yuvToRgbConversionMatrix);
   }
   color = gammaCorrection(color, params.gammaDecodeParams);
   color = (params.gamutConversionMatrix * color);
@@ -549,9 +549,9 @@
 fn textureLoadExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, coord : vec2<i32>, params : ExternalTextureParams) -> vec4<f32> {
   var color : vec3<f32>;
   if ((params.numPlanes == 1u)) {
-    color = textureLoad(plane0, coord, 0).rgb;
+    color = textureLoad(plane0, coord, 0i).rgb;
   } else {
-    color = (vec4<f32>(textureLoad(plane0, coord, 0).r, textureLoad(plane1, coord, 0).rg, 1.0) * params.yuvToRgbConversionMatrix);
+    color = (vec4<f32>(textureLoad(plane0, coord, 0i).r, textureLoad(plane1, coord, 0i).rg, 1.0) * params.yuvToRgbConversionMatrix);
   }
   color = gammaCorrection(color, params.gammaDecodeParams);
   color = (params.gamutConversionMatrix * color);
@@ -632,9 +632,9 @@
 fn textureLoadExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, coord : vec2<i32>, params : ExternalTextureParams) -> vec4<f32> {
   var color : vec3<f32>;
   if ((params.numPlanes == 1u)) {
-    color = textureLoad(plane0, coord, 0).rgb;
+    color = textureLoad(plane0, coord, 0i).rgb;
   } else {
-    color = (vec4<f32>(textureLoad(plane0, coord, 0).r, textureLoad(plane1, coord, 0).rg, 1.0) * params.yuvToRgbConversionMatrix);
+    color = (vec4<f32>(textureLoad(plane0, coord, 0i).r, textureLoad(plane1, coord, 0i).rg, 1.0) * params.yuvToRgbConversionMatrix);
   }
   color = gammaCorrection(color, params.gammaDecodeParams);
   color = (params.gamutConversionMatrix * color);
diff --git a/src/tint/transform/robustness.cc b/src/tint/transform/robustness.cc
index d946d23..a7f2a4a 100644
--- a/src/tint/transform/robustness.cc
+++ b/src/tint/transform/robustness.cc
@@ -28,6 +28,8 @@
 TINT_INSTANTIATE_TYPEINFO(tint::transform::Robustness);
 TINT_INSTANTIATE_TYPEINFO(tint::transform::Robustness::Config);
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::transform {
 
 /// State holds the current transform state
@@ -59,7 +61,6 @@
         auto* ret_unwrapped = ret_type->UnwrapRef();
 
         ProgramBuilder& b = *ctx.dst;
-        using u32 = ProgramBuilder::u32;
 
         struct Value {
             const ast::Expression* expr = nullptr;  // If null, then is a constant
@@ -103,7 +104,7 @@
         limit.is_signed = false;  // Like size, limit is always unsigned.
         if (size.expr) {
             // Dynamic size
-            limit.expr = b.Sub(size.expr, 1u);
+            limit.expr = b.Sub(size.expr, 1_u);
         } else {
             // Constant size
             limit.u32 = size.u32 - 1u;
@@ -158,10 +159,10 @@
 
             // Convert idx and limit to expressions, so we can emit `min(idx, limit)`.
             if (!idx.expr) {
-                idx.expr = b.Expr(idx.u32);
+                idx.expr = b.Expr(u32(idx.u32));
             }
             if (!limit.expr) {
-                limit.expr = b.Expr(limit.u32);
+                limit.expr = b.Expr(u32(limit.u32));
             }
 
             // Perform the clamp with `min(idx, limit)`
@@ -182,8 +183,8 @@
 
         // Convert idx to an expression, so we can emit the new accessor.
         if (!idx.expr) {
-            idx.expr = idx.is_signed ? static_cast<const ast::Expression*>(b.Expr(idx.i32))
-                                     : static_cast<const ast::Expression*>(b.Expr(idx.u32));
+            idx.expr = idx.is_signed ? static_cast<const ast::Expression*>(b.Expr(i32(idx.i32)))
+                                     : static_cast<const ast::Expression*>(b.Expr(u32(idx.u32)));
         }
 
         // Clone arguments outside of create() call to have deterministic ordering
@@ -236,8 +237,8 @@
             level_arg = [&] {
                 auto* arg = expr->args[level_idx];
                 auto* num_levels = b.Call("textureNumLevels", ctx.Clone(texture_arg));
-                auto* zero = b.Expr(0);
-                auto* max = ctx.dst->Sub(num_levels, 1);
+                auto* zero = b.Expr(0_i);
+                auto* max = ctx.dst->Sub(num_levels, 1_i);
                 auto* clamped = b.Call("clamp", ctx.Clone(arg), zero, max);
                 return clamped;
             };
@@ -250,7 +251,7 @@
                           : b.Call("textureDimensions", ctx.Clone(texture_arg));
             auto* zero = b.Construct(CreateASTTypeFor(ctx, coords_ty));
             auto* max =
-                ctx.dst->Sub(texture_dims, b.Construct(CreateASTTypeFor(ctx, coords_ty), 1));
+                ctx.dst->Sub(texture_dims, b.Construct(CreateASTTypeFor(ctx, coords_ty), 1_i));
             auto* clamped_coords = b.Call("clamp", ctx.Clone(coords_arg), zero, max);
             ctx.Replace(coords_arg, clamped_coords);
         }
@@ -259,8 +260,8 @@
         if (array_idx >= 0) {
             auto* arg = expr->args[array_idx];
             auto* num_layers = b.Call("textureNumLayers", ctx.Clone(texture_arg));
-            auto* zero = b.Expr(0);
-            auto* max = ctx.dst->Sub(num_layers, 1);
+            auto* zero = b.Expr(0_i);
+            auto* max = ctx.dst->Sub(num_layers, 1_i);
             auto* clamped = b.Call("clamp", ctx.Clone(arg), zero, max);
             ctx.Replace(arg, clamped);
         }
@@ -268,7 +269,7 @@
         // Clamp the level argument, if provided
         if (level_idx >= 0) {
             auto* arg = expr->args[level_idx];
-            ctx.Replace(arg, level_arg ? level_arg() : ctx.dst->Expr(0));
+            ctx.Replace(arg, level_arg ? level_arg() : ctx.dst->Expr(0_i));
         }
 
         return nullptr;  // Clone, which will use the argument replacements above.
diff --git a/src/tint/transform/robustness_test.cc b/src/tint/transform/robustness_test.cc
index 481be31..fb0e5a4 100644
--- a/src/tint/transform/robustness_test.cc
+++ b/src/tint/transform/robustness_test.cc
@@ -138,7 +138,7 @@
 var<private> a : array<f32, 3>;
 
 fn f() {
-  var b : f32 = a[1];
+  var b : f32 = a[1i];
 }
 )";
 
@@ -146,7 +146,7 @@
 var<private> a : array<f32, 3>;
 
 fn f() {
-  var b : f32 = a[1];
+  var b : f32 = a[1i];
 }
 )";
 
@@ -158,7 +158,7 @@
 TEST_F(RobustnessTest, Array_Idx_Scalar_OutOfOrder) {
     auto* src = R"(
 fn f() {
-  var b : f32 = a[1];
+  var b : f32 = a[1i];
 }
 
 var<private> a : array<f32, 3>;
@@ -166,7 +166,7 @@
 
     auto* expect = R"(
 fn f() {
-  var b : f32 = a[1];
+  var b : f32 = a[1i];
 }
 
 var<private> a : array<f32, 3>;
@@ -242,7 +242,7 @@
 var<private> a : array<f32, 3>;
 
 fn f() {
-  var b : f32 = a[0];
+  var b : f32 = a[0i];
 }
 )";
 
@@ -262,7 +262,7 @@
 
     auto* expect = R"(
 fn f() {
-  var b : f32 = a[0];
+  var b : f32 = a[0i];
 }
 
 var<private> a : array<f32, 3>;
@@ -286,7 +286,7 @@
 var<private> a : array<f32, 3>;
 
 fn f() {
-  var b : f32 = a[2];
+  var b : f32 = a[2i];
 }
 )";
 
@@ -306,7 +306,7 @@
 
     auto* expect = R"(
 fn f() {
-  var b : f32 = a[2];
+  var b : f32 = a[2i];
 }
 
 var<private> a : array<f32, 3>;
@@ -402,7 +402,7 @@
 var<private> a : vec3<f32>;
 
 fn f() {
-  var b : f32 = a[1];
+  var b : f32 = a[1i];
 }
 )";
 
@@ -410,7 +410,7 @@
 var<private> a : vec3<f32>;
 
 fn f() {
-  var b : f32 = a[1];
+  var b : f32 = a[1i];
 }
 )";
 
@@ -422,7 +422,7 @@
 TEST_F(RobustnessTest, Vector_Idx_Scalar_OutOfOrder) {
     auto* src = R"(
 fn f() {
-  var b : f32 = a[1];
+  var b : f32 = a[1i];
 }
 
 var<private> a : vec3<f32>;
@@ -430,7 +430,7 @@
 
     auto* expect = R"(
 fn f() {
-  var b : f32 = a[1];
+  var b : f32 = a[1i];
 }
 
 var<private> a : vec3<f32>;
@@ -506,7 +506,7 @@
 var<private> a : vec3<f32>;
 
 fn f() {
-  var b : f32 = a.xy[1];
+  var b : f32 = a.xy[1i];
 }
 )";
 
@@ -526,7 +526,7 @@
 
     auto* expect = R"(
 fn f() {
-  var b : f32 = a.xy[1];
+  var b : f32 = a.xy[1i];
 }
 
 var<private> a : vec3<f32>;
@@ -654,7 +654,7 @@
 var<private> a : vec3<f32>;
 
 fn f() {
-  var b : f32 = a[0];
+  var b : f32 = a[0i];
 }
 )";
 
@@ -674,7 +674,7 @@
 
     auto* expect = R"(
 fn f() {
-  var b : f32 = a[0];
+  var b : f32 = a[0i];
 }
 
 var<private> a : vec3<f32>;
@@ -698,7 +698,7 @@
 var<private> a : vec3<f32>;
 
 fn f() {
-  var b : f32 = a[2];
+  var b : f32 = a[2i];
 }
 )";
 
@@ -718,7 +718,7 @@
 
     auto* expect = R"(
 fn f() {
-  var b : f32 = a[2];
+  var b : f32 = a[2i];
 }
 
 var<private> a : vec3<f32>;
@@ -734,7 +734,7 @@
 var<private> a : mat3x2<f32>;
 
 fn f() {
-  var b : f32 = a[2][1];
+  var b : f32 = a[2i][1i];
 }
 )";
 
@@ -742,7 +742,7 @@
 var<private> a : mat3x2<f32>;
 
 fn f() {
-  var b : f32 = a[2][1];
+  var b : f32 = a[2i][1i];
 }
 )";
 
@@ -754,7 +754,7 @@
 TEST_F(RobustnessTest, Matrix_Idx_Scalar_OutOfOrder) {
     auto* src = R"(
 fn f() {
-  var b : f32 = a[2][1];
+  var b : f32 = a[2i][1i];
 }
 
 var<private> a : mat3x2<f32>;
@@ -762,7 +762,7 @@
 
     auto* expect = R"(
 fn f() {
-  var b : f32 = a[2][1];
+  var b : f32 = a[2i][1i];
 }
 
 var<private> a : mat3x2<f32>;
@@ -790,7 +790,7 @@
 var<private> c : i32;
 
 fn f() {
-  var b : f32 = a[min(u32(((c + 2) - 3)), 2u)][1];
+  var b : f32 = a[min(u32(((c + 2) - 3)), 2u)][1i];
 }
 )";
 
@@ -812,7 +812,7 @@
 
     auto* expect = R"(
 fn f() {
-  var b : f32 = a[min(u32(((c + 2) - 3)), 2u)][1];
+  var b : f32 = a[min(u32(((c + 2) - 3)), 2u)][1i];
 }
 
 var<private> c : i32;
@@ -842,7 +842,7 @@
 var<private> c : i32;
 
 fn f() {
-  var b : f32 = a[1][min(u32(((c + 2) - 3)), 1u)];
+  var b : f32 = a[1i][min(u32(((c + 2) - 3)), 1u)];
 }
 )";
 
@@ -864,7 +864,7 @@
 
     auto* expect = R"(
 fn f() {
-  var b : f32 = a[1][min(u32(((c + 2) - 3)), 1u)];
+  var b : f32 = a[1i][min(u32(((c + 2) - 3)), 1u)];
 }
 
 var<private> c : i32;
@@ -890,7 +890,7 @@
 var<private> a : mat3x2<f32>;
 
 fn f() {
-  var b : f32 = a[0][1];
+  var b : f32 = a[0i][1i];
 }
 )";
 
@@ -910,7 +910,7 @@
 
     auto* expect = R"(
 fn f() {
-  var b : f32 = a[0][1];
+  var b : f32 = a[0i][1i];
 }
 
 var<private> a : mat3x2<f32>;
@@ -934,7 +934,7 @@
 var<private> a : mat3x2<f32>;
 
 fn f() {
-  var b : f32 = a[2][0];
+  var b : f32 = a[2i][0i];
 }
 )";
 
@@ -954,7 +954,7 @@
 
     auto* expect = R"(
 fn f() {
-  var b : f32 = a[2][0];
+  var b : f32 = a[2i][0i];
 }
 
 var<private> a : mat3x2<f32>;
@@ -978,7 +978,7 @@
 var<private> a : mat3x2<f32>;
 
 fn f() {
-  var b : f32 = a[2][1];
+  var b : f32 = a[2i][1i];
 }
 )";
 
@@ -998,7 +998,7 @@
 
     auto* expect = R"(
 fn f() {
-  var b : f32 = a[2][1];
+  var b : f32 = a[2i][1i];
 }
 
 var<private> a : mat3x2<f32>;
@@ -1022,7 +1022,7 @@
 var<private> a : mat3x2<f32>;
 
 fn f() {
-  var b : f32 = a[2][1];
+  var b : f32 = a[2i][1i];
 }
 )";
 
@@ -1042,7 +1042,7 @@
 
     auto* expect = R"(
 fn f() {
-  var b : f32 = a[2][1];
+  var b : f32 = a[2i][1i];
 }
 
 var<private> a : mat3x2<f32>;
@@ -1202,14 +1202,14 @@
   var array_idx : i32;
   var level_idx : i32;
   var sample_idx : i32;
-  textureLoad(tex_1d, clamp(1, i32(), (textureDimensions(tex_1d, clamp(level_idx, 0, (textureNumLevels(tex_1d) - 1))) - i32(1))), clamp(level_idx, 0, (textureNumLevels(tex_1d) - 1)));
-  textureLoad(tex_2d, clamp(vec2<i32>(1, 2), vec2<i32>(), (textureDimensions(tex_2d, clamp(level_idx, 0, (textureNumLevels(tex_2d) - 1))) - vec2<i32>(1))), clamp(level_idx, 0, (textureNumLevels(tex_2d) - 1)));
-  textureLoad(tex_2d_arr, clamp(vec2<i32>(1, 2), vec2<i32>(), (textureDimensions(tex_2d_arr, clamp(level_idx, 0, (textureNumLevels(tex_2d_arr) - 1))) - vec2<i32>(1))), clamp(array_idx, 0, (textureNumLayers(tex_2d_arr) - 1)), clamp(level_idx, 0, (textureNumLevels(tex_2d_arr) - 1)));
-  textureLoad(tex_3d, clamp(vec3<i32>(1, 2, 3), vec3<i32>(), (textureDimensions(tex_3d, clamp(level_idx, 0, (textureNumLevels(tex_3d) - 1))) - vec3<i32>(1))), clamp(level_idx, 0, (textureNumLevels(tex_3d) - 1)));
-  textureLoad(tex_ms_2d, clamp(vec2<i32>(1, 2), vec2<i32>(), (textureDimensions(tex_ms_2d) - vec2<i32>(1))), sample_idx);
-  textureLoad(tex_depth_2d, clamp(vec2<i32>(1, 2), vec2<i32>(), (textureDimensions(tex_depth_2d, clamp(level_idx, 0, (textureNumLevels(tex_depth_2d) - 1))) - vec2<i32>(1))), clamp(level_idx, 0, (textureNumLevels(tex_depth_2d) - 1)));
-  textureLoad(tex_depth_2d_arr, clamp(vec2<i32>(1, 2), vec2<i32>(), (textureDimensions(tex_depth_2d_arr, clamp(level_idx, 0, (textureNumLevels(tex_depth_2d_arr) - 1))) - vec2<i32>(1))), clamp(array_idx, 0, (textureNumLayers(tex_depth_2d_arr) - 1)), clamp(level_idx, 0, (textureNumLevels(tex_depth_2d_arr) - 1)));
-  textureLoad(tex_external, clamp(vec2<i32>(1, 2), vec2<i32>(), (textureDimensions(tex_external) - vec2<i32>(1))));
+  textureLoad(tex_1d, clamp(1, i32(), (textureDimensions(tex_1d, clamp(level_idx, 0i, (textureNumLevels(tex_1d) - 1i))) - i32(1i))), clamp(level_idx, 0i, (textureNumLevels(tex_1d) - 1i)));
+  textureLoad(tex_2d, clamp(vec2<i32>(1, 2), vec2<i32>(), (textureDimensions(tex_2d, clamp(level_idx, 0i, (textureNumLevels(tex_2d) - 1i))) - vec2<i32>(1i))), clamp(level_idx, 0i, (textureNumLevels(tex_2d) - 1i)));
+  textureLoad(tex_2d_arr, clamp(vec2<i32>(1, 2), vec2<i32>(), (textureDimensions(tex_2d_arr, clamp(level_idx, 0i, (textureNumLevels(tex_2d_arr) - 1i))) - vec2<i32>(1i))), clamp(array_idx, 0i, (textureNumLayers(tex_2d_arr) - 1i)), clamp(level_idx, 0i, (textureNumLevels(tex_2d_arr) - 1i)));
+  textureLoad(tex_3d, clamp(vec3<i32>(1, 2, 3), vec3<i32>(), (textureDimensions(tex_3d, clamp(level_idx, 0i, (textureNumLevels(tex_3d) - 1i))) - vec3<i32>(1i))), clamp(level_idx, 0i, (textureNumLevels(tex_3d) - 1i)));
+  textureLoad(tex_ms_2d, clamp(vec2<i32>(1, 2), vec2<i32>(), (textureDimensions(tex_ms_2d) - vec2<i32>(1i))), sample_idx);
+  textureLoad(tex_depth_2d, clamp(vec2<i32>(1, 2), vec2<i32>(), (textureDimensions(tex_depth_2d, clamp(level_idx, 0i, (textureNumLevels(tex_depth_2d) - 1i))) - vec2<i32>(1i))), clamp(level_idx, 0i, (textureNumLevels(tex_depth_2d) - 1i)));
+  textureLoad(tex_depth_2d_arr, clamp(vec2<i32>(1, 2), vec2<i32>(), (textureDimensions(tex_depth_2d_arr, clamp(level_idx, 0i, (textureNumLevels(tex_depth_2d_arr) - 1i))) - vec2<i32>(1i))), clamp(array_idx, 0i, (textureNumLayers(tex_depth_2d_arr) - 1i)), clamp(level_idx, 0i, (textureNumLevels(tex_depth_2d_arr) - 1i)));
+  textureLoad(tex_external, clamp(vec2<i32>(1, 2), vec2<i32>(), (textureDimensions(tex_external) - vec2<i32>(1i))));
 }
 )";
 
@@ -1252,14 +1252,14 @@
   var array_idx : i32;
   var level_idx : i32;
   var sample_idx : i32;
-  textureLoad(tex_1d, clamp(1, i32(), (textureDimensions(tex_1d, clamp(level_idx, 0, (textureNumLevels(tex_1d) - 1))) - i32(1))), clamp(level_idx, 0, (textureNumLevels(tex_1d) - 1)));
-  textureLoad(tex_2d, clamp(vec2<i32>(1, 2), vec2<i32>(), (textureDimensions(tex_2d, clamp(level_idx, 0, (textureNumLevels(tex_2d) - 1))) - vec2<i32>(1))), clamp(level_idx, 0, (textureNumLevels(tex_2d) - 1)));
-  textureLoad(tex_2d_arr, clamp(vec2<i32>(1, 2), vec2<i32>(), (textureDimensions(tex_2d_arr, clamp(level_idx, 0, (textureNumLevels(tex_2d_arr) - 1))) - vec2<i32>(1))), clamp(array_idx, 0, (textureNumLayers(tex_2d_arr) - 1)), clamp(level_idx, 0, (textureNumLevels(tex_2d_arr) - 1)));
-  textureLoad(tex_3d, clamp(vec3<i32>(1, 2, 3), vec3<i32>(), (textureDimensions(tex_3d, clamp(level_idx, 0, (textureNumLevels(tex_3d) - 1))) - vec3<i32>(1))), clamp(level_idx, 0, (textureNumLevels(tex_3d) - 1)));
-  textureLoad(tex_ms_2d, clamp(vec2<i32>(1, 2), vec2<i32>(), (textureDimensions(tex_ms_2d) - vec2<i32>(1))), sample_idx);
-  textureLoad(tex_depth_2d, clamp(vec2<i32>(1, 2), vec2<i32>(), (textureDimensions(tex_depth_2d, clamp(level_idx, 0, (textureNumLevels(tex_depth_2d) - 1))) - vec2<i32>(1))), clamp(level_idx, 0, (textureNumLevels(tex_depth_2d) - 1)));
-  textureLoad(tex_depth_2d_arr, clamp(vec2<i32>(1, 2), vec2<i32>(), (textureDimensions(tex_depth_2d_arr, clamp(level_idx, 0, (textureNumLevels(tex_depth_2d_arr) - 1))) - vec2<i32>(1))), clamp(array_idx, 0, (textureNumLayers(tex_depth_2d_arr) - 1)), clamp(level_idx, 0, (textureNumLevels(tex_depth_2d_arr) - 1)));
-  textureLoad(tex_external, clamp(vec2<i32>(1, 2), vec2<i32>(), (textureDimensions(tex_external) - vec2<i32>(1))));
+  textureLoad(tex_1d, clamp(1, i32(), (textureDimensions(tex_1d, clamp(level_idx, 0i, (textureNumLevels(tex_1d) - 1i))) - i32(1i))), clamp(level_idx, 0i, (textureNumLevels(tex_1d) - 1i)));
+  textureLoad(tex_2d, clamp(vec2<i32>(1, 2), vec2<i32>(), (textureDimensions(tex_2d, clamp(level_idx, 0i, (textureNumLevels(tex_2d) - 1i))) - vec2<i32>(1i))), clamp(level_idx, 0i, (textureNumLevels(tex_2d) - 1i)));
+  textureLoad(tex_2d_arr, clamp(vec2<i32>(1, 2), vec2<i32>(), (textureDimensions(tex_2d_arr, clamp(level_idx, 0i, (textureNumLevels(tex_2d_arr) - 1i))) - vec2<i32>(1i))), clamp(array_idx, 0i, (textureNumLayers(tex_2d_arr) - 1i)), clamp(level_idx, 0i, (textureNumLevels(tex_2d_arr) - 1i)));
+  textureLoad(tex_3d, clamp(vec3<i32>(1, 2, 3), vec3<i32>(), (textureDimensions(tex_3d, clamp(level_idx, 0i, (textureNumLevels(tex_3d) - 1i))) - vec3<i32>(1i))), clamp(level_idx, 0i, (textureNumLevels(tex_3d) - 1i)));
+  textureLoad(tex_ms_2d, clamp(vec2<i32>(1, 2), vec2<i32>(), (textureDimensions(tex_ms_2d) - vec2<i32>(1i))), sample_idx);
+  textureLoad(tex_depth_2d, clamp(vec2<i32>(1, 2), vec2<i32>(), (textureDimensions(tex_depth_2d, clamp(level_idx, 0i, (textureNumLevels(tex_depth_2d) - 1i))) - vec2<i32>(1i))), clamp(level_idx, 0i, (textureNumLevels(tex_depth_2d) - 1i)));
+  textureLoad(tex_depth_2d_arr, clamp(vec2<i32>(1, 2), vec2<i32>(), (textureDimensions(tex_depth_2d_arr, clamp(level_idx, 0i, (textureNumLevels(tex_depth_2d_arr) - 1i))) - vec2<i32>(1i))), clamp(array_idx, 0i, (textureNumLayers(tex_depth_2d_arr) - 1i)), clamp(level_idx, 0i, (textureNumLevels(tex_depth_2d_arr) - 1i)));
+  textureLoad(tex_external, clamp(vec2<i32>(1, 2), vec2<i32>(), (textureDimensions(tex_external) - vec2<i32>(1i))));
 }
 
 @group(0) @binding(0) var tex_1d : texture_1d<f32>;
@@ -1313,10 +1313,10 @@
 @group(0) @binding(3) var tex3d : texture_storage_3d<rgba8sint, write>;
 
 fn f() {
-  textureStore(tex1d, clamp(10, i32(), (textureDimensions(tex1d) - i32(1))), vec4<i32>());
-  textureStore(tex2d, clamp(vec2<i32>(10, 20), vec2<i32>(), (textureDimensions(tex2d) - vec2<i32>(1))), vec4<i32>());
-  textureStore(tex2d_arr, clamp(vec2<i32>(10, 20), vec2<i32>(), (textureDimensions(tex2d_arr) - vec2<i32>(1))), clamp(50, 0, (textureNumLayers(tex2d_arr) - 1)), vec4<i32>());
-  textureStore(tex3d, clamp(vec3<i32>(10, 20, 30), vec3<i32>(), (textureDimensions(tex3d) - vec3<i32>(1))), vec4<i32>());
+  textureStore(tex1d, clamp(10, i32(), (textureDimensions(tex1d) - i32(1i))), vec4<i32>());
+  textureStore(tex2d, clamp(vec2<i32>(10, 20), vec2<i32>(), (textureDimensions(tex2d) - vec2<i32>(1i))), vec4<i32>());
+  textureStore(tex2d_arr, clamp(vec2<i32>(10, 20), vec2<i32>(), (textureDimensions(tex2d_arr) - vec2<i32>(1i))), clamp(50, 0i, (textureNumLayers(tex2d_arr) - 1i)), vec4<i32>());
+  textureStore(tex3d, clamp(vec3<i32>(10, 20, 30), vec3<i32>(), (textureDimensions(tex3d) - vec3<i32>(1i))), vec4<i32>());
 }
 )";
 
@@ -1347,10 +1347,10 @@
 
     auto* expect = R"(
 fn f() {
-  textureStore(tex1d, clamp(10, i32(), (textureDimensions(tex1d) - i32(1))), vec4<i32>());
-  textureStore(tex2d, clamp(vec2<i32>(10, 20), vec2<i32>(), (textureDimensions(tex2d) - vec2<i32>(1))), vec4<i32>());
-  textureStore(tex2d_arr, clamp(vec2<i32>(10, 20), vec2<i32>(), (textureDimensions(tex2d_arr) - vec2<i32>(1))), clamp(50, 0, (textureNumLayers(tex2d_arr) - 1)), vec4<i32>());
-  textureStore(tex3d, clamp(vec3<i32>(10, 20, 30), vec3<i32>(), (textureDimensions(tex3d) - vec3<i32>(1))), vec4<i32>());
+  textureStore(tex1d, clamp(10, i32(), (textureDimensions(tex1d) - i32(1i))), vec4<i32>());
+  textureStore(tex2d, clamp(vec2<i32>(10, 20), vec2<i32>(), (textureDimensions(tex2d) - vec2<i32>(1i))), vec4<i32>());
+  textureStore(tex2d_arr, clamp(vec2<i32>(10, 20), vec2<i32>(), (textureDimensions(tex2d_arr) - vec2<i32>(1i))), clamp(50, 0i, (textureNumLayers(tex2d_arr) - 1i)), vec4<i32>());
+  textureStore(tex3d, clamp(vec3<i32>(10, 20, 30), vec3<i32>(), (textureDimensions(tex3d) - vec3<i32>(1i))), vec4<i32>());
 }
 
 @group(0) @binding(0) var tex1d : texture_storage_1d<rgba8sint, write>;
@@ -1498,21 +1498,21 @@
 @group(1) @binding(0) var<uniform> u : U;
 
 fn f() {
-  var i32_sa1 : f32 = s.a[3];
-  var i32_sa2 : f32 = s.a[1];
-  var i32_sa3 : f32 = s.a[0];
-  var i32_sa4 : f32 = s.a[0];
-  var i32_sa5 : f32 = s.a[0];
+  var i32_sa1 : f32 = s.a[3i];
+  var i32_sa2 : f32 = s.a[1i];
+  var i32_sa3 : f32 = s.a[0i];
+  var i32_sa4 : f32 = s.a[0i];
+  var i32_sa5 : f32 = s.a[0i];
   var i32_sb1 : f32 = s.b[min(4u, (arrayLength(&(s.b)) - 1u))];
   var i32_sb2 : f32 = s.b[min(1u, (arrayLength(&(s.b)) - 1u))];
   var i32_sb3 : f32 = s.b[min(0u, (arrayLength(&(s.b)) - 1u))];
   var i32_sb4 : f32 = s.b[min(0u, (arrayLength(&(s.b)) - 1u))];
   var i32_sb5 : f32 = s.b[min(0u, (arrayLength(&(s.b)) - 1u))];
-  var i32_ua1 : f32 = u.a[3].x;
-  var i32_ua2 : f32 = u.a[1].x;
-  var i32_ua3 : f32 = u.a[0].x;
-  var i32_ua4 : f32 = u.a[0].x;
-  var i32_ua5 : f32 = u.a[0].x;
+  var i32_ua1 : f32 = u.a[3i].x;
+  var i32_ua2 : f32 = u.a[1i].x;
+  var i32_ua3 : f32 = u.a[0i].x;
+  var i32_ua4 : f32 = u.a[0i].x;
+  var i32_ua5 : f32 = u.a[0i].x;
   var u32_sa1 : f32 = s.a[0u];
   var u32_sa2 : f32 = s.a[1u];
   var u32_sa3 : f32 = s.a[3u];
@@ -1571,11 +1571,11 @@
   var i32_sb3 : f32 = s.b[0];
   var i32_sb4 : f32 = s.b[-1];
   var i32_sb5 : f32 = s.b[-4];
-  var i32_ua1 : f32 = u.a[3].x;
-  var i32_ua2 : f32 = u.a[1].x;
-  var i32_ua3 : f32 = u.a[0].x;
-  var i32_ua4 : f32 = u.a[0].x;
-  var i32_ua5 : f32 = u.a[0].x;
+  var i32_ua1 : f32 = u.a[3i].x;
+  var i32_ua2 : f32 = u.a[1i].x;
+  var i32_ua3 : f32 = u.a[0i].x;
+  var i32_ua4 : f32 = u.a[0i].x;
+  var i32_ua5 : f32 = u.a[0i].x;
   var u32_sa1 : f32 = s.a[0u];
   var u32_sa2 : f32 = s.a[1u];
   var u32_sa3 : f32 = s.a[3u];
@@ -1626,11 +1626,11 @@
 @group(1) @binding(0) var<uniform> u : U;
 
 fn f() {
-  var i32_sa1 : f32 = s.a[3];
-  var i32_sa2 : f32 = s.a[1];
-  var i32_sa3 : f32 = s.a[0];
-  var i32_sa4 : f32 = s.a[0];
-  var i32_sa5 : f32 = s.a[0];
+  var i32_sa1 : f32 = s.a[3i];
+  var i32_sa2 : f32 = s.a[1i];
+  var i32_sa3 : f32 = s.a[0i];
+  var i32_sa4 : f32 = s.a[0i];
+  var i32_sa5 : f32 = s.a[0i];
   var i32_sb1 : f32 = s.b[min(4u, (arrayLength(&(s.b)) - 1u))];
   var i32_sb2 : f32 = s.b[min(1u, (arrayLength(&(s.b)) - 1u))];
   var i32_sb3 : f32 = s.b[min(0u, (arrayLength(&(s.b)) - 1u))];
diff --git a/src/tint/transform/transform.cc b/src/tint/transform/transform.cc
index f1873f6..e3d0ea9 100644
--- a/src/tint/transform/transform.cc
+++ b/src/tint/transform/transform.cc
@@ -110,7 +110,7 @@
         if (a->IsRuntimeSized()) {
             return ctx.dst->ty.array(el, nullptr, std::move(attrs));
         } else {
-            return ctx.dst->ty.array(el, a->Count(), std::move(attrs));
+            return ctx.dst->ty.array(el, u32(a->Count()), std::move(attrs));
         }
     }
     if (auto* s = ty->As<sem::Struct>()) {
diff --git a/src/tint/transform/utils/get_insertion_point_test.cc b/src/tint/transform/utils/get_insertion_point_test.cc
index 83eb76d..071cfea 100644
--- a/src/tint/transform/utils/get_insertion_point_test.cc
+++ b/src/tint/transform/utils/get_insertion_point_test.cc
@@ -20,6 +20,8 @@
 #include "src/tint/transform/test_helper.h"
 #include "src/tint/transform/utils/get_insertion_point.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::transform {
 namespace {
 
@@ -27,10 +29,10 @@
 
 TEST_F(GetInsertionPointTest, Block) {
     // fn f() {
-    //     var a = 1;
+    //     var a = 1i;
     // }
     ProgramBuilder b;
-    auto* expr = b.Expr(1);
+    auto* expr = b.Expr(1_i);
     auto* var = b.Decl(b.Var("a", nullptr, expr));
     auto* block = b.Block(var);
     b.Func("f", {}, b.ty.void_(), {block});
@@ -48,11 +50,11 @@
 
 TEST_F(GetInsertionPointTest, ForLoopInit) {
     // fn f() {
-    //     for(var a = 1; true; ) {
+    //     for(var a = 1i; true; ) {
     //     }
     // }
     ProgramBuilder b;
-    auto* expr = b.Expr(1);
+    auto* expr = b.Expr(1_i);
     auto* var = b.Decl(b.Var("a", nullptr, expr));
     auto* fl = b.For(var, b.Expr(true), {}, b.Block());
     auto* func_block = b.Block(fl);
@@ -70,11 +72,11 @@
 
 TEST_F(GetInsertionPointTest, ForLoopCont_Invalid) {
     // fn f() {
-    //     for(; true; var a = 1) {
+    //     for(; true; var a = 1i) {
     //     }
     // }
     ProgramBuilder b;
-    auto* expr = b.Expr(1);
+    auto* expr = b.Expr(1_i);
     auto* var = b.Decl(b.Var("a", nullptr, expr));
     auto* s = b.For({}, b.Expr(true), var, b.Block());
     b.Func("f", {}, b.ty.void_(), {s});
diff --git a/src/tint/transform/utils/hoist_to_decl_before_test.cc b/src/tint/transform/utils/hoist_to_decl_before_test.cc
index e675fac..1e4cb8e 100644
--- a/src/tint/transform/utils/hoist_to_decl_before_test.cc
+++ b/src/tint/transform/utils/hoist_to_decl_before_test.cc
@@ -21,6 +21,8 @@
 #include "src/tint/transform/test_helper.h"
 #include "src/tint/transform/utils/hoist_to_decl_before.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::transform {
 namespace {
 
@@ -31,7 +33,7 @@
     //     var a = 1;
     // }
     ProgramBuilder b;
-    auto* expr = b.Expr(1);
+    auto* expr = b.Expr(1_i);
     auto* var = b.Decl(b.Var("a", nullptr, expr));
     b.Func("f", {}, b.ty.void_(), {var});
 
@@ -49,7 +51,7 @@
 
     auto* expect = R"(
 fn f() {
-  let tint_symbol = 1;
+  let tint_symbol = 1i;
   var a = tint_symbol;
 }
 )";
@@ -59,11 +61,11 @@
 
 TEST_F(HoistToDeclBeforeTest, ForLoopInit) {
     // fn f() {
-    //     for(var a = 1; true; ) {
+    //     for(var a = 1i; true; ) {
     //     }
     // }
     ProgramBuilder b;
-    auto* expr = b.Expr(1);
+    auto* expr = b.Expr(1_i);
     auto* s = b.For(b.Decl(b.Var("a", nullptr, expr)), b.Expr(true), {}, b.Block());
     b.Func("f", {}, b.ty.void_(), {s});
 
@@ -81,7 +83,7 @@
 
     auto* expect = R"(
 fn f() {
-  let tint_symbol = 1;
+  let tint_symbol = 1i;
   for(var a = tint_symbol; true; ) {
   }
 }
@@ -133,11 +135,11 @@
 
 TEST_F(HoistToDeclBeforeTest, ForLoopCont) {
     // fn f() {
-    //     for(; true; var a = 1) {
+    //     for(; true; var a = 1i) {
     //     }
     // }
     ProgramBuilder b;
-    auto* expr = b.Expr(1);
+    auto* expr = b.Expr(1_i);
     auto* s = b.For({}, b.Expr(true), b.Decl(b.Var("a", nullptr, expr)), b.Block());
     b.Func("f", {}, b.ty.void_(), {s});
 
@@ -163,7 +165,7 @@
     }
 
     continuing {
-      let tint_symbol = 1;
+      let tint_symbol = 1i;
       var a = tint_symbol;
     }
   }
@@ -223,8 +225,8 @@
     //     var b = a[0];
     // }
     ProgramBuilder b;
-    auto* var1 = b.Decl(b.Var("a", b.ty.array<ProgramBuilder::i32, 10>()));
-    auto* expr = b.IndexAccessor("a", 0);
+    auto* var1 = b.Decl(b.Var("a", b.ty.array<i32, 10>()));
+    auto* expr = b.IndexAccessor("a", 0_i);
     auto* var2 = b.Decl(b.Var("b", nullptr, expr));
     b.Func("f", {}, b.ty.void_(), {var1, var2});
 
@@ -242,8 +244,8 @@
 
     auto* expect = R"(
 fn f() {
-  var a : array<i32, 10>;
-  let tint_symbol = a[0];
+  var a : array<i32, 10u>;
+  let tint_symbol = a[0i];
   var b = tint_symbol;
 }
 )";
@@ -258,8 +260,8 @@
     // }
     ProgramBuilder b;
 
-    auto* var1 = b.Decl(b.Var("a", b.ty.array(b.ty.array<ProgramBuilder::i32, 10>(), 10)));
-    auto* expr = b.IndexAccessor(b.IndexAccessor("a", 0), 0);
+    auto* var1 = b.Decl(b.Var("a", b.ty.array(b.ty.array<i32, 10>(), 10_i)));
+    auto* expr = b.IndexAccessor(b.IndexAccessor("a", 0_i), 0_i);
     auto* var2 = b.Decl(b.Var("b", nullptr, expr));
     b.Func("f", {}, b.ty.void_(), {var1, var2});
 
@@ -277,8 +279,8 @@
 
     auto* expect = R"(
 fn f() {
-  var a : array<array<i32, 10>, 10>;
-  let tint_symbol = a[0][0];
+  var a : array<array<i32, 10u>, 10i>;
+  let tint_symbol = a[0i][0i];
   var b = tint_symbol;
 }
 )";
@@ -328,11 +330,11 @@
 
 TEST_F(HoistToDeclBeforeTest, Prepare_ForLoopCont) {
     // fn f() {
-    //     for(; true; var a = 1) {
+    //     for(; true; var a = 1i) {
     //     }
     // }
     ProgramBuilder b;
-    auto* expr = b.Expr(1);
+    auto* expr = b.Expr(1_i);
     auto* s = b.For({}, b.Expr(true), b.Decl(b.Var("a", nullptr, expr)), b.Block());
     b.Func("f", {}, b.ty.void_(), {s});
 
@@ -358,7 +360,7 @@
     }
 
     continuing {
-      var a = 1;
+      var a = 1i;
     }
   }
 }
@@ -414,11 +416,11 @@
     // fn foo() {
     // }
     // fn f() {
-    //     var a = 1;
+    //     var a = 1i;
     // }
     ProgramBuilder b;
     b.Func("foo", {}, b.ty.void_(), {});
-    auto* var = b.Decl(b.Var("a", nullptr, b.Expr(1)));
+    auto* var = b.Decl(b.Var("a", nullptr, b.Expr(1_i)));
     b.Func("f", {}, b.ty.void_(), {var});
 
     Program original(std::move(b));
@@ -440,7 +442,7 @@
 
 fn f() {
   foo();
-  var a = 1;
+  var a = 1i;
 }
 )";
 
@@ -451,12 +453,12 @@
     // fn foo() {
     // }
     // fn f() {
-    //     for(var a = 1; true;) {
+    //     for(var a = 1i; true;) {
     //     }
     // }
     ProgramBuilder b;
     b.Func("foo", {}, b.ty.void_(), {});
-    auto* var = b.Decl(b.Var("a", nullptr, b.Expr(1)));
+    auto* var = b.Decl(b.Var("a", nullptr, b.Expr(1_i)));
     auto* s = b.For(var, b.Expr(true), {}, b.Block());
     b.Func("f", {}, b.ty.void_(), {s});
 
@@ -479,7 +481,7 @@
 
 fn f() {
   foo();
-  for(var a = 1; true; ) {
+  for(var a = 1i; true; ) {
   }
 }
 )";
@@ -491,14 +493,14 @@
     // fn foo() {
     // }
     // fn f() {
-    //     var a = 1;
-    //     for(; true; a+=1) {
+    //     var a = 1i;
+    //     for(; true; a+=1i) {
     //     }
     // }
     ProgramBuilder b;
     b.Func("foo", {}, b.ty.void_(), {});
-    auto* var = b.Decl(b.Var("a", nullptr, b.Expr(1)));
-    auto* cont = b.CompoundAssign("a", b.Expr(1), ast::BinaryOp::kAdd);
+    auto* var = b.Decl(b.Var("a", nullptr, b.Expr(1_i)));
+    auto* cont = b.CompoundAssign("a", b.Expr(1_i), ast::BinaryOp::kAdd);
     auto* s = b.For({}, b.Expr(true), cont, b.Block());
     b.Func("f", {}, b.ty.void_(), {var, s});
 
@@ -520,7 +522,7 @@
 }
 
 fn f() {
-  var a = 1;
+  var a = 1i;
   loop {
     if (!(true)) {
       break;
@@ -530,7 +532,7 @@
 
     continuing {
       foo();
-      a += 1;
+      a += 1i;
     }
   }
 }
diff --git a/src/tint/transform/vertex_pulling.cc b/src/tint/transform/vertex_pulling.cc
index d383860..6d315f5 100644
--- a/src/tint/transform/vertex_pulling.cc
+++ b/src/tint/transform/vertex_pulling.cc
@@ -28,6 +28,8 @@
 TINT_INSTANTIATE_TYPEINFO(tint::transform::VertexPulling);
 TINT_INSTANTIATE_TYPEINFO(tint::transform::VertexPulling::Config);
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::transform {
 
 namespace {
@@ -250,11 +252,11 @@
     void AddVertexStorageBuffers() {
         // Creating the struct type
         static const char kStructName[] = "TintVertexData";
-        auto* struct_type = ctx.dst->Structure(
-            ctx.dst->Symbols().New(kStructName),
-            {
-                ctx.dst->Member(GetStructBufferName(), ctx.dst->ty.array<ProgramBuilder::u32>()),
-            });
+        auto* struct_type =
+            ctx.dst->Structure(ctx.dst->Symbols().New(kStructName),
+                               {
+                                   ctx.dst->Member(GetStructBufferName(), ctx.dst->ty.array<u32>()),
+                               });
         for (uint32_t i = 0; i < cfg.vertex_state.size(); ++i) {
             // The decorated variable with struct type
             ctx.dst->Global(GetVertexBufferName(i), ctx.dst->ty.Of(struct_type),
@@ -297,7 +299,7 @@
 
             auto* attribute_offset = index_expr;
             if (buffer_layout.array_stride != 4) {
-                attribute_offset = ctx.dst->Mul(index_expr, buffer_layout.array_stride / 4u);
+                attribute_offset = ctx.dst->Mul(index_expr, u32(buffer_layout.array_stride / 4u));
             }
 
             // let pulling_offset_n = <attribute_offset>
@@ -359,13 +361,13 @@
                         case BaseType::kI32:
                             ty = ctx.dst->ty.i32();
                             for (uint32_t i = fmt_dt.width; i < var_dt.width; i++) {
-                                values.emplace_back(ctx.dst->Expr((i == 3) ? 1 : 0));
+                                values.emplace_back(ctx.dst->Expr(i32((i == 3) ? 1 : 0)));
                             }
                             break;
                         case BaseType::kU32:
                             ty = ctx.dst->ty.u32();
                             for (uint32_t i = fmt_dt.width; i < var_dt.width; i++) {
-                                values.emplace_back(ctx.dst->Expr((i == 3) ? 1u : 0u));
+                                values.emplace_back(ctx.dst->Expr(u32((i == 3) ? 1u : 0u)));
                             }
                             break;
                         case BaseType::kF32:
@@ -403,10 +405,6 @@
                                  uint32_t offset,
                                  uint32_t buffer,
                                  VertexFormat format) {
-        using u32 = ProgramBuilder::u32;
-        using i32 = ProgramBuilder::i32;
-        using f32 = ProgramBuilder::f32;
-
         // Returns a u32 loaded from buffer_base + offset.
         auto load_u32 = [&] {
             return LoadPrimitive(array_base, offset, buffer, VertexFormat::kUint32);
@@ -433,17 +431,17 @@
                 LoadPrimitive(array_base, low_u32_offset, buffer, VertexFormat::kUint32);
             switch (offset & 3) {
                 case 0:
-                    return ctx.dst->Shl(low_u32, 16u);
+                    return ctx.dst->Shl(low_u32, 16_u);
                 case 1:
-                    return ctx.dst->And(ctx.dst->Shl(low_u32, 8u), 0xffff0000u);
+                    return ctx.dst->And(ctx.dst->Shl(low_u32, 8_u), 0xffff0000_u);
                 case 2:
-                    return ctx.dst->And(low_u32, 0xffff0000u);
+                    return ctx.dst->And(low_u32, 0xffff0000_u);
                 default: {  // 3:
                     auto* high_u32 = LoadPrimitive(array_base, low_u32_offset + 4, buffer,
                                                    VertexFormat::kUint32);
-                    auto* shr = ctx.dst->Shr(low_u32, 8u);
-                    auto* shl = ctx.dst->Shl(high_u32, 24u);
-                    return ctx.dst->And(ctx.dst->Or(shl, shr), 0xffff0000u);
+                    auto* shr = ctx.dst->Shr(low_u32, 8_u);
+                    auto* shl = ctx.dst->Shl(high_u32, 24_u);
+                    return ctx.dst->And(ctx.dst->Or(shl, shr), 0xffff0000_u);
                 }
             }
         };
@@ -456,17 +454,17 @@
                 LoadPrimitive(array_base, low_u32_offset, buffer, VertexFormat::kUint32);
             switch (offset & 3) {
                 case 0:
-                    return ctx.dst->And(low_u32, 0xffffu);
+                    return ctx.dst->And(low_u32, 0xffff_u);
                 case 1:
-                    return ctx.dst->And(ctx.dst->Shr(low_u32, 8u), 0xffffu);
+                    return ctx.dst->And(ctx.dst->Shr(low_u32, 8_u), 0xffff_u);
                 case 2:
-                    return ctx.dst->Shr(low_u32, 16u);
+                    return ctx.dst->Shr(low_u32, 16_u);
                 default: {  // 3:
                     auto* high_u32 = LoadPrimitive(array_base, low_u32_offset + 4, buffer,
                                                    VertexFormat::kUint32);
-                    auto* shr = ctx.dst->Shr(low_u32, 24u);
-                    auto* shl = ctx.dst->Shl(high_u32, 8u);
-                    return ctx.dst->And(ctx.dst->Or(shl, shr), 0xffffu);
+                    auto* shr = ctx.dst->Shr(low_u32, 24_u);
+                    auto* shl = ctx.dst->Shl(high_u32, 8_u);
+                    return ctx.dst->And(ctx.dst->Or(shl, shr), 0xffff_u);
                 }
             }
         };
@@ -517,25 +515,25 @@
                 // yyxx0000, yyxx0000
                 auto* u16s = ctx.dst->vec2<u32>(load_u16_h());
                 // xx000000, yyxx0000
-                auto* shl = ctx.dst->Shl(u16s, ctx.dst->vec2<u32>(8u, 0u));
+                auto* shl = ctx.dst->Shl(u16s, ctx.dst->vec2<u32>(8_u, 0_u));
                 // 000000xx, 000000yy
-                return ctx.dst->Shr(shl, ctx.dst->vec2<u32>(24u));
+                return ctx.dst->Shr(shl, ctx.dst->vec2<u32>(24_u));
             }
             case VertexFormat::kUint8x4: {
                 // wwzzyyxx, wwzzyyxx, wwzzyyxx, wwzzyyxx
                 auto* u32s = ctx.dst->vec4<u32>(load_u32());
                 // xx000000, yyxx0000, zzyyxx00, wwzzyyxx
-                auto* shl = ctx.dst->Shl(u32s, ctx.dst->vec4<u32>(24u, 16u, 8u, 0u));
+                auto* shl = ctx.dst->Shl(u32s, ctx.dst->vec4<u32>(24_u, 16_u, 8_u, 0_u));
                 // 000000xx, 000000yy, 000000zz, 000000ww
-                return ctx.dst->Shr(shl, ctx.dst->vec4<u32>(24u));
+                return ctx.dst->Shr(shl, ctx.dst->vec4<u32>(24_u));
             }
             case VertexFormat::kUint16x2: {
                 // yyyyxxxx, yyyyxxxx
                 auto* u32s = ctx.dst->vec2<u32>(load_u32());
                 // xxxx0000, yyyyxxxx
-                auto* shl = ctx.dst->Shl(u32s, ctx.dst->vec2<u32>(16u, 0u));
+                auto* shl = ctx.dst->Shl(u32s, ctx.dst->vec2<u32>(16_u, 0_u));
                 // 0000xxxx, 0000yyyy
-                return ctx.dst->Shr(shl, ctx.dst->vec2<u32>(16u));
+                return ctx.dst->Shr(shl, ctx.dst->vec2<u32>(16_u));
             }
             case VertexFormat::kUint16x4: {
                 // yyyyxxxx, wwwwzzzz
@@ -543,33 +541,33 @@
                 // yyyyxxxx, yyyyxxxx, wwwwzzzz, wwwwzzzz
                 auto* xxyy = ctx.dst->MemberAccessor(u32s, "xxyy");
                 // xxxx0000, yyyyxxxx, zzzz0000, wwwwzzzz
-                auto* shl = ctx.dst->Shl(xxyy, ctx.dst->vec4<u32>(16u, 0u, 16u, 0u));
+                auto* shl = ctx.dst->Shl(xxyy, ctx.dst->vec4<u32>(16_u, 0_u, 16_u, 0_u));
                 // 0000xxxx, 0000yyyy, 0000zzzz, 0000wwww
-                return ctx.dst->Shr(shl, ctx.dst->vec4<u32>(16u));
+                return ctx.dst->Shr(shl, ctx.dst->vec4<u32>(16_u));
             }
             case VertexFormat::kSint8x2: {
                 // yyxx0000, yyxx0000
                 auto* i16s = ctx.dst->vec2<i32>(load_i16_h());
                 // xx000000, yyxx0000
-                auto* shl = ctx.dst->Shl(i16s, ctx.dst->vec2<u32>(8u, 0u));
+                auto* shl = ctx.dst->Shl(i16s, ctx.dst->vec2<u32>(8_u, 0_u));
                 // ssssssxx, ssssssyy
-                return ctx.dst->Shr(shl, ctx.dst->vec2<u32>(24u));
+                return ctx.dst->Shr(shl, ctx.dst->vec2<u32>(24_u));
             }
             case VertexFormat::kSint8x4: {
                 // wwzzyyxx, wwzzyyxx, wwzzyyxx, wwzzyyxx
                 auto* i32s = ctx.dst->vec4<i32>(load_i32());
                 // xx000000, yyxx0000, zzyyxx00, wwzzyyxx
-                auto* shl = ctx.dst->Shl(i32s, ctx.dst->vec4<u32>(24u, 16u, 8u, 0u));
+                auto* shl = ctx.dst->Shl(i32s, ctx.dst->vec4<u32>(24_u, 16_u, 8_u, 0_u));
                 // ssssssxx, ssssssyy, sssssszz, ssssssww
-                return ctx.dst->Shr(shl, ctx.dst->vec4<u32>(24u));
+                return ctx.dst->Shr(shl, ctx.dst->vec4<u32>(24_u));
             }
             case VertexFormat::kSint16x2: {
                 // yyyyxxxx, yyyyxxxx
                 auto* i32s = ctx.dst->vec2<i32>(load_i32());
                 // xxxx0000, yyyyxxxx
-                auto* shl = ctx.dst->Shl(i32s, ctx.dst->vec2<u32>(16u, 0u));
+                auto* shl = ctx.dst->Shl(i32s, ctx.dst->vec2<u32>(16_u, 0_u));
                 // ssssxxxx, ssssyyyy
-                return ctx.dst->Shr(shl, ctx.dst->vec2<u32>(16u));
+                return ctx.dst->Shr(shl, ctx.dst->vec2<u32>(16_u));
             }
             case VertexFormat::kSint16x4: {
                 // yyyyxxxx, wwwwzzzz
@@ -577,9 +575,9 @@
                 // yyyyxxxx, yyyyxxxx, wwwwzzzz, wwwwzzzz
                 auto* xxyy = ctx.dst->MemberAccessor(i32s, "xxyy");
                 // xxxx0000, yyyyxxxx, zzzz0000, wwwwzzzz
-                auto* shl = ctx.dst->Shl(xxyy, ctx.dst->vec4<u32>(16u, 0u, 16u, 0u));
+                auto* shl = ctx.dst->Shl(xxyy, ctx.dst->vec4<u32>(16_u, 0_u, 16_u, 0_u));
                 // ssssxxxx, ssssyyyy, sssszzzz, sssswwww
-                return ctx.dst->Shr(shl, ctx.dst->vec4<u32>(16u));
+                return ctx.dst->Shr(shl, ctx.dst->vec4<u32>(16_u));
             }
             case VertexFormat::kUnorm8x2:
                 return ctx.dst->MemberAccessor(ctx.dst->Call("unpack4x8unorm", load_u16_l()), "xy");
@@ -623,17 +621,17 @@
                                          uint32_t offset,
                                          uint32_t buffer,
                                          VertexFormat format) {
-        const ast::Expression* u32 = nullptr;
+        const ast::Expression* u = nullptr;
         if ((offset & 3) == 0) {
             // Aligned load.
 
             const ast ::Expression* index = nullptr;
             if (offset > 0) {
-                index = ctx.dst->Add(array_base, offset / 4);
+                index = ctx.dst->Add(array_base, u32(offset / 4));
             } else {
                 index = ctx.dst->Expr(array_base);
             }
-            u32 = ctx.dst->IndexAccessor(
+            u = ctx.dst->IndexAccessor(
                 ctx.dst->MemberAccessor(GetVertexBufferName(buffer), GetStructBufferName()), index);
 
         } else {
@@ -645,18 +643,18 @@
 
             uint32_t shift = 8u * (offset & 3u);
 
-            auto* low_shr = ctx.dst->Shr(low, shift);
-            auto* high_shl = ctx.dst->Shl(high, 32u - shift);
-            u32 = ctx.dst->Or(low_shr, high_shl);
+            auto* low_shr = ctx.dst->Shr(low, u32(shift));
+            auto* high_shl = ctx.dst->Shl(high, u32(32u - shift));
+            u = ctx.dst->Or(low_shr, high_shl);
         }
 
         switch (format) {
             case VertexFormat::kUint32:
-                return u32;
+                return u;
             case VertexFormat::kSint32:
-                return ctx.dst->Bitcast(ctx.dst->ty.i32(), u32);
+                return ctx.dst->Bitcast(ctx.dst->ty.i32(), u);
             case VertexFormat::kFloat32:
-                return ctx.dst->Bitcast(ctx.dst->ty.f32(), u32);
+                return ctx.dst->Bitcast(ctx.dst->ty.f32(), u);
             default:
                 break;
         }
diff --git a/src/tint/transform/vertex_pulling_test.cc b/src/tint/transform/vertex_pulling_test.cc
index 82e28b3..80768a7 100644
--- a/src/tint/transform/vertex_pulling_test.cc
+++ b/src/tint/transform/vertex_pulling_test.cc
@@ -1178,7 +1178,7 @@
     snorm8x4 = unpack4x8snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]).x;
     uint16x2 = vec3<u32>(((vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]) << vec2<u32>(16u, 0u)) >> vec2<u32>(16u)), 0u);
     uint16x4 = (((vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]).xxyy << vec4<u32>(16u, 0u, 16u, 0u)) >> vec4<u32>(16u))).xy;
-    sint16x2 = vec4<i32>(((vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)])) << vec2<u32>(16u, 0u)) >> vec2<u32>(16u)), 0, 1);
+    sint16x2 = vec4<i32>(((vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)])) << vec2<u32>(16u, 0u)) >> vec2<u32>(16u)), 0i, 1i);
     sint16x4 = (((vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).xxyy << vec4<u32>(16u, 0u, 16u, 0u)) >> vec4<u32>(16u))).x;
     unorm16x2 = vec3<f32>(unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0.0);
     unorm16x4 = vec4<f32>(unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).x;
@@ -1194,8 +1194,8 @@
     uint32x2 = vec4<u32>(vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), 0u, 1u);
     uint32x3 = vec4<u32>(vec3<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]), 1u);
     uint32x4 = vec4<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)]).xy;
-    sint32 = vec4<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0, 0, 1);
-    sint32x2 = vec3<i32>(vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])), 0);
+    sint32 = vec4<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0i, 0i, 1i);
+    sint32x2 = vec3<i32>(vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])), 0i);
     sint32x3 = vec3<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)])).x;
     sint32x4 = vec4<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)])).xy;
   }
diff --git a/src/tint/transform/wrap_arrays_in_structs.cc b/src/tint/transform/wrap_arrays_in_structs.cc
index b47fa63..b1dc5e8 100644
--- a/src/tint/transform/wrap_arrays_in_structs.cc
+++ b/src/tint/transform/wrap_arrays_in_structs.cc
@@ -143,7 +143,7 @@
             if (!array->IsStrideImplicit()) {
                 attrs.emplace_back(c.dst->create<ast::StrideAttribute>(array->Stride()));
             }
-            return c.dst->ty.array(el_type(c), array->Count(), std::move(attrs));
+            return c.dst->ty.array(el_type(c), u32(array->Count()), std::move(attrs));
         };
 
         // Structure() will create and append the ast::Struct to the
diff --git a/src/tint/transform/zero_init_workgroup_memory.cc b/src/tint/transform/zero_init_workgroup_memory.cc
index b299c59..21a4565 100644
--- a/src/tint/transform/zero_init_workgroup_memory.cc
+++ b/src/tint/transform/zero_init_workgroup_memory.cc
@@ -208,10 +208,10 @@
                 auto idx = b.Symbols().New("idx");
                 auto* init = b.Decl(b.Var(idx, b.ty.u32(), local_index()));
                 auto* cond = b.create<ast::BinaryExpression>(ast::BinaryOp::kLessThan, b.Expr(idx),
-                                                             b.Expr(num_iterations));
-                auto* cont =
-                    b.Assign(idx, b.Add(idx, workgroup_size_const ? b.Expr(workgroup_size_const)
-                                                                  : workgroup_size_expr()));
+                                                             b.Expr(u32(num_iterations)));
+                auto* cont = b.Assign(
+                    idx, b.Add(idx, workgroup_size_const ? b.Expr(u32(workgroup_size_const))
+                                                         : workgroup_size_expr()));
 
                 auto block =
                     DeclareArrayIndices(num_iterations, array_indices, [&] { return b.Expr(idx); });
@@ -227,8 +227,8 @@
                 //  if (local_index < num_iterations) {
                 //    ...
                 //  }
-                auto* cond = b.create<ast::BinaryExpression>(ast::BinaryOp::kLessThan,
-                                                             local_index(), b.Expr(num_iterations));
+                auto* cond = b.create<ast::BinaryExpression>(
+                    ast::BinaryOp::kLessThan, local_index(), b.Expr(u32(num_iterations)));
                 auto block = DeclareArrayIndices(num_iterations, array_indices,
                                                  [&] { return b.Expr(local_index()); });
                 for (auto& s : stmts) {
@@ -337,9 +337,9 @@
             auto name = array_index_names.at(index);
             auto* mod = (num_iterations > index.modulo)
                             ? b.create<ast::BinaryExpression>(ast::BinaryOp::kModulo, iteration(),
-                                                              b.Expr(index.modulo))
+                                                              b.Expr(u32(index.modulo)))
                             : iteration();
-            auto* div = (index.division != 1u) ? b.Div(mod, index.division) : mod;
+            auto* div = (index.division != 1u) ? b.Div(mod, u32(index.division)) : mod;
             auto* decl = b.Decl(b.Let(name, b.ty.u32(), div));
             stmts.emplace_back(decl);
         }
@@ -371,7 +371,7 @@
             workgroup_size_expr = [this, expr, size = workgroup_size_expr] {
                 auto* e = ctx.Clone(expr);
                 if (ctx.src->TypeOf(expr)->UnwrapRef()->Is<sem::I32>()) {
-                    e = b.Construct<ProgramBuilder::u32>(e);
+                    e = b.Construct<u32>(e);
                 }
                 return size ? b.Mul(size(), e) : e;
             };
@@ -381,8 +381,8 @@
                 // Fold workgroup_size_const in to workgroup_size_expr
                 workgroup_size_expr = [this, is_signed, const_size = workgroup_size_const,
                                        expr_size = workgroup_size_expr] {
-                    return is_signed ? b.Mul(expr_size(), static_cast<int32_t>(const_size))
-                                     : b.Mul(expr_size(), const_size);
+                    return is_signed ? b.Mul(expr_size(), i32(const_size))
+                                     : b.Mul(expr_size(), u32(const_size));
                 };
             }
             // Indicate that workgroup_size_expr should be used instead of the
diff --git a/src/tint/writer/append_vector.cc b/src/tint/writer/append_vector.cc
index 767ad6e..d3d11c1 100644
--- a/src/tint/writer/append_vector.cc
+++ b/src/tint/writer/append_vector.cc
@@ -23,6 +23,8 @@
 #include "src/tint/sem/type_conversion.h"
 #include "src/tint/utils/transform.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer {
 namespace {
 
@@ -45,9 +47,9 @@
 const sem::Expression* Zero(ProgramBuilder& b, const sem::Type* ty, const sem::Statement* stmt) {
     const ast::Expression* expr = nullptr;
     if (ty->Is<sem::I32>()) {
-        expr = b.Expr(0);
+        expr = b.Expr(0_i);
     } else if (ty->Is<sem::U32>()) {
-        expr = b.Expr(0u);
+        expr = b.Expr(0_u);
     } else if (ty->Is<sem::F32>()) {
         expr = b.Expr(0.0f);
     } else if (ty->Is<sem::Bool>()) {
diff --git a/src/tint/writer/append_vector_test.cc b/src/tint/writer/append_vector_test.cc
index 7cb1243..5a9551e 100644
--- a/src/tint/writer/append_vector_test.cc
+++ b/src/tint/writer/append_vector_test.cc
@@ -19,6 +19,8 @@
 
 #include "gtest/gtest.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer {
 namespace {
 
@@ -26,9 +28,9 @@
 
 // AppendVector(vec2<i32>(1, 2), 3) -> vec3<i32>(1, 2, 3)
 TEST_F(AppendVectorTest, Vec2i32_i32) {
-    auto* scalar_1 = Expr(1);
-    auto* scalar_2 = Expr(2);
-    auto* scalar_3 = Expr(3);
+    auto* scalar_1 = Expr(1_i);
+    auto* scalar_2 = Expr(2_i);
+    auto* scalar_3 = Expr(3_i);
     auto* vec_12 = vec2<i32>(scalar_1, scalar_2);
     WrapInFunction(vec_12, scalar_3);
 
@@ -66,9 +68,9 @@
 
 // AppendVector(vec2<i32>(1, 2), 3u) -> vec3<i32>(1, 2, i32(3u))
 TEST_F(AppendVectorTest, Vec2i32_u32) {
-    auto* scalar_1 = Expr(1);
-    auto* scalar_2 = Expr(2);
-    auto* scalar_3 = Expr(3u);
+    auto* scalar_1 = Expr(1_i);
+    auto* scalar_2 = Expr(2_i);
+    auto* scalar_3 = Expr(3_u);
     auto* vec_12 = vec2<i32>(scalar_1, scalar_2);
     WrapInFunction(vec_12, scalar_3);
 
@@ -111,9 +113,9 @@
 // AppendVector(vec2<i32>(vec2<u32>(1u, 2u)), 3u) ->
 //    vec3<i32>(vec2<i32>(vec2<u32>(1u, 2u)), i32(3u))
 TEST_F(AppendVectorTest, Vec2i32FromVec2u32_u32) {
-    auto* scalar_1 = Expr(1u);
-    auto* scalar_2 = Expr(2u);
-    auto* scalar_3 = Expr(3u);
+    auto* scalar_1 = Expr(1_u);
+    auto* scalar_2 = Expr(2_u);
+    auto* scalar_3 = Expr(3_u);
     auto* uvec_12 = vec2<u32>(scalar_1, scalar_2);
     auto* vec_12 = vec2<i32>(uvec_12);
     WrapInFunction(vec_12, scalar_3);
@@ -160,8 +162,8 @@
 
 // AppendVector(vec2<i32>(1, 2), 3.0f) -> vec3<i32>(1, 2, i32(3.0f))
 TEST_F(AppendVectorTest, Vec2i32_f32) {
-    auto* scalar_1 = Expr(1);
-    auto* scalar_2 = Expr(2);
+    auto* scalar_1 = Expr(1_i);
+    auto* scalar_2 = Expr(2_i);
     auto* scalar_3 = Expr(3.0f);
     auto* vec_12 = vec2<i32>(scalar_1, scalar_2);
     WrapInFunction(vec_12, scalar_3);
@@ -204,10 +206,10 @@
 
 // AppendVector(vec3<i32>(1, 2, 3), 4) -> vec4<i32>(1, 2, 3, 4)
 TEST_F(AppendVectorTest, Vec3i32_i32) {
-    auto* scalar_1 = Expr(1);
-    auto* scalar_2 = Expr(2);
-    auto* scalar_3 = Expr(3);
-    auto* scalar_4 = Expr(4);
+    auto* scalar_1 = Expr(1_i);
+    auto* scalar_2 = Expr(2_i);
+    auto* scalar_3 = Expr(3_i);
+    auto* scalar_4 = Expr(4_i);
     auto* vec_123 = vec3<i32>(scalar_1, scalar_2, scalar_3);
     WrapInFunction(vec_123, scalar_4);
 
@@ -250,7 +252,7 @@
 TEST_F(AppendVectorTest, Vec2i32Var_i32) {
     Global("vec_12", ty.vec2<i32>(), ast::StorageClass::kPrivate);
     auto* vec_12 = Expr("vec_12");
-    auto* scalar_3 = Expr(3);
+    auto* scalar_3 = Expr(3_i);
     WrapInFunction(vec_12, scalar_3);
 
     resolver::Resolver resolver(this);
@@ -285,8 +287,8 @@
 // AppendVector(1, 2, scalar_3) -> vec3<i32>(1, 2, scalar_3)
 TEST_F(AppendVectorTest, Vec2i32_i32Var) {
     Global("scalar_3", ty.i32(), ast::StorageClass::kPrivate);
-    auto* scalar_1 = Expr(1);
-    auto* scalar_2 = Expr(2);
+    auto* scalar_1 = Expr(1_i);
+    auto* scalar_2 = Expr(2_i);
     auto* scalar_3 = Expr("scalar_3");
     auto* vec_12 = vec2<i32>(scalar_1, scalar_2);
     WrapInFunction(vec_12, scalar_3);
@@ -440,7 +442,7 @@
 
 // AppendVector(vec3<i32>(), 4) -> vec3<bool>(0, 0, 0, 4)
 TEST_F(AppendVectorTest, ZeroVec3i32_i32) {
-    auto* scalar = Expr(4);
+    auto* scalar = Expr(4_i);
     auto* vec000 = vec3<i32>();
     WrapInFunction(vec000, scalar);
 
diff --git a/src/tint/writer/glsl/generator_impl_array_accessor_test.cc b/src/tint/writer/glsl/generator_impl_array_accessor_test.cc
index ce1075c..d28e560 100644
--- a/src/tint/writer/glsl/generator_impl_array_accessor_test.cc
+++ b/src/tint/writer/glsl/generator_impl_array_accessor_test.cc
@@ -14,6 +14,8 @@
 
 #include "src/tint/writer/glsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::glsl {
 namespace {
 
@@ -21,7 +23,7 @@
 
 TEST_F(GlslGeneratorImplTest_Expression, IndexAccessor) {
     Global("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
-    auto* expr = IndexAccessor("ary", 5);
+    auto* expr = IndexAccessor("ary", 5_i);
     WrapInFunction(expr);
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/glsl/generator_impl_binary_test.cc b/src/tint/writer/glsl/generator_impl_binary_test.cc
index a389184..970a2b3 100644
--- a/src/tint/writer/glsl/generator_impl_binary_test.cc
+++ b/src/tint/writer/glsl/generator_impl_binary_test.cc
@@ -16,6 +16,8 @@
 #include "src/tint/ast/variable_decl_statement.h"
 #include "src/tint/writer/glsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::glsl {
 namespace {
 
@@ -329,11 +331,11 @@
 
 TEST_F(GlslGeneratorImplTest_Binary, If_WithLogical) {
     // if (a && b) {
-    //   return 1;
+    //   return 1i;
     // } else if (b || c) {
-    //   return 2;
+    //   return 2i;
     // } else {
-    //   return 3;
+    //   return 3i;
     // }
 
     Global("a", ty.bool_(), ast::StorageClass::kPrivate);
@@ -342,9 +344,9 @@
 
     auto* expr =
         If(create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b")),
-           Block(Return(1)),
+           Block(Return(1_i)),
            Else(If(create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, Expr("b"), Expr("c")),
-                   Block(Return(2)), Else(Block(Return(3))))));
+                   Block(Return(2_i)), Else(Block(Return(3_i))))));
     Func("func", {}, ty.i32(), {WrapInStatement(expr)});
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/glsl/generator_impl_bitcast_test.cc b/src/tint/writer/glsl/generator_impl_bitcast_test.cc
index 0ee8a22..a56c5dd 100644
--- a/src/tint/writer/glsl/generator_impl_bitcast_test.cc
+++ b/src/tint/writer/glsl/generator_impl_bitcast_test.cc
@@ -14,13 +14,15 @@
 
 #include "src/tint/writer/glsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::glsl {
 namespace {
 
 using GlslGeneratorImplTest_Bitcast = TestHelper;
 
 TEST_F(GlslGeneratorImplTest_Bitcast, EmitExpression_Bitcast_Float) {
-    auto* bitcast = create<ast::BitcastExpression>(ty.f32(), Expr(1));
+    auto* bitcast = create<ast::BitcastExpression>(ty.f32(), Expr(1_i));
     WrapInFunction(bitcast);
 
     GeneratorImpl& gen = Build();
@@ -31,7 +33,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Bitcast, EmitExpression_Bitcast_Int) {
-    auto* bitcast = create<ast::BitcastExpression>(ty.i32(), Expr(1u));
+    auto* bitcast = create<ast::BitcastExpression>(ty.i32(), Expr(1_u));
     WrapInFunction(bitcast);
 
     GeneratorImpl& gen = Build();
@@ -42,7 +44,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Bitcast, EmitExpression_Bitcast_Uint) {
-    auto* bitcast = create<ast::BitcastExpression>(ty.u32(), Expr(1));
+    auto* bitcast = create<ast::BitcastExpression>(ty.u32(), Expr(1_i));
     WrapInFunction(bitcast);
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/glsl/generator_impl_builtin_test.cc b/src/tint/writer/glsl/generator_impl_builtin_test.cc
index f01feff..311abd9 100644
--- a/src/tint/writer/glsl/generator_impl_builtin_test.cc
+++ b/src/tint/writer/glsl/generator_impl_builtin_test.cc
@@ -18,13 +18,15 @@
 #include "src/tint/sem/call.h"
 #include "src/tint/writer/glsl/test_helper.h"
 
+using ::testing::HasSubstr;
+
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::glsl {
 namespace {
 
 using BuiltinType = sem::BuiltinType;
 
-using ::testing::HasSubstr;
-
 using GlslGeneratorImplTest_Builtin = TestHelper;
 
 enum class ParamType {
@@ -267,7 +269,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Builtin, Select_Vector) {
-    auto* call = Call("select", vec2<i32>(1, 2), vec2<i32>(3, 4), vec2<bool>(true, false));
+    auto* call = Call("select", vec2<i32>(1_i, 2_i), vec2<i32>(3_i, 4_i), vec2<bool>(true, false));
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -766,7 +768,7 @@
     Func("main", {}, ty.void_(), {CallStmt(Call("storageBarrier"))},
          {
              Stage(ast::PipelineStage::kCompute),
-             WorkgroupSize(1),
+             WorkgroupSize(1_i),
          });
 
     GeneratorImpl& gen = Build();
@@ -786,7 +788,7 @@
     Func("main", {}, ty.void_(), {CallStmt(Call("workgroupBarrier"))},
          {
              Stage(ast::PipelineStage::kCompute),
-             WorkgroupSize(1),
+             WorkgroupSize(1_i),
          });
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/glsl/generator_impl_case_test.cc b/src/tint/writer/glsl/generator_impl_case_test.cc
index df50988..02d1665 100644
--- a/src/tint/writer/glsl/generator_impl_case_test.cc
+++ b/src/tint/writer/glsl/generator_impl_case_test.cc
@@ -15,13 +15,15 @@
 #include "src/tint/ast/fallthrough_statement.h"
 #include "src/tint/writer/glsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::glsl {
 namespace {
 
 using GlslGeneratorImplTest_Case = TestHelper;
 
 TEST_F(GlslGeneratorImplTest_Case, Emit_Case) {
-    auto* s = Switch(1, Case(Expr(5), Block(create<ast::BreakStatement>())), DefaultCase());
+    auto* s = Switch(1_i, Case(Expr(5_i), Block(create<ast::BreakStatement>())), DefaultCase());
     WrapInFunction(s);
 
     GeneratorImpl& gen = Build();
@@ -36,7 +38,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Case, Emit_Case_BreaksByDefault) {
-    auto* s = Switch(1, Case(Expr(5), Block()), DefaultCase());
+    auto* s = Switch(1_i, Case(Expr(5_i), Block()), DefaultCase());
     WrapInFunction(s);
 
     GeneratorImpl& gen = Build();
@@ -51,7 +53,8 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Case, Emit_Case_WithFallthrough) {
-    auto* s = Switch(1, Case(Expr(5), Block(create<ast::FallthroughStatement>())), DefaultCase());
+    auto* s =
+        Switch(1_i, Case(Expr(5_i), Block(create<ast::FallthroughStatement>())), DefaultCase());
     WrapInFunction(s);
 
     GeneratorImpl& gen = Build();
@@ -66,8 +69,8 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Case, Emit_Case_MultipleSelectors) {
-    auto* s =
-        Switch(1, Case({Expr(5), Expr(6)}, Block(create<ast::BreakStatement>())), DefaultCase());
+    auto* s = Switch(1_i, Case({Expr(5_i), Expr(6_i)}, Block(create<ast::BreakStatement>())),
+                     DefaultCase());
     WrapInFunction(s);
 
     GeneratorImpl& gen = Build();
@@ -83,7 +86,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Case, Emit_Case_Default) {
-    auto* s = Switch(1, DefaultCase(Block(create<ast::BreakStatement>())));
+    auto* s = Switch(1_i, DefaultCase(Block(create<ast::BreakStatement>())));
     WrapInFunction(s);
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/glsl/generator_impl_cast_test.cc b/src/tint/writer/glsl/generator_impl_cast_test.cc
index 7de8cc6..3666782 100644
--- a/src/tint/writer/glsl/generator_impl_cast_test.cc
+++ b/src/tint/writer/glsl/generator_impl_cast_test.cc
@@ -14,13 +14,15 @@
 
 #include "src/tint/writer/glsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::glsl {
 namespace {
 
 using GlslGeneratorImplTest_Cast = TestHelper;
 
 TEST_F(GlslGeneratorImplTest_Cast, EmitExpression_Cast_Scalar) {
-    auto* cast = Construct<f32>(1);
+    auto* cast = Construct<f32>(1_i);
     WrapInFunction(cast);
 
     GeneratorImpl& gen = Build();
@@ -31,7 +33,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Cast, EmitExpression_Cast_Vector) {
-    auto* cast = vec3<f32>(vec3<i32>(1, 2, 3));
+    auto* cast = vec3<f32>(vec3<i32>(1_i, 2_i, 3_i));
     WrapInFunction(cast);
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/glsl/generator_impl_constructor_test.cc b/src/tint/writer/glsl/generator_impl_constructor_test.cc
index 9d04309..c247bab 100644
--- a/src/tint/writer/glsl/generator_impl_constructor_test.cc
+++ b/src/tint/writer/glsl/generator_impl_constructor_test.cc
@@ -15,6 +15,8 @@
 #include "gmock/gmock.h"
 #include "src/tint/writer/glsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::glsl {
 namespace {
 
@@ -32,7 +34,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Constructor, EmitConstructor_Int) {
-    WrapInFunction(Expr(-12345));
+    WrapInFunction(Expr(i32(-12345)));
 
     GeneratorImpl& gen = Build();
 
@@ -41,7 +43,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Constructor, EmitConstructor_UInt) {
-    WrapInFunction(Expr(56779u));
+    WrapInFunction(Expr(56779_u));
 
     GeneratorImpl& gen = Build();
 
@@ -51,7 +53,7 @@
 
 TEST_F(GlslGeneratorImplTest_Constructor, EmitConstructor_Float) {
     // Use a number close to 1<<30 but whose decimal representation ends in 0.
-    WrapInFunction(Expr(static_cast<float>((1 << 30) - 4)));
+    WrapInFunction(Expr(f32((1 << 30) - 4)));
 
     GeneratorImpl& gen = Build();
 
@@ -78,7 +80,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Constructor, EmitConstructor_Type_Int) {
-    WrapInFunction(Construct<i32>(-12345));
+    WrapInFunction(Construct<i32>(i32(-12345)));
 
     GeneratorImpl& gen = Build();
 
@@ -87,7 +89,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Constructor, EmitConstructor_Type_Uint) {
-    WrapInFunction(Construct<u32>(12345u));
+    WrapInFunction(Construct<u32>(12345_u));
 
     GeneratorImpl& gen = Build();
 
@@ -132,7 +134,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Constructor, EmitConstructor_Type_Vec_SingleScalar_Int) {
-    WrapInFunction(vec3<i32>(2));
+    WrapInFunction(vec3<i32>(2_i));
 
     GeneratorImpl& gen = Build();
 
@@ -141,7 +143,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Constructor, EmitConstructor_Type_Vec_SingleScalar_UInt) {
-    WrapInFunction(vec3<u32>(2u));
+    WrapInFunction(vec3<u32>(2_u));
 
     GeneratorImpl& gen = Build();
 
@@ -170,7 +172,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Constructor, EmitConstructor_Type_Array) {
-    WrapInFunction(Construct(ty.array(ty.vec3<f32>(), 3), vec3<f32>(1.f, 2.f, 3.f),
+    WrapInFunction(Construct(ty.array(ty.vec3<f32>(), 3_u), vec3<f32>(1.f, 2.f, 3.f),
                              vec3<f32>(4.f, 5.f, 6.f), vec3<f32>(7.f, 8.f, 9.f)));
 
     GeneratorImpl& gen = Build();
@@ -182,7 +184,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Constructor, EmitConstructor_Type_Array_Empty) {
-    WrapInFunction(Construct(ty.array(ty.vec3<f32>(), 3)));
+    WrapInFunction(Construct(ty.array(ty.vec3<f32>(), 3_u)));
 
     GeneratorImpl& gen = Build();
 
@@ -198,7 +200,7 @@
                                    Member("c", ty.vec3<i32>()),
                                });
 
-    WrapInFunction(Construct(ty.Of(str), 1, 2.0f, vec3<i32>(3, 4, 5)));
+    WrapInFunction(Construct(ty.Of(str), 1_i, 2.0f, vec3<i32>(3_i, 4_i, 5_i)));
 
     GeneratorImpl& gen = SanitizeAndBuild();
 
diff --git a/src/tint/writer/glsl/generator_impl_function_test.cc b/src/tint/writer/glsl/generator_impl_function_test.cc
index 7254831..8b91cef 100644
--- a/src/tint/writer/glsl/generator_impl_function_test.cc
+++ b/src/tint/writer/glsl/generator_impl_function_test.cc
@@ -20,6 +20,8 @@
 
 using ::testing::HasSubstr;
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::glsl {
 namespace {
 
@@ -739,7 +741,7 @@
          {
              Return(),
          },
-         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     GeneratorImpl& gen = Build();
 
@@ -757,7 +759,7 @@
     Func("main", ast::VariableList{}, ty.void_(), {},
          {
              Stage(ast::PipelineStage::kCompute),
-             WorkgroupSize(2, 4, 6),
+             WorkgroupSize(2_i, 4_i, 6_i),
          });
 
     GeneratorImpl& gen = Build();
@@ -773,9 +775,9 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_Compute_WithWorkgroup_Const) {
-    GlobalConst("width", ty.i32(), Construct(ty.i32(), 2));
-    GlobalConst("height", ty.i32(), Construct(ty.i32(), 3));
-    GlobalConst("depth", ty.i32(), Construct(ty.i32(), 4));
+    GlobalConst("width", ty.i32(), Construct(ty.i32(), 2_i));
+    GlobalConst("height", ty.i32(), Construct(ty.i32(), 3_i));
+    GlobalConst("depth", ty.i32(), Construct(ty.i32(), 4_i));
     Func("main", ast::VariableList{}, ty.void_(), {},
          {
              Stage(ast::PipelineStage::kCompute),
@@ -799,9 +801,9 @@
 
 TEST_F(GlslGeneratorImplTest_Function,
        Emit_Attribute_EntryPoint_Compute_WithWorkgroup_OverridableConst) {
-    Override("width", ty.i32(), Construct(ty.i32(), 2), {Id(7u)});
-    Override("height", ty.i32(), Construct(ty.i32(), 3), {Id(8u)});
-    Override("depth", ty.i32(), Construct(ty.i32(), 4), {Id(9u)});
+    Override("width", ty.i32(), Construct(ty.i32(), 2_i), {Id(7u)});
+    Override("height", ty.i32(), Construct(ty.i32(), 3_i), {Id(8u)});
+    Override("depth", ty.i32(), Construct(ty.i32(), 4_i), {Id(9u)});
     Func("main", ast::VariableList{}, ty.void_(), {},
          {
              Stage(ast::PipelineStage::kCompute),
@@ -903,7 +905,7 @@
                  Decl(var),
                  Return(),
              },
-             {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+             {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
     }
 
     {
@@ -914,7 +916,7 @@
                  Decl(var),
                  Return(),
              },
-             {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+             {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
     }
 
     GeneratorImpl& gen = SanitizeAndBuild();
diff --git a/src/tint/writer/glsl/generator_impl_import_test.cc b/src/tint/writer/glsl/generator_impl_import_test.cc
index ed20460..a4a6440 100644
--- a/src/tint/writer/glsl/generator_impl_import_test.cc
+++ b/src/tint/writer/glsl/generator_impl_import_test.cc
@@ -14,6 +14,8 @@
 
 #include "src/tint/writer/glsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::glsl {
 namespace {
 
@@ -72,7 +74,7 @@
 TEST_P(GlslImportData_SingleIntParamTest, IntScalar) {
     auto param = GetParam();
 
-    auto* expr = Call(param.name, Expr(1));
+    auto* expr = Call(param.name, Expr(1_i));
     WrapInFunction(expr);
 
     GeneratorImpl& gen = Build();
@@ -177,7 +179,7 @@
 TEST_P(GlslImportData_DualParam_Int_Test, IntScalar) {
     auto param = GetParam();
 
-    auto* expr = Call(param.name, 1, 2);
+    auto* expr = Call(param.name, 1_i, 2_i);
     WrapInFunction(expr);
 
     GeneratorImpl& gen = Build();
@@ -240,7 +242,7 @@
 TEST_P(GlslImportData_TripleParam_Int_Test, IntScalar) {
     auto param = GetParam();
 
-    auto* expr = Call(param.name, 1, 2, 3);
+    auto* expr = Call(param.name, 1_i, 2_i, 3_i);
     WrapInFunction(expr);
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/glsl/generator_impl_loop_test.cc b/src/tint/writer/glsl/generator_impl_loop_test.cc
index 0d801c0..de29622 100644
--- a/src/tint/writer/glsl/generator_impl_loop_test.cc
+++ b/src/tint/writer/glsl/generator_impl_loop_test.cc
@@ -15,6 +15,8 @@
 #include "src/tint/ast/variable_decl_statement.h"
 #include "src/tint/writer/glsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::glsl {
 namespace {
 
@@ -261,12 +263,12 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Loop, Emit_ForLoopWithSimpleCont) {
-    // for(; ; i = i + 1) {
+    // for(; ; i = i + 1i) {
     //   return;
     // }
 
     auto* v = Decl(Var("i", ty.i32()));
-    auto* f = For(nullptr, nullptr, Assign("i", Add("i", 1)),  //
+    auto* f = For(nullptr, nullptr, Assign("i", Add("i", 1_i)),  //
                   Block(Return()));
     WrapInFunction(v, f);
 
@@ -314,11 +316,11 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Loop, Emit_ForLoopWithSimpleInitCondCont) {
-    // for(var i : i32; true; i = i + 1) {
+    // for(var i : i32; true; i = ii + 1) {
     //   return;
     // }
 
-    auto* f = For(Decl(Var("i", ty.i32())), true, Assign("i", Add("i", 1)), Block(Return()));
+    auto* f = For(Decl(Var("i", ty.i32())), true, Assign("i", Add("i", 1_i)), Block(Return()));
     WrapInFunction(f);
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/glsl/generator_impl_member_accessor_test.cc b/src/tint/writer/glsl/generator_impl_member_accessor_test.cc
index b3892fc..2fdc833 100644
--- a/src/tint/writer/glsl/generator_impl_member_accessor_test.cc
+++ b/src/tint/writer/glsl/generator_impl_member_accessor_test.cc
@@ -16,6 +16,8 @@
 #include "src/tint/ast/stage_attribute.h"
 #include "src/tint/writer/glsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::glsl {
 namespace {
 
@@ -81,10 +83,6 @@
     return ty.mat4x4<T>();
 }
 
-using i32 = ProgramBuilder::i32;
-using u32 = ProgramBuilder::u32;
-using f32 = ProgramBuilder::f32;
-
 template <typename BASE>
 class GlslGeneratorImplTest_MemberAccessorBase : public BASE {
   public:
@@ -310,7 +308,7 @@
     //   a : mat4x3<f32>;
     // };
     // var<storage> data : Data;
-    // data.a[2][1];
+    // data.a[2i][1i];
 
     SetupStorageBuffer({
         Member("z", ty.f32()),
@@ -319,7 +317,7 @@
 
     SetupFunction({
         Decl(Var("x", nullptr, ast::StorageClass::kNone,
-                 IndexAccessor(IndexAccessor(MemberAccessor("data", "a"), 2), 1))),
+                 IndexAccessor(IndexAccessor(MemberAccessor("data", "a"), 2_i), 1_i))),
     });
 
     GeneratorImpl& gen = SanitizeAndBuild();
@@ -365,7 +363,7 @@
 
     SetupFunction({
         Decl(Var("x", nullptr, ast::StorageClass::kNone,
-                 IndexAccessor(MemberAccessor("data", "a"), 2))),
+                 IndexAccessor(MemberAccessor("data", "a"), 2_i))),
     });
 
     GeneratorImpl& gen = SanitizeAndBuild();
@@ -399,10 +397,10 @@
 TEST_F(GlslGeneratorImplTest_MemberAccessor,
        EmitExpression_IndexAccessor_StorageBuffer_Load_Int_FromArray_ExprIdx) {
     // struct Data {
-    //   a : array<i32, 5>;
+    //   a : array<i32, 5u>;
     // };
     // var<storage> data : Data;
-    // data.a[(2 + 4) - 3];
+    // data.a[(2i + 4i) - 3i];
 
     SetupStorageBuffer({
         Member("z", ty.f32()),
@@ -411,7 +409,7 @@
 
     SetupFunction({
         Decl(Var("x", nullptr, ast::StorageClass::kNone,
-                 IndexAccessor(MemberAccessor("data", "a"), Sub(Add(2, Expr(4)), Expr(3))))),
+                 IndexAccessor(MemberAccessor("data", "a"), Sub(Add(2_i, 4_i), 3_i)))),
     });
 
     GeneratorImpl& gen = SanitizeAndBuild();
@@ -444,10 +442,10 @@
 
 TEST_F(GlslGeneratorImplTest_MemberAccessor, StorageBuffer_Store_ToArray) {
     // struct Data {
-    //   a : array<i32, 5>;
+    //   a : array<i32, 5u>;
     // };
     // var<storage> data : Data;
-    // data.a[2] = 2;
+    // data.a[2i] = 2i;
 
     SetupStorageBuffer({
         Member("z", ty.f32()),
@@ -455,7 +453,7 @@
     });
 
     SetupFunction({
-        Assign(IndexAccessor(MemberAccessor("data", "a"), 2), 2),
+        Assign(IndexAccessor(MemberAccessor("data", "a"), 2_i), 2_i),
     });
 
     GeneratorImpl& gen = SanitizeAndBuild();
@@ -492,11 +490,11 @@
     //   b : vec3<f32>;
     // };
     // struct Data {
-    //   var c : array<Inner, 4>;
+    //   var c : array<Inner, 4u>;
     // };
     //
     // var<storage> data : Pre;
-    // data.c[2].b
+    // data.c[2i].b
 
     auto* inner = Structure("Inner", {
                                          Member("a", ty.vec3<f32>()),
@@ -504,12 +502,12 @@
                                      });
 
     SetupStorageBuffer({
-        Member("c", ty.array(ty.Of(inner), 4, 32)),
+        Member("c", ty.array(ty.Of(inner), 4_u, 32)),
     });
 
     SetupFunction({
         Decl(Var("x", nullptr, ast::StorageClass::kNone,
-                 MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2), "b"))),
+                 MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"))),
     });
 
     GeneratorImpl& gen = SanitizeAndBuild();
@@ -549,11 +547,11 @@
     //   b : vec3<f32>;
     // };
     // struct Data {
-    //   var c : array<Inner, 4>;
+    //   var c : array<Inner, 4u>;
     // };
     //
     // var<storage> data : Pre;
-    // data.c[2].b.xy
+    // data.c[2i].b.xy
 
     auto* inner = Structure("Inner", {
                                          Member("a", ty.vec3<f32>()),
@@ -561,13 +559,13 @@
                                      });
 
     SetupStorageBuffer({
-        Member("c", ty.array(ty.Of(inner), 4, 32)),
+        Member("c", ty.array(ty.Of(inner), 4_u, 32)),
     });
 
     SetupFunction({
         Decl(Var("x", nullptr, ast::StorageClass::kNone,
-                 MemberAccessor(MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2), "b"),
-                                "xy"))),
+                 MemberAccessor(
+                     MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"), "xy"))),
     });
 
     GeneratorImpl& gen = SanitizeAndBuild();
@@ -608,11 +606,11 @@
     //   b : vec3<f32>;
     // };
     // struct Data {
-    //   var c : array<Inner, 4>;
+    //   var c : array<Inner, 4u>;
     // };
     //
     // var<storage> data : Pre;
-    // data.c[2].b.g
+    // data.c[2i].b.g
 
     auto* inner = Structure("Inner", {
                                          Member("a", ty.vec3<f32>()),
@@ -620,13 +618,13 @@
                                      });
 
     SetupStorageBuffer({
-        Member("c", ty.array(ty.Of(inner), 4, 32)),
+        Member("c", ty.array(ty.Of(inner), 4_u, 32)),
     });
 
     SetupFunction({
         Decl(Var("x", nullptr, ast::StorageClass::kNone,
-                 MemberAccessor(MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2), "b"),
-                                "g"))),
+                 MemberAccessor(
+                     MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"), "g"))),
     });
 
     GeneratorImpl& gen = SanitizeAndBuild();
@@ -666,11 +664,11 @@
     //   b : vec3<f32>;
     // };
     // struct Data {
-    //   var c : array<Inner, 4>;
+    //   var c : array<Inner, 4u>;
     // };
     //
     // var<storage> data : Pre;
-    // data.c[2].b[1]
+    // data.c[2i].b[1i]
 
     auto* inner = Structure("Inner", {
                                          Member("a", ty.vec3<f32>()),
@@ -678,13 +676,13 @@
                                      });
 
     SetupStorageBuffer({
-        Member("c", ty.array(ty.Of(inner), 4, 32)),
+        Member("c", ty.array(ty.Of(inner), 4_u, 32)),
     });
 
     SetupFunction({
-        Decl(Var(
-            "x", nullptr, ast::StorageClass::kNone,
-            IndexAccessor(MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2), "b"), 1))),
+        Decl(Var("x", nullptr, ast::StorageClass::kNone,
+                 IndexAccessor(MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"),
+                               1_i))),
     });
 
     GeneratorImpl& gen = SanitizeAndBuild();
@@ -724,11 +722,11 @@
     //   b : vec3<f32>;
     // };
     // struct Data {
-    //   var c : array<Inner, 4>;
+    //   var c : array<Inner, 4u>;
     // };
     //
     // var<storage> data : Pre;
-    // data.c[2].b = vec3<f32>(1.f, 2.f, 3.f);
+    // data.c[2i].b = vec3<f32>(1.f, 2.f, 3.f);
 
     auto* inner = Structure("Inner", {
                                          Member("a", ty.vec3<f32>()),
@@ -736,11 +734,11 @@
                                      });
 
     SetupStorageBuffer({
-        Member("c", ty.array(ty.Of(inner), 4, 32)),
+        Member("c", ty.array(ty.Of(inner), 4_u, 32)),
     });
 
     SetupFunction({
-        Assign(MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2), "b"),
+        Assign(MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"),
                vec3<f32>(1.f, 2.f, 3.f)),
     });
 
@@ -781,11 +779,11 @@
     //   b : vec3<f32>;
     // };
     // struct Data {
-    //   var c : array<Inner, 4>;
+    //   var c : array<Inner, 4u>;
     // };
     //
     // var<storage> data : Pre;
-    // data.c[2].b.y = 1.f;
+    // data.c[2i].b.y = 1.f;
 
     auto* inner = Structure("Inner", {
                                          Member("a", ty.vec3<i32>()),
@@ -793,13 +791,13 @@
                                      });
 
     SetupStorageBuffer({
-        Member("c", ty.array(ty.Of(inner), 4, 32)),
+        Member("c", ty.array(ty.Of(inner), 4_u, 32)),
     });
 
     SetupFunction({
-        Assign(
-            MemberAccessor(MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2), "b"), "y"),
-            Expr(1.f)),
+        Assign(MemberAccessor(MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"),
+                              "y"),
+               Expr(1.f)),
     });
 
     GeneratorImpl& gen = SanitizeAndBuild();
diff --git a/src/tint/writer/glsl/generator_impl_return_test.cc b/src/tint/writer/glsl/generator_impl_return_test.cc
index 3f950b2..59df385 100644
--- a/src/tint/writer/glsl/generator_impl_return_test.cc
+++ b/src/tint/writer/glsl/generator_impl_return_test.cc
@@ -14,6 +14,8 @@
 
 #include "src/tint/writer/glsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::glsl {
 namespace {
 
@@ -32,7 +34,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Return, Emit_ReturnWithValue) {
-    auto* r = Return(123);
+    auto* r = Return(123_i);
     Func("f", {}, ty.i32(), {r});
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/glsl/generator_impl_sanitizer_test.cc b/src/tint/writer/glsl/generator_impl_sanitizer_test.cc
index 30f33e9..874bfd0 100644
--- a/src/tint/writer/glsl/generator_impl_sanitizer_test.cc
+++ b/src/tint/writer/glsl/generator_impl_sanitizer_test.cc
@@ -17,6 +17,8 @@
 #include "src/tint/ast/variable_decl_statement.h"
 #include "src/tint/writer/glsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::glsl {
 namespace {
 
@@ -153,8 +155,8 @@
 }
 
 TEST_F(GlslSanitizerTest, PromoteArrayInitializerToConstVar) {
-    auto* array_init = array<i32, 4>(1, 2, 3, 4);
-    auto* array_index = IndexAccessor(array_init, 3);
+    auto* array_init = array<i32, 4>(1_i, 2_i, 3_i, 4_i);
+    auto* array_index = IndexAccessor(array_init, 3_i);
     auto* pos = Var("pos", ty.i32(), ast::StorageClass::kNone, array_index);
 
     Func("main", ast::VariableList{}, ty.void_(),
@@ -192,7 +194,7 @@
                                    Member("b", ty.vec3<f32>()),
                                    Member("c", ty.i32()),
                                });
-    auto* struct_init = Construct(ty.Of(str), 1, vec3<f32>(2.f, 3.f, 4.f), 4);
+    auto* struct_init = Construct(ty.Of(str), 1_i, vec3<f32>(2.f, 3.f, 4.f), 4_i);
     auto* struct_access = MemberAccessor(struct_init, "b");
     auto* pos = Var("pos", ty.vec3<f32>(), ast::StorageClass::kNone, struct_access);
 
@@ -271,18 +273,18 @@
 }
 
 TEST_F(GlslSanitizerTest, InlinePtrLetsComplexChain) {
-    // var a : array<mat4x4<f32>, 4>;
-    // let ap : ptr<function, array<mat4x4<f32>, 4>> = &a;
-    // let mp : ptr<function, mat4x4<f32>> = &(*ap)[3];
-    // let vp : ptr<function, vec4<f32>> = &(*mp)[2];
+    // var a : array<mat4x4<f32>, 4u>;
+    // let ap : ptr<function, array<mat4x4<f32>, 4u>> = &a;
+    // let mp : ptr<function, mat4x4<f32>> = &(*ap)[3i];
+    // let vp : ptr<function, vec4<f32>> = &(*mp)[2i];
     // let v : vec4<f32> = *vp;
-    auto* a = Var("a", ty.array(ty.mat4x4<f32>(), 4));
-    auto* ap = Let("ap", ty.pointer(ty.array(ty.mat4x4<f32>(), 4), ast::StorageClass::kFunction),
+    auto* a = Var("a", ty.array(ty.mat4x4<f32>(), 4_u));
+    auto* ap = Let("ap", ty.pointer(ty.array(ty.mat4x4<f32>(), 4_u), ast::StorageClass::kFunction),
                    AddressOf(a));
     auto* mp = Let("mp", ty.pointer(ty.mat4x4<f32>(), ast::StorageClass::kFunction),
-                   AddressOf(IndexAccessor(Deref(ap), 3)));
+                   AddressOf(IndexAccessor(Deref(ap), 3_i)));
     auto* vp = Let("vp", ty.pointer(ty.vec4<f32>(), ast::StorageClass::kFunction),
-                   AddressOf(IndexAccessor(Deref(mp), 2)));
+                   AddressOf(IndexAccessor(Deref(mp), 2_i)));
     auto* v = Var("v", ty.vec4<f32>(), ast::StorageClass::kNone, Deref(vp));
 
     Func("main", ast::VariableList{}, ty.void_(),
diff --git a/src/tint/writer/glsl/generator_impl_switch_test.cc b/src/tint/writer/glsl/generator_impl_switch_test.cc
index 7016b1a..1cc42fb 100644
--- a/src/tint/writer/glsl/generator_impl_switch_test.cc
+++ b/src/tint/writer/glsl/generator_impl_switch_test.cc
@@ -14,6 +14,8 @@
 
 #include "src/tint/writer/glsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::glsl {
 namespace {
 
@@ -26,7 +28,7 @@
     auto* def = create<ast::CaseStatement>(ast::CaseSelectorList{}, def_body);
 
     ast::CaseSelectorList case_val;
-    case_val.push_back(Expr(5));
+    case_val.push_back(Expr(5_i));
 
     auto* case_body = Block(create<ast::BreakStatement>());
 
diff --git a/src/tint/writer/glsl/generator_impl_type_test.cc b/src/tint/writer/glsl/generator_impl_type_test.cc
index a711597..b7daee2 100644
--- a/src/tint/writer/glsl/generator_impl_type_test.cc
+++ b/src/tint/writer/glsl/generator_impl_type_test.cc
@@ -22,11 +22,13 @@
 #include "src/tint/sem/storage_texture.h"
 #include "src/tint/writer/glsl/test_helper.h"
 
+using ::testing::HasSubstr;
+
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::glsl {
 namespace {
 
-using ::testing::HasSubstr;
-
 using GlslGeneratorImplTest_Type = TestHelper;
 
 TEST_F(GlslGeneratorImplTest_Type, EmitType_Array) {
@@ -43,7 +45,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Type, EmitType_ArrayOfArray) {
-    auto* arr = ty.array(ty.array<bool, 4>(), 5);
+    auto* arr = ty.array(ty.array<bool, 4>(), 5_u);
     Global("G", arr, ast::StorageClass::kPrivate);
 
     GeneratorImpl& gen = Build();
@@ -56,7 +58,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Type, EmitType_ArrayOfArrayOfArray) {
-    auto* arr = ty.array(ty.array(ty.array<bool, 4>(), 5), 6);
+    auto* arr = ty.array(ty.array(ty.array<bool, 4>(), 5_u), 6_u);
     Global("G", arr, ast::StorageClass::kPrivate);
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/glsl/generator_impl_workgroup_var_test.cc b/src/tint/writer/glsl/generator_impl_workgroup_var_test.cc
index b13aed3..a61cb17 100644
--- a/src/tint/writer/glsl/generator_impl_workgroup_var_test.cc
+++ b/src/tint/writer/glsl/generator_impl_workgroup_var_test.cc
@@ -17,9 +17,12 @@
 #include "src/tint/ast/stage_attribute.h"
 #include "src/tint/writer/glsl/test_helper.h"
 
+using ::testing::HasSubstr;
+
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::glsl {
 namespace {
-using ::testing::HasSubstr;
 
 using GlslGeneratorImplTest_WorkgroupVar = TestHelper;
 
@@ -29,7 +32,7 @@
     Func("main", {}, ty.void_(), {Assign("wg", 1.2f)},
          {
              Stage(ast::PipelineStage::kCompute),
-             WorkgroupSize(1),
+             WorkgroupSize(1_i),
          });
     GeneratorImpl& gen = Build();
 
@@ -45,7 +48,7 @@
     Func("main", {}, ty.void_(), {Assign("wg", 1.2f)},
          {
              Stage(ast::PipelineStage::kCompute),
-             WorkgroupSize(1),
+             WorkgroupSize(1_i),
          });
     GeneratorImpl& gen = Build();
 
diff --git a/src/tint/writer/hlsl/generator_impl.cc b/src/tint/writer/hlsl/generator_impl.cc
index d66b6bc..a64630b 100644
--- a/src/tint/writer/hlsl/generator_impl.cc
+++ b/src/tint/writer/hlsl/generator_impl.cc
@@ -73,6 +73,8 @@
 #include "src/tint/writer/float_to_string.h"
 #include "src/tint/writer/generate_external_texture_bindings.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::hlsl {
 namespace {
 
@@ -656,9 +658,9 @@
                 }
                 if (!val.WithScalarAt(i, [&](auto&& s) -> bool {
                         // Use std::equal_to to work around -Wfloat-equal warnings
-                        auto equals_to = std::equal_to<std::remove_reference_t<decltype(s)>>{};
-
-                        bool is_zero = equals_to(s, 0);
+                        using T = std::remove_reference_t<decltype(s)>;
+                        auto equal_to = std::equal_to<T>{};
+                        bool is_zero = equal_to(s, T(0));
                         return EmitValue(out, elem_ty, is_zero ? 1 : static_cast<int>(s));
                     })) {
                     return false;
@@ -2329,7 +2331,7 @@
 
     auto emit_vector_appended_with_i32_zero = [&](const ast::Expression* vector) {
         auto* i32 = builder_.create<sem::I32>();
-        auto* zero = builder_.Expr(0);
+        auto* zero = builder_.Expr(0_i);
         auto* stmt = builder_.Sem().Get(vector)->Stmt();
         builder_.Sem().Add(zero, builder_.create<sem::Expression>(zero, i32, stmt, sem::Constant{},
                                                                   /* has_side_effects */ false));
diff --git a/src/tint/writer/hlsl/generator_impl_array_accessor_test.cc b/src/tint/writer/hlsl/generator_impl_array_accessor_test.cc
index 42c8236..bbdeb10 100644
--- a/src/tint/writer/hlsl/generator_impl_array_accessor_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_array_accessor_test.cc
@@ -14,6 +14,8 @@
 
 #include "src/tint/writer/hlsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::hlsl {
 namespace {
 
@@ -21,7 +23,7 @@
 
 TEST_F(HlslGeneratorImplTest_Expression, IndexAccessor) {
     Global("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
-    auto* expr = IndexAccessor("ary", 5);
+    auto* expr = IndexAccessor("ary", 5_i);
     WrapInFunction(expr);
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/hlsl/generator_impl_assign_test.cc b/src/tint/writer/hlsl/generator_impl_assign_test.cc
index 6cb6423..5e5f031 100644
--- a/src/tint/writer/hlsl/generator_impl_assign_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_assign_test.cc
@@ -14,6 +14,8 @@
 
 #include "src/tint/writer/hlsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::hlsl {
 namespace {
 
@@ -44,7 +46,7 @@
          {
              Decl(Var("lhs", ty.vec3<f32>())),
              Decl(Var("rhs", ty.f32())),
-             Decl(Let("index", ty.u32(), Expr(0u))),
+             Decl(Let("index", ty.u32(), Expr(0_u))),
              Assign(IndexAccessor("lhs", "index"), "rhs"),
          });
 
@@ -92,7 +94,7 @@
          {
              Decl(Var("lhs", ty.mat4x2<f32>())),
              Decl(Var("rhs", ty.vec2<f32>())),
-             Decl(Let("index", ty.u32(), Expr(0u))),
+             Decl(Let("index", ty.u32(), Expr(0_u))),
              Assign(IndexAccessor("lhs", "index"), "rhs"),
          });
 
@@ -145,7 +147,7 @@
          {
              Decl(Var("lhs", ty.mat4x2<f32>())),
              Decl(Var("rhs", ty.f32())),
-             Decl(Let("index", ty.u32(), Expr(0u))),
+             Decl(Let("index", ty.u32(), Expr(0_u))),
              Assign(IndexAccessor(IndexAccessor("lhs", "index"), "index"), "rhs"),
          });
 
diff --git a/src/tint/writer/hlsl/generator_impl_binary_test.cc b/src/tint/writer/hlsl/generator_impl_binary_test.cc
index 6299e84..4d62885 100644
--- a/src/tint/writer/hlsl/generator_impl_binary_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_binary_test.cc
@@ -16,6 +16,8 @@
 #include "src/tint/ast/variable_decl_statement.h"
 #include "src/tint/writer/hlsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::hlsl {
 namespace {
 
@@ -319,11 +321,11 @@
 
 TEST_F(HlslGeneratorImplTest_Binary, If_WithLogical) {
     // if (a && b) {
-    //   return 1;
+    //   return 1i;
     // } else if (b || c) {
-    //   return 2;
+    //   return 2i;
     // } else {
-    //   return 3;
+    //   return 3i;
     // }
 
     Global("a", ty.bool_(), ast::StorageClass::kPrivate);
@@ -332,9 +334,9 @@
 
     auto* expr =
         If(create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b")),
-           Block(Return(1)),
+           Block(Return(1_i)),
            Else(If(create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, Expr("b"), Expr("c")),
-                   Block(Return(2)), Else(Block(Return(3))))));
+                   Block(Return(2_i)), Else(Block(Return(3_i))))));
     Func("func", {}, ty.i32(), {WrapInStatement(expr)});
 
     GeneratorImpl& gen = Build();
@@ -531,7 +533,7 @@
     Func("fn", {}, ty.void_(),
          {
              Decl(Var("a", ty.i32())),
-             Decl(Let("r", nullptr, Op("a", 0))),
+             Decl(Let("r", nullptr, Op("a", 0_i))),
          });
 
     GeneratorImpl& gen = Build();
@@ -549,7 +551,7 @@
     Func("fn", {}, ty.void_(),
          {
              Decl(Var("a", ty.u32())),
-             Decl(Let("r", nullptr, Op("a", 0u))),
+             Decl(Let("r", nullptr, Op("a", 0_u))),
          });
 
     GeneratorImpl& gen = Build();
@@ -566,8 +568,8 @@
 TEST_P(HlslGeneratorDivModTest, DivOrModByLiteralZero_vec_by_vec_i32) {
     Func("fn", {}, ty.void_(),
          {
-             Decl(Var("a", nullptr, vec4<i32>(100, 100, 100, 100))),
-             Decl(Let("r", nullptr, Op("a", vec4<i32>(50, 0, 25, 0)))),
+             Decl(Var("a", nullptr, vec4<i32>(100_i, 100_i, 100_i, 100_i))),
+             Decl(Let("r", nullptr, Op("a", vec4<i32>(50_i, 0_i, 25_i, 0_i)))),
          });
 
     GeneratorImpl& gen = Build();
@@ -584,8 +586,8 @@
 TEST_P(HlslGeneratorDivModTest, DivOrModByLiteralZero_vec_by_scalar_i32) {
     Func("fn", {}, ty.void_(),
          {
-             Decl(Var("a", nullptr, vec4<i32>(100, 100, 100, 100))),
-             Decl(Let("r", nullptr, Op("a", 0))),
+             Decl(Var("a", nullptr, vec4<i32>(100_i, 100_i, 100_i, 100_i))),
+             Decl(Let("r", nullptr, Op("a", 0_i))),
          });
 
     GeneratorImpl& gen = Build();
@@ -674,7 +676,7 @@
 TEST_P(HlslGeneratorDivModTest, DivOrModByExpression_i32) {
     Func("zero", {}, ty.i32(),
          {
-             Return(Expr(0)),
+             Return(Expr(0_i)),
          });
 
     Func("fn", {}, ty.void_(),
@@ -705,7 +707,7 @@
 TEST_P(HlslGeneratorDivModTest, DivOrModByExpression_u32) {
     Func("zero", {}, ty.u32(),
          {
-             Return(Expr(0u)),
+             Return(Expr(0_u)),
          });
 
     Func("fn", {}, ty.void_(),
@@ -736,7 +738,7 @@
 TEST_P(HlslGeneratorDivModTest, DivOrModByExpression_vec_by_vec_i32) {
     Func("zero", {}, ty.vec3<i32>(),
          {
-             Return(vec3<i32>(0, 0, 0)),
+             Return(vec3<i32>(0_i, 0_i, 0_i)),
          });
 
     Func("fn", {}, ty.void_(),
@@ -767,7 +769,7 @@
 TEST_P(HlslGeneratorDivModTest, DivOrModByExpression_vec_by_scalar_i32) {
     Func("zero", {}, ty.i32(),
          {
-             Return(0),
+             Return(0_i),
          });
 
     Func("fn", {}, ty.void_(),
diff --git a/src/tint/writer/hlsl/generator_impl_bitcast_test.cc b/src/tint/writer/hlsl/generator_impl_bitcast_test.cc
index 253d580..8305d64 100644
--- a/src/tint/writer/hlsl/generator_impl_bitcast_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_bitcast_test.cc
@@ -14,13 +14,15 @@
 
 #include "src/tint/writer/hlsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::hlsl {
 namespace {
 
 using HlslGeneratorImplTest_Bitcast = TestHelper;
 
 TEST_F(HlslGeneratorImplTest_Bitcast, EmitExpression_Bitcast_Float) {
-    auto* bitcast = create<ast::BitcastExpression>(ty.f32(), Expr(1));
+    auto* bitcast = create<ast::BitcastExpression>(ty.f32(), Expr(1_i));
     WrapInFunction(bitcast);
 
     GeneratorImpl& gen = Build();
@@ -31,7 +33,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Bitcast, EmitExpression_Bitcast_Int) {
-    auto* bitcast = create<ast::BitcastExpression>(ty.i32(), Expr(1u));
+    auto* bitcast = create<ast::BitcastExpression>(ty.i32(), Expr(1_u));
     WrapInFunction(bitcast);
 
     GeneratorImpl& gen = Build();
@@ -42,7 +44,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Bitcast, EmitExpression_Bitcast_Uint) {
-    auto* bitcast = create<ast::BitcastExpression>(ty.u32(), Expr(1));
+    auto* bitcast = create<ast::BitcastExpression>(ty.u32(), Expr(1_i));
     WrapInFunction(bitcast);
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/hlsl/generator_impl_builtin_test.cc b/src/tint/writer/hlsl/generator_impl_builtin_test.cc
index e7f1f55..ada17f1 100644
--- a/src/tint/writer/hlsl/generator_impl_builtin_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_builtin_test.cc
@@ -18,13 +18,14 @@
 #include "src/tint/sem/call.h"
 #include "src/tint/writer/hlsl/test_helper.h"
 
+using ::testing::HasSubstr;
+
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::hlsl {
 namespace {
 
 using BuiltinType = sem::BuiltinType;
-
-using ::testing::HasSubstr;
-
 using HlslGeneratorImplTest_Builtin = TestHelper;
 
 enum class ParamType {
@@ -267,7 +268,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Builtin, Select_Vector) {
-    auto* call = Call("select", vec2<i32>(1, 2), vec2<i32>(3, 4), vec2<bool>(true, false));
+    auto* call = Call("select", vec2<i32>(1_i, 2_i), vec2<i32>(3_i, 4_i), vec2<bool>(true, false));
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -693,7 +694,7 @@
     Func("main", {}, ty.void_(), {CallStmt(Call("storageBarrier"))},
          {
              Stage(ast::PipelineStage::kCompute),
-             WorkgroupSize(1),
+             WorkgroupSize(1_i),
          });
 
     GeneratorImpl& gen = Build();
@@ -711,7 +712,7 @@
     Func("main", {}, ty.void_(), {CallStmt(Call("workgroupBarrier"))},
          {
              Stage(ast::PipelineStage::kCompute),
-             WorkgroupSize(1),
+             WorkgroupSize(1_i),
          });
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/hlsl/generator_impl_case_test.cc b/src/tint/writer/hlsl/generator_impl_case_test.cc
index 2cedd99..ee3acfc 100644
--- a/src/tint/writer/hlsl/generator_impl_case_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_case_test.cc
@@ -15,13 +15,15 @@
 #include "src/tint/ast/fallthrough_statement.h"
 #include "src/tint/writer/hlsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::hlsl {
 namespace {
 
 using HlslGeneratorImplTest_Case = TestHelper;
 
 TEST_F(HlslGeneratorImplTest_Case, Emit_Case) {
-    auto* s = Switch(1, Case(Expr(5), Block(create<ast::BreakStatement>())), DefaultCase());
+    auto* s = Switch(1_i, Case(Expr(5_i), Block(create<ast::BreakStatement>())), DefaultCase());
     WrapInFunction(s);
 
     GeneratorImpl& gen = Build();
@@ -36,7 +38,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Case, Emit_Case_BreaksByDefault) {
-    auto* s = Switch(1, Case(Expr(5), Block()), DefaultCase());
+    auto* s = Switch(1_i, Case(Expr(5_i), Block()), DefaultCase());
     WrapInFunction(s);
 
     GeneratorImpl& gen = Build();
@@ -51,9 +53,9 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Case, Emit_Case_WithFallthrough) {
-    auto* s = Switch(1,                                                          //
-                     Case(Expr(4), Block(create<ast::FallthroughStatement>())),  //
-                     Case(Expr(5), Block(create<ast::ReturnStatement>())),       //
+    auto* s = Switch(1_i,                                                          //
+                     Case(Expr(4_i), Block(create<ast::FallthroughStatement>())),  //
+                     Case(Expr(5_i), Block(create<ast::ReturnStatement>())),       //
                      DefaultCase());
     WrapInFunction(s);
 
@@ -73,8 +75,8 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Case, Emit_Case_MultipleSelectors) {
-    auto* s =
-        Switch(1, Case({Expr(5), Expr(6)}, Block(create<ast::BreakStatement>())), DefaultCase());
+    auto* s = Switch(1_i, Case({Expr(5_i), Expr(6_i)}, Block(create<ast::BreakStatement>())),
+                     DefaultCase());
     WrapInFunction(s);
 
     GeneratorImpl& gen = Build();
@@ -90,14 +92,14 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Case, Emit_Case_Default) {
-    auto* s = Switch(1, DefaultCase(Block(create<ast::BreakStatement>())));
+    auto* s = Switch(1_i, DefaultCase(Block(create<ast::BreakStatement>())));
     WrapInFunction(s);
 
     GeneratorImpl& gen = Build();
 
     gen.increment_indent();
 
-    ASSERT_TRUE(gen.EmitCase(s, 0)) << gen.error();
+    ASSERT_TRUE(gen.EmitCase(s, 0_i)) << gen.error();
     EXPECT_EQ(gen.result(), R"(  default: {
     break;
   }
diff --git a/src/tint/writer/hlsl/generator_impl_cast_test.cc b/src/tint/writer/hlsl/generator_impl_cast_test.cc
index 1460eff..458f07d 100644
--- a/src/tint/writer/hlsl/generator_impl_cast_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_cast_test.cc
@@ -14,13 +14,15 @@
 
 #include "src/tint/writer/hlsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::hlsl {
 namespace {
 
 using HlslGeneratorImplTest_Cast = TestHelper;
 
 TEST_F(HlslGeneratorImplTest_Cast, EmitExpression_Cast_Scalar) {
-    auto* cast = Construct<f32>(1);
+    auto* cast = Construct<f32>(1_i);
     WrapInFunction(cast);
 
     GeneratorImpl& gen = Build();
@@ -31,7 +33,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Cast, EmitExpression_Cast_Vector) {
-    auto* cast = vec3<f32>(vec3<i32>(1, 2, 3));
+    auto* cast = vec3<f32>(vec3<i32>(1_i, 2_i, 3_i));
     WrapInFunction(cast);
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/hlsl/generator_impl_constructor_test.cc b/src/tint/writer/hlsl/generator_impl_constructor_test.cc
index 5bea0ab..5916b0a 100644
--- a/src/tint/writer/hlsl/generator_impl_constructor_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_constructor_test.cc
@@ -15,6 +15,8 @@
 #include "gmock/gmock.h"
 #include "src/tint/writer/hlsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::hlsl {
 namespace {
 
@@ -32,7 +34,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Int) {
-    WrapInFunction(Expr(-12345));
+    WrapInFunction(Expr(i32(-12345)));
 
     GeneratorImpl& gen = Build();
 
@@ -41,7 +43,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_UInt) {
-    WrapInFunction(Expr(56779u));
+    WrapInFunction(Expr(56779_u));
 
     GeneratorImpl& gen = Build();
 
@@ -51,7 +53,7 @@
 
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Float) {
     // Use a number close to 1<<30 but whose decimal representation ends in 0.
-    WrapInFunction(Expr(static_cast<float>((1 << 30) - 4)));
+    WrapInFunction(Expr(f32((1 << 30) - 4)));
 
     GeneratorImpl& gen = Build();
 
@@ -78,7 +80,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Int) {
-    WrapInFunction(Construct<i32>(-12345));
+    WrapInFunction(Construct<i32>(i32(-12345)));
 
     GeneratorImpl& gen = Build();
 
@@ -87,7 +89,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Uint) {
-    WrapInFunction(Construct<u32>(12345u));
+    WrapInFunction(Construct<u32>(12345_u));
 
     GeneratorImpl& gen = Build();
 
@@ -156,7 +158,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Vec_SingleScalar_Int) {
-    WrapInFunction(vec3<i32>(2));
+    WrapInFunction(vec3<i32>(2_i));
 
     GeneratorImpl& gen = Build();
 
@@ -165,7 +167,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Vec_SingleScalar_UInt) {
-    WrapInFunction(vec3<u32>(2u));
+    WrapInFunction(vec3<u32>(2_u));
 
     GeneratorImpl& gen = Build();
 
@@ -195,7 +197,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Array) {
-    WrapInFunction(Construct(ty.array(ty.vec3<f32>(), 3), vec3<f32>(1.f, 2.f, 3.f),
+    WrapInFunction(Construct(ty.array(ty.vec3<f32>(), 3_u), vec3<f32>(1.f, 2.f, 3.f),
                              vec3<f32>(4.f, 5.f, 6.f), vec3<f32>(7.f, 8.f, 9.f)));
 
     GeneratorImpl& gen = Build();
@@ -206,7 +208,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Array_Empty) {
-    WrapInFunction(Construct(ty.array(ty.vec3<f32>(), 3)));
+    WrapInFunction(Construct(ty.array(ty.vec3<f32>(), 3_u)));
 
     GeneratorImpl& gen = Build();
 
@@ -221,7 +223,7 @@
                                    Member("c", ty.vec3<i32>()),
                                });
 
-    WrapInFunction(Construct(ty.Of(str), 1, 2.0f, vec3<i32>(3, 4, 5)));
+    WrapInFunction(Construct(ty.Of(str), 1_i, 2.0f, vec3<i32>(3_i, 4_i, 5_i)));
 
     GeneratorImpl& gen = SanitizeAndBuild();
 
diff --git a/src/tint/writer/hlsl/generator_impl_function_test.cc b/src/tint/writer/hlsl/generator_impl_function_test.cc
index 69d8f4f..0525fa6 100644
--- a/src/tint/writer/hlsl/generator_impl_function_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_function_test.cc
@@ -20,6 +20,8 @@
 
 using ::testing::HasSubstr;
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::hlsl {
 namespace {
 
@@ -645,7 +647,7 @@
          {
              Return(),
          },
-         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     GeneratorImpl& gen = Build();
 
@@ -661,7 +663,7 @@
     Func("main", ast::VariableList{}, ty.void_(), {},
          {
              Stage(ast::PipelineStage::kCompute),
-             WorkgroupSize(2, 4, 6),
+             WorkgroupSize(2_i, 4_i, 6_i),
          });
 
     GeneratorImpl& gen = Build();
@@ -675,9 +677,9 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_Compute_WithWorkgroup_Const) {
-    GlobalConst("width", ty.i32(), Construct(ty.i32(), 2));
-    GlobalConst("height", ty.i32(), Construct(ty.i32(), 3));
-    GlobalConst("depth", ty.i32(), Construct(ty.i32(), 4));
+    GlobalConst("width", ty.i32(), Construct(ty.i32(), 2_i));
+    GlobalConst("height", ty.i32(), Construct(ty.i32(), 3_i));
+    GlobalConst("depth", ty.i32(), Construct(ty.i32(), 4_i));
     Func("main", ast::VariableList{}, ty.void_(), {},
          {
              Stage(ast::PipelineStage::kCompute),
@@ -700,9 +702,9 @@
 
 TEST_F(HlslGeneratorImplTest_Function,
        Emit_Attribute_EntryPoint_Compute_WithWorkgroup_OverridableConst) {
-    Override("width", ty.i32(), Construct(ty.i32(), 2), {Id(7u)});
-    Override("height", ty.i32(), Construct(ty.i32(), 3), {Id(8u)});
-    Override("depth", ty.i32(), Construct(ty.i32(), 4), {Id(9u)});
+    Override("width", ty.i32(), Construct(ty.i32(), 2_i), {Id(7u)});
+    Override("height", ty.i32(), Construct(ty.i32(), 3_i), {Id(8u)});
+    Override("depth", ty.i32(), Construct(ty.i32(), 4_i), {Id(9u)});
     Func("main", ast::VariableList{}, ty.void_(), {},
          {
              Stage(ast::PipelineStage::kCompute),
@@ -766,7 +768,7 @@
 TEST_F(HlslGeneratorImplTest_Function, Emit_Function_WithDiscardAndVoidReturn) {
     Func("my_func", {Param("a", ty.i32())}, ty.void_(),
          {
-             If(Equal("a", 0),  //
+             If(Equal("a", 0_i),  //
                 Block(create<ast::DiscardStatement>())),
              Return(),
          });
@@ -786,9 +788,9 @@
 TEST_F(HlslGeneratorImplTest_Function, Emit_Function_WithDiscardAndNonVoidReturn) {
     Func("my_func", {Param("a", ty.i32())}, ty.i32(),
          {
-             If(Equal("a", 0),  //
+             If(Equal("a", 0_i),  //
                 Block(create<ast::DiscardStatement>())),
-             Return(42),
+             Return(42_i),
          });
 
     GeneratorImpl& gen = Build();
@@ -842,7 +844,7 @@
                  Decl(var),
                  Return(),
              },
-             {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+             {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
     }
 
     {
@@ -853,7 +855,7 @@
                  Decl(var),
                  Return(),
              },
-             {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+             {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
     }
 
     GeneratorImpl& gen = SanitizeAndBuild();
diff --git a/src/tint/writer/hlsl/generator_impl_import_test.cc b/src/tint/writer/hlsl/generator_impl_import_test.cc
index 9cfafb1..73e3161 100644
--- a/src/tint/writer/hlsl/generator_impl_import_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_import_test.cc
@@ -14,6 +14,8 @@
 
 #include "src/tint/writer/hlsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::hlsl {
 namespace {
 
@@ -72,7 +74,7 @@
 TEST_P(HlslImportData_SingleIntParamTest, IntScalar) {
     auto param = GetParam();
 
-    auto* expr = Call(param.name, Expr(1));
+    auto* expr = Call(param.name, Expr(1_i));
     WrapInFunction(expr);
 
     GeneratorImpl& gen = Build();
@@ -177,7 +179,7 @@
 TEST_P(HlslImportData_DualParam_Int_Test, IntScalar) {
     auto param = GetParam();
 
-    auto* expr = Call(param.name, 1, 2);
+    auto* expr = Call(param.name, 1_i, 2_i);
     WrapInFunction(expr);
 
     GeneratorImpl& gen = Build();
@@ -243,7 +245,7 @@
 TEST_P(HlslImportData_TripleParam_Int_Test, IntScalar) {
     auto param = GetParam();
 
-    auto* expr = Call(param.name, 1, 2, 3);
+    auto* expr = Call(param.name, 1_i, 2_i, 3_i);
     WrapInFunction(expr);
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/hlsl/generator_impl_loop_test.cc b/src/tint/writer/hlsl/generator_impl_loop_test.cc
index 57cbd39..0bd1f75 100644
--- a/src/tint/writer/hlsl/generator_impl_loop_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_loop_test.cc
@@ -15,6 +15,8 @@
 #include "src/tint/ast/variable_decl_statement.h"
 #include "src/tint/writer/hlsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::hlsl {
 namespace {
 
@@ -256,12 +258,12 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Loop, Emit_ForLoopWithSimpleCont) {
-    // for(; ; i = i + 1) {
+    // for(; ; i = i + 1i) {
     //   return;
     // }
 
     auto* v = Decl(Var("i", ty.i32()));
-    auto* f = For(nullptr, nullptr, Assign("i", Add("i", 1)), Block(Return()));
+    auto* f = For(nullptr, nullptr, Assign("i", Add("i", 1_i)), Block(Return()));
     WrapInFunction(v, f);
 
     GeneratorImpl& gen = Build();
@@ -307,11 +309,11 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Loop, Emit_ForLoopWithSimpleInitCondCont) {
-    // for(var i : i32; true; i = i + 1) {
+    // for(var i : i32; true; i = i + 1i) {
     //   return;
     // }
 
-    auto* f = For(Decl(Var("i", ty.i32())), true, Assign("i", Add("i", 1)), Block(Return()));
+    auto* f = For(Decl(Var("i", ty.i32())), true, Assign("i", Add("i", 1_i)), Block(Return()));
     WrapInFunction(f);
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc b/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc
index b9f6fe4..ad1e973 100644
--- a/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc
@@ -16,11 +16,13 @@
 #include "src/tint/ast/stage_attribute.h"
 #include "src/tint/writer/hlsl/test_helper.h"
 
+using ::testing::HasSubstr;
+
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::hlsl {
 namespace {
 
-using ::testing::HasSubstr;
-
 using create_type_func_ptr = const ast::Type* (*)(const ProgramBuilder::TypesBuilder& ty);
 
 inline const ast::Type* ty_i32(const ProgramBuilder::TypesBuilder& ty) {
@@ -81,10 +83,6 @@
     return ty.mat4x4<T>();
 }
 
-using i32 = ProgramBuilder::i32;
-using u32 = ProgramBuilder::u32;
-using f32 = ProgramBuilder::f32;
-
 template <typename BASE>
 class HlslGeneratorImplTest_MemberAccessorBase : public BASE {
   public:
@@ -352,7 +350,7 @@
     //   a : mat4x3<f32>;
     // };
     // var<storage> data : Data;
-    // data.a[2][1];
+    // data.a[2i][1i];
 
     SetupStorageBuffer({
         Member("z", ty.f32()),
@@ -361,7 +359,7 @@
 
     SetupFunction({
         Decl(Var("x", nullptr, ast::StorageClass::kNone,
-                 IndexAccessor(IndexAccessor(MemberAccessor("data", "a"), 2), 1))),
+                 IndexAccessor(IndexAccessor(MemberAccessor("data", "a"), 2_i), 1_i))),
     });
 
     GeneratorImpl& gen = SanitizeAndBuild();
@@ -393,7 +391,7 @@
 
     SetupFunction({
         Decl(Var("x", nullptr, ast::StorageClass::kNone,
-                 IndexAccessor(MemberAccessor("data", "a"), 2))),
+                 IndexAccessor(MemberAccessor("data", "a"), 2_i))),
     });
 
     GeneratorImpl& gen = SanitizeAndBuild();
@@ -416,7 +414,7 @@
     //   a : array<i32, 5>;
     // };
     // var<storage> data : Data;
-    // data.a[(2 + 4) - 3];
+    // data.a[(2i + 4i) - 3i];
 
     SetupStorageBuffer({
         Member("z", ty.f32()),
@@ -425,7 +423,7 @@
 
     SetupFunction({
         Decl(Var("x", nullptr, ast::StorageClass::kNone,
-                 IndexAccessor(MemberAccessor("data", "a"), Sub(Add(2, Expr(4)), Expr(3))))),
+                 IndexAccessor(MemberAccessor("data", "a"), Sub(Add(2_i, Expr(4_i)), Expr(3_i))))),
     });
 
     GeneratorImpl& gen = SanitizeAndBuild();
@@ -455,7 +453,7 @@
     });
 
     SetupFunction({
-        Assign(IndexAccessor(MemberAccessor("data", "a"), 2), 2),
+        Assign(IndexAccessor(MemberAccessor("data", "a"), 2_i), 2_i),
     });
 
     GeneratorImpl& gen = SanitizeAndBuild();
@@ -478,7 +476,7 @@
     //   b : vec3<f32>;
     // };
     // struct Data {
-    //   var c : array<Inner, 4>;
+    //   var c : array<Inner, 4u>;
     // };
     //
     // var<storage> data : Pre;
@@ -490,12 +488,12 @@
                                      });
 
     SetupStorageBuffer({
-        Member("c", ty.array(ty.Of(inner), 4, 32)),
+        Member("c", ty.array(ty.Of(inner), 4_u, 32)),
     });
 
     SetupFunction({
         Decl(Var("x", nullptr, ast::StorageClass::kNone,
-                 MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2), "b"))),
+                 MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"))),
     });
 
     GeneratorImpl& gen = SanitizeAndBuild();
@@ -518,7 +516,7 @@
     //   b : vec3<f32>;
     // };
     // struct Data {
-    //   var c : array<Inner, 4>;
+    //   var c : array<Inner, 4u>;
     // };
     //
     // var<storage> data : Pre;
@@ -530,13 +528,13 @@
                                      });
 
     SetupStorageBuffer({
-        Member("c", ty.array(ty.Of(inner), 4, 32)),
+        Member("c", ty.array(ty.Of(inner), 4_u, 32)),
     });
 
     SetupFunction({
         Decl(Var("x", nullptr, ast::StorageClass::kNone,
-                 MemberAccessor(MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2), "b"),
-                                "xy"))),
+                 MemberAccessor(
+                     MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"), "xy"))),
     });
 
     GeneratorImpl& gen = SanitizeAndBuild();
@@ -560,7 +558,7 @@
     //   b : vec3<f32>;
     // };
     // struct Data {
-    //   var c : array<Inner, 4>;
+    //   var c : array<Inner, 4u>;
     // };
     //
     // var<storage> data : Pre;
@@ -572,13 +570,13 @@
                                      });
 
     SetupStorageBuffer({
-        Member("c", ty.array(ty.Of(inner), 4, 32)),
+        Member("c", ty.array(ty.Of(inner), 4_u, 32)),
     });
 
     SetupFunction({
         Decl(Var("x", nullptr, ast::StorageClass::kNone,
-                 MemberAccessor(MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2), "b"),
-                                "g"))),
+                 MemberAccessor(
+                     MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"), "g"))),
     });
 
     GeneratorImpl& gen = SanitizeAndBuild();
@@ -601,7 +599,7 @@
     //   b : vec3<f32>;
     // };
     // struct Data {
-    //   var c : array<Inner, 4>;
+    //   var c : array<Inner, 4u>;
     // };
     //
     // var<storage> data : Pre;
@@ -613,13 +611,13 @@
                                      });
 
     SetupStorageBuffer({
-        Member("c", ty.array(ty.Of(inner), 4, 32)),
+        Member("c", ty.array(ty.Of(inner), 4_u, 32)),
     });
 
     SetupFunction({
-        Decl(Var(
-            "x", nullptr, ast::StorageClass::kNone,
-            IndexAccessor(MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2), "b"), 1))),
+        Decl(Var("x", nullptr, ast::StorageClass::kNone,
+                 IndexAccessor(MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"),
+                               1_i))),
     });
 
     GeneratorImpl& gen = SanitizeAndBuild();
@@ -642,7 +640,7 @@
     //   b : vec3<f32>;
     // };
     // struct Data {
-    //   var c : array<Inner, 4>;
+    //   var c : array<Inner, 4u>;
     // };
     //
     // var<storage> data : Pre;
@@ -654,11 +652,11 @@
                                      });
 
     SetupStorageBuffer({
-        Member("c", ty.array(ty.Of(inner), 4, 32)),
+        Member("c", ty.array(ty.Of(inner), 4_u, 32)),
     });
 
     SetupFunction({
-        Assign(MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2), "b"),
+        Assign(MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"),
                vec3<f32>(1.f, 2.f, 3.f)),
     });
 
@@ -682,7 +680,7 @@
     //   b : vec3<f32>;
     // };
     // struct Data {
-    //   var c : array<Inner, 4>;
+    //   var c : array<Inner, 4u>;
     // };
     //
     // var<storage> data : Pre;
@@ -694,13 +692,13 @@
                                      });
 
     SetupStorageBuffer({
-        Member("c", ty.array(ty.Of(inner), 4, 32)),
+        Member("c", ty.array(ty.Of(inner), 4_u, 32)),
     });
 
     SetupFunction({
-        Assign(
-            MemberAccessor(MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2), "b"), "y"),
-            Expr(1.f)),
+        Assign(MemberAccessor(MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2_i), "b"),
+                              "y"),
+               Expr(1.f)),
     });
 
     GeneratorImpl& gen = SanitizeAndBuild();
diff --git a/src/tint/writer/hlsl/generator_impl_return_test.cc b/src/tint/writer/hlsl/generator_impl_return_test.cc
index 987c6e3..1813645 100644
--- a/src/tint/writer/hlsl/generator_impl_return_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_return_test.cc
@@ -14,6 +14,8 @@
 
 #include "src/tint/writer/hlsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::hlsl {
 namespace {
 
@@ -32,7 +34,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Return, Emit_ReturnWithValue) {
-    auto* r = Return(123);
+    auto* r = Return(123_i);
     Func("f", {}, ty.i32(), {r});
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/hlsl/generator_impl_sanitizer_test.cc b/src/tint/writer/hlsl/generator_impl_sanitizer_test.cc
index 34801fa..b68c950 100644
--- a/src/tint/writer/hlsl/generator_impl_sanitizer_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_sanitizer_test.cc
@@ -17,6 +17,8 @@
 #include "src/tint/ast/variable_decl_statement.h"
 #include "src/tint/writer/hlsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::hlsl {
 namespace {
 
@@ -185,8 +187,8 @@
 }
 
 TEST_F(HlslSanitizerTest, PromoteArrayInitializerToConstVar) {
-    auto* array_init = array<i32, 4>(1, 2, 3, 4);
-    auto* array_index = IndexAccessor(array_init, 3);
+    auto* array_init = array<i32, 4>(1_i, 2_i, 3_i, 4_i);
+    auto* array_index = IndexAccessor(array_init, 3_i);
     auto* pos = Var("pos", ty.i32(), ast::StorageClass::kNone, array_index);
 
     Func("main", ast::VariableList{}, ty.void_(),
@@ -217,7 +219,7 @@
                                    Member("b", ty.vec3<f32>()),
                                    Member("c", ty.i32()),
                                });
-    auto* struct_init = Construct(ty.Of(str), 1, vec3<f32>(2.f, 3.f, 4.f), 4);
+    auto* struct_init = Construct(ty.Of(str), 1_i, vec3<f32>(2.f, 3.f, 4.f), 4_i);
     auto* struct_access = MemberAccessor(struct_init, "b");
     auto* pos = Var("pos", ty.vec3<f32>(), ast::StorageClass::kNone, struct_access);
 
@@ -282,18 +284,18 @@
 }
 
 TEST_F(HlslSanitizerTest, InlinePtrLetsComplexChain) {
-    // var a : array<mat4x4<f32>, 4>;
-    // let ap : ptr<function, array<mat4x4<f32>, 4>> = &a;
-    // let mp : ptr<function, mat4x4<f32>> = &(*ap)[3];
-    // let vp : ptr<function, vec4<f32>> = &(*mp)[2];
+    // var a : array<mat4x4<f32>, 4u>;
+    // let ap : ptr<function, array<mat4x4<f32>, 4u>> = &a;
+    // let mp : ptr<function, mat4x4<f32>> = &(*ap)[3i];
+    // let vp : ptr<function, vec4<f32>> = &(*mp)[2i];
     // let v : vec4<f32> = *vp;
-    auto* a = Var("a", ty.array(ty.mat4x4<f32>(), 4));
-    auto* ap = Let("ap", ty.pointer(ty.array(ty.mat4x4<f32>(), 4), ast::StorageClass::kFunction),
+    auto* a = Var("a", ty.array(ty.mat4x4<f32>(), 4_u));
+    auto* ap = Let("ap", ty.pointer(ty.array(ty.mat4x4<f32>(), 4_u), ast::StorageClass::kFunction),
                    AddressOf(a));
     auto* mp = Let("mp", ty.pointer(ty.mat4x4<f32>(), ast::StorageClass::kFunction),
-                   AddressOf(IndexAccessor(Deref(ap), 3)));
+                   AddressOf(IndexAccessor(Deref(ap), 3_i)));
     auto* vp = Let("vp", ty.pointer(ty.vec4<f32>(), ast::StorageClass::kFunction),
-                   AddressOf(IndexAccessor(Deref(mp), 2)));
+                   AddressOf(IndexAccessor(Deref(mp), 2_i)));
     auto* v = Var("v", ty.vec4<f32>(), ast::StorageClass::kNone, Deref(vp));
 
     Func("main", ast::VariableList{}, ty.void_(),
diff --git a/src/tint/writer/hlsl/generator_impl_switch_test.cc b/src/tint/writer/hlsl/generator_impl_switch_test.cc
index cf92541..3ef1a7b 100644
--- a/src/tint/writer/hlsl/generator_impl_switch_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_switch_test.cc
@@ -14,6 +14,8 @@
 
 #include "src/tint/writer/hlsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::hlsl {
 namespace {
 
@@ -21,9 +23,9 @@
 
 TEST_F(HlslGeneratorImplTest_Switch, Emit_Switch) {
     Global("cond", ty.i32(), ast::StorageClass::kPrivate);
-    auto* s = Switch(                   //
-        Expr("cond"),                   //
-        Case(Expr(5), Block(Break())),  //
+    auto* s = Switch(                     //
+        Expr("cond"),                     //
+        Case(Expr(5_i), Block(Break())),  //
         DefaultCase());
     WrapInFunction(s);
 
@@ -48,7 +50,7 @@
     Global("a", ty.i32(), ast::StorageClass::kPrivate);
     auto* s = Switch(  //
         Expr("cond"),  //
-        DefaultCase(Block(Assign(Expr("a"), Expr(42)))));
+        DefaultCase(Block(Assign(Expr("a"), Expr(42_i)))));
     WrapInFunction(s);
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/hlsl/generator_impl_type_test.cc b/src/tint/writer/hlsl/generator_impl_type_test.cc
index 4a52f14..b99f06e 100644
--- a/src/tint/writer/hlsl/generator_impl_type_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_type_test.cc
@@ -22,11 +22,13 @@
 #include "src/tint/sem/storage_texture.h"
 #include "src/tint/writer/hlsl/test_helper.h"
 
+using ::testing::HasSubstr;
+
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::hlsl {
 namespace {
 
-using ::testing::HasSubstr;
-
 using HlslGeneratorImplTest_Type = TestHelper;
 
 TEST_F(HlslGeneratorImplTest_Type, EmitType_Array) {
@@ -43,7 +45,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Type, EmitType_ArrayOfArray) {
-    auto* arr = ty.array(ty.array<bool, 4>(), 5);
+    auto* arr = ty.array(ty.array<bool, 4>(), 5_u);
     Global("G", arr, ast::StorageClass::kPrivate);
 
     GeneratorImpl& gen = Build();
@@ -56,7 +58,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Type, EmitType_ArrayOfArrayOfArray) {
-    auto* arr = ty.array(ty.array(ty.array<bool, 4>(), 5), 6);
+    auto* arr = ty.array(ty.array(ty.array<bool, 4>(), 5_u), 6_u);
     Global("G", arr, ast::StorageClass::kPrivate);
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/hlsl/generator_impl_workgroup_var_test.cc b/src/tint/writer/hlsl/generator_impl_workgroup_var_test.cc
index 0330815..466c871 100644
--- a/src/tint/writer/hlsl/generator_impl_workgroup_var_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_workgroup_var_test.cc
@@ -17,9 +17,12 @@
 #include "src/tint/ast/stage_attribute.h"
 #include "src/tint/writer/hlsl/test_helper.h"
 
+using ::testing::HasSubstr;
+
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::hlsl {
 namespace {
-using ::testing::HasSubstr;
 
 using HlslGeneratorImplTest_WorkgroupVar = TestHelper;
 
@@ -29,7 +32,7 @@
     Func("main", {}, ty.void_(), {Assign("wg", 1.2f)},
          {
              Stage(ast::PipelineStage::kCompute),
-             WorkgroupSize(1),
+             WorkgroupSize(1_i),
          });
     GeneratorImpl& gen = Build();
 
@@ -45,7 +48,7 @@
     Func("main", {}, ty.void_(), {Assign("wg", 1.2f)},
          {
              Stage(ast::PipelineStage::kCompute),
-             WorkgroupSize(1),
+             WorkgroupSize(1_i),
          });
     GeneratorImpl& gen = Build();
 
diff --git a/src/tint/writer/msl/generator_impl_array_accessor_test.cc b/src/tint/writer/msl/generator_impl_array_accessor_test.cc
index 8463f44..7475b67 100644
--- a/src/tint/writer/msl/generator_impl_array_accessor_test.cc
+++ b/src/tint/writer/msl/generator_impl_array_accessor_test.cc
@@ -14,6 +14,8 @@
 
 #include "src/tint/writer/msl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::msl {
 namespace {
 
@@ -21,7 +23,7 @@
 
 TEST_F(MslGeneratorImplTest, IndexAccessor) {
     auto* ary = Var("ary", ty.array<i32, 10>());
-    auto* expr = IndexAccessor("ary", 5);
+    auto* expr = IndexAccessor("ary", 5_i);
     WrapInFunction(ary, expr);
 
     GeneratorImpl& gen = Build();
@@ -35,7 +37,7 @@
     Global("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
 
     auto* p = Let("p", nullptr, AddressOf("ary"));
-    auto* expr = IndexAccessor(Deref("p"), 5);
+    auto* expr = IndexAccessor(Deref("p"), 5_i);
     WrapInFunction(p, expr);
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/msl/generator_impl_bitcast_test.cc b/src/tint/writer/msl/generator_impl_bitcast_test.cc
index 73807e4..c398558 100644
--- a/src/tint/writer/msl/generator_impl_bitcast_test.cc
+++ b/src/tint/writer/msl/generator_impl_bitcast_test.cc
@@ -14,13 +14,15 @@
 
 #include "src/tint/writer/msl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::msl {
 namespace {
 
 using MslGeneratorImplTest = TestHelper;
 
 TEST_F(MslGeneratorImplTest, EmitExpression_Bitcast) {
-    auto* bitcast = create<ast::BitcastExpression>(ty.f32(), Expr(1));
+    auto* bitcast = create<ast::BitcastExpression>(ty.f32(), Expr(1_i));
     WrapInFunction(bitcast);
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/msl/generator_impl_builtin_test.cc b/src/tint/writer/msl/generator_impl_builtin_test.cc
index a4b6f0b..752fc73 100644
--- a/src/tint/writer/msl/generator_impl_builtin_test.cc
+++ b/src/tint/writer/msl/generator_impl_builtin_test.cc
@@ -16,6 +16,8 @@
 #include "src/tint/sem/call.h"
 #include "src/tint/writer/msl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::msl {
 namespace {
 
@@ -460,10 +462,10 @@
     Func("f", {Param("a", ty.i32()), Param("b", ty.i32()), Param("c", ty.i32())}, ty.i32(),
          {Return(Mul(Add("a", "b"), "c"))});
 
-    Func("func", {}, ty.void_(), {CallStmt(Call("f", 1, 2, 3))},
+    Func("func", {}, ty.void_(), {CallStmt(Call("f", 1_i, 2_i, 3_i))},
          {
              Stage(ast::PipelineStage::kCompute),
-             WorkgroupSize(1),
+             WorkgroupSize(1_i),
          });
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/msl/generator_impl_case_test.cc b/src/tint/writer/msl/generator_impl_case_test.cc
index e461797..8fc1bc9 100644
--- a/src/tint/writer/msl/generator_impl_case_test.cc
+++ b/src/tint/writer/msl/generator_impl_case_test.cc
@@ -15,13 +15,15 @@
 #include "src/tint/ast/fallthrough_statement.h"
 #include "src/tint/writer/msl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::msl {
 namespace {
 
 using MslGeneratorImplTest = TestHelper;
 
 TEST_F(MslGeneratorImplTest, Emit_Case) {
-    auto* s = Switch(1, Case(Expr(5), Block(create<ast::BreakStatement>())), DefaultCase());
+    auto* s = Switch(1_i, Case(Expr(5_i), Block(create<ast::BreakStatement>())), DefaultCase());
     WrapInFunction(s);
 
     GeneratorImpl& gen = Build();
@@ -36,7 +38,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_Case_BreaksByDefault) {
-    auto* s = Switch(1, Case(Expr(5), Block()), DefaultCase());
+    auto* s = Switch(1_i, Case(Expr(5_i), Block()), DefaultCase());
     WrapInFunction(s);
 
     GeneratorImpl& gen = Build();
@@ -51,7 +53,8 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_Case_WithFallthrough) {
-    auto* s = Switch(1, Case(Expr(5), Block(create<ast::FallthroughStatement>())), DefaultCase());
+    auto* s =
+        Switch(1_i, Case(Expr(5_i), Block(create<ast::FallthroughStatement>())), DefaultCase());
     WrapInFunction(s);
 
     GeneratorImpl& gen = Build();
@@ -66,8 +69,8 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_Case_MultipleSelectors) {
-    auto* s =
-        Switch(1, Case({Expr(5), Expr(6)}, Block(create<ast::BreakStatement>())), DefaultCase());
+    auto* s = Switch(1_i, Case({Expr(5_i), Expr(6_i)}, Block(create<ast::BreakStatement>())),
+                     DefaultCase());
     WrapInFunction(s);
 
     GeneratorImpl& gen = Build();
@@ -83,7 +86,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_Case_Default) {
-    auto* s = Switch(1, DefaultCase(Block(create<ast::BreakStatement>())));
+    auto* s = Switch(1_i, DefaultCase(Block(create<ast::BreakStatement>())));
     WrapInFunction(s);
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/msl/generator_impl_cast_test.cc b/src/tint/writer/msl/generator_impl_cast_test.cc
index 0b84d4d..0eca191 100644
--- a/src/tint/writer/msl/generator_impl_cast_test.cc
+++ b/src/tint/writer/msl/generator_impl_cast_test.cc
@@ -14,13 +14,15 @@
 
 #include "src/tint/writer/msl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::msl {
 namespace {
 
 using MslGeneratorImplTest = TestHelper;
 
 TEST_F(MslGeneratorImplTest, EmitExpression_Cast_Scalar) {
-    auto* cast = Construct<f32>(1);
+    auto* cast = Construct<f32>(1_i);
     WrapInFunction(cast);
 
     GeneratorImpl& gen = Build();
@@ -31,7 +33,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, EmitExpression_Cast_Vector) {
-    auto* cast = vec3<f32>(vec3<i32>(1, 2, 3));
+    auto* cast = vec3<f32>(vec3<i32>(1_i, 2_i, 3_i));
     WrapInFunction(cast);
 
     GeneratorImpl& gen = Build();
@@ -42,7 +44,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, EmitExpression_Cast_IntMin) {
-    auto* cast = Construct<u32>(std::numeric_limits<int32_t>::min());
+    auto* cast = Construct<u32>(i32(std::numeric_limits<int32_t>::min()));
     WrapInFunction(cast);
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/msl/generator_impl_constructor_test.cc b/src/tint/writer/msl/generator_impl_constructor_test.cc
index 07a25eb..134a7ae 100644
--- a/src/tint/writer/msl/generator_impl_constructor_test.cc
+++ b/src/tint/writer/msl/generator_impl_constructor_test.cc
@@ -15,6 +15,8 @@
 #include "gmock/gmock.h"
 #include "src/tint/writer/msl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::msl {
 namespace {
 
@@ -32,7 +34,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, EmitConstructor_Int) {
-    WrapInFunction(Expr(-12345));
+    WrapInFunction(Expr(i32(-12345)));
 
     GeneratorImpl& gen = Build();
 
@@ -41,7 +43,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, EmitConstructor_UInt) {
-    WrapInFunction(Expr(56779u));
+    WrapInFunction(Expr(56779_u));
 
     GeneratorImpl& gen = Build();
 
@@ -78,7 +80,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, EmitConstructor_Type_Int) {
-    WrapInFunction(Construct<i32>(-12345));
+    WrapInFunction(Construct<i32>(i32(-12345)));
 
     GeneratorImpl& gen = Build();
 
@@ -87,7 +89,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, EmitConstructor_Type_Uint) {
-    WrapInFunction(Construct<u32>(12345u));
+    WrapInFunction(Construct<u32>(12345_u));
 
     GeneratorImpl& gen = Build();
 
@@ -137,7 +139,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, EmitConstructor_Type_Array) {
-    WrapInFunction(Construct(ty.array(ty.vec3<f32>(), 3), vec3<f32>(1.0f, 2.0f, 3.0f),
+    WrapInFunction(Construct(ty.array(ty.vec3<f32>(), 3_u), vec3<f32>(1.0f, 2.0f, 3.0f),
                              vec3<f32>(4.0f, 5.0f, 6.0f), vec3<f32>(7.0f, 8.0f, 9.0f)));
 
     GeneratorImpl& gen = Build();
@@ -154,7 +156,7 @@
                                    Member("c", ty.vec3<i32>()),
                                });
 
-    WrapInFunction(Construct(ty.Of(str), 1, 2.0f, vec3<i32>(3, 4, 5)));
+    WrapInFunction(Construct(ty.Of(str), 1_i, 2.0f, vec3<i32>(3_i, 4_i, 5_i)));
 
     GeneratorImpl& gen = Build();
 
diff --git a/src/tint/writer/msl/generator_impl_function_test.cc b/src/tint/writer/msl/generator_impl_function_test.cc
index 80ca5fd..063fda8 100644
--- a/src/tint/writer/msl/generator_impl_function_test.cc
+++ b/src/tint/writer/msl/generator_impl_function_test.cc
@@ -16,6 +16,8 @@
 #include "src/tint/ast/variable_decl_statement.h"
 #include "src/tint/writer/msl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::msl {
 namespace {
 
@@ -641,7 +643,7 @@
              },
              {
                  Stage(ast::PipelineStage::kCompute),
-                 WorkgroupSize(1),
+                 WorkgroupSize(1_i),
              });
     }
 
@@ -651,7 +653,7 @@
         Func("b", ast::VariableList{}, ty.void_(), ast::StatementList{Decl(var), Return()},
              {
                  Stage(ast::PipelineStage::kCompute),
-                 WorkgroupSize(1),
+                 WorkgroupSize(1_i),
              });
     }
 
diff --git a/src/tint/writer/msl/generator_impl_import_test.cc b/src/tint/writer/msl/generator_impl_import_test.cc
index 8d4c086..fa5519a 100644
--- a/src/tint/writer/msl/generator_impl_import_test.cc
+++ b/src/tint/writer/msl/generator_impl_import_test.cc
@@ -15,6 +15,8 @@
 #include "src/tint/sem/call.h"
 #include "src/tint/writer/msl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::msl {
 namespace {
 
@@ -74,7 +76,7 @@
                                          MslImportData{"trunc", "trunc"}));
 
 TEST_F(MslGeneratorImplTest, MslImportData_SingleParamTest_IntScalar) {
-    auto* expr = Call("abs", 1);
+    auto* expr = Call("abs", 1_i);
     WrapInFunction(expr);
 
     GeneratorImpl& gen = Build();
@@ -156,7 +158,7 @@
 TEST_P(MslImportData_DualParam_Int_Test, IntScalar) {
     auto param = GetParam();
 
-    auto* expr = Call(param.name, 1, 2);
+    auto* expr = Call(param.name, 1_i, 2_i);
     WrapInFunction(expr);
 
     GeneratorImpl& gen = Build();
@@ -217,7 +219,7 @@
 TEST_P(MslImportData_TripleParam_Int_Test, IntScalar) {
     auto param = GetParam();
 
-    auto* expr = Call(param.name, 1, 2, 3);
+    auto* expr = Call(param.name, 1_i, 2_i, 3_i);
     WrapInFunction(expr);
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/msl/generator_impl_loop_test.cc b/src/tint/writer/msl/generator_impl_loop_test.cc
index 2e85284..1df7486 100644
--- a/src/tint/writer/msl/generator_impl_loop_test.cc
+++ b/src/tint/writer/msl/generator_impl_loop_test.cc
@@ -15,6 +15,8 @@
 #include "src/tint/ast/variable_decl_statement.h"
 #include "src/tint/writer/msl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::msl {
 namespace {
 
@@ -175,7 +177,7 @@
     // fn f(i : i32) {}
     //
     // var<workgroup> a : atomic<i32>;
-    // for({f(1); f(2);}; ; ) {
+    // for({f(1i); f(2i);}; ; ) {
     //   return;
     // }
 
@@ -183,7 +185,7 @@
     auto f = [&](auto&& expr) { return CallStmt(Call("f", expr)); };
 
     Global("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
-    auto* multi_stmt = Block(f(1), f(2));
+    auto* multi_stmt = Block(f(1_i), f(2_i));
     auto* loop = For(multi_stmt, nullptr, nullptr,  //
                      Block(Return()));
     WrapInFunction(loop);
@@ -231,7 +233,7 @@
     // }
 
     auto* v = Decl(Var("i", ty.i32()));
-    auto* f = For(nullptr, nullptr, Assign("i", Add("i", 1)),  //
+    auto* f = For(nullptr, nullptr, Assign("i", Add("i", 1_i)),  //
                   Block(Return()));
     WrapInFunction(v, f);
 
@@ -251,7 +253,7 @@
     // fn f(i : i32) {}
     //
     // var<workgroup> a : atomic<i32>;
-    // for(; ; { f(1); f(2); }) {
+    // for(; ; { f(1i); f(2i); }) {
     //   return;
     // }
 
@@ -259,7 +261,7 @@
     auto f = [&](auto&& expr) { return CallStmt(Call("f", expr)); };
 
     Global("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
-    auto* multi_stmt = Block(f(1), f(2));
+    auto* multi_stmt = Block(f(1_i), f(2_i));
     auto* loop = For(nullptr, nullptr, multi_stmt,  //
                      Block(Return()));
     WrapInFunction(loop);
@@ -286,7 +288,7 @@
 
     Func("a_statement", {}, ty.void_(), {});
 
-    auto* f = For(Decl(Var("i", ty.i32())), true, Assign("i", Add("i", 1)),
+    auto* f = For(Decl(Var("i", ty.i32())), true, Assign("i", Add("i", 1_i)),
                   Block(CallStmt(Call("a_statement"))));
     WrapInFunction(f);
 
@@ -306,7 +308,7 @@
     // fn f(i : i32) {}
     //
     // var<workgroup> a : atomic<i32>;
-    // for({ f(1); f(2); }; true; { f(3); f(4); }) {
+    // for({ f(1i); f(2i); }; true; { f(3i); f(4i); }) {
     //   return;
     // }
 
@@ -314,8 +316,8 @@
     auto f = [&](auto&& expr) { return CallStmt(Call("f", expr)); };
 
     Global("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
-    auto* multi_stmt_a = Block(f(1), f(2));
-    auto* multi_stmt_b = Block(f(3), f(4));
+    auto* multi_stmt_a = Block(f(1_i), f(2_i));
+    auto* multi_stmt_b = Block(f(3_i), f(4_i));
     auto* loop = For(multi_stmt_a, Expr(true), multi_stmt_b,  //
                      Block(Return()));
     WrapInFunction(loop);
diff --git a/src/tint/writer/msl/generator_impl_return_test.cc b/src/tint/writer/msl/generator_impl_return_test.cc
index 080b7ef..1443209 100644
--- a/src/tint/writer/msl/generator_impl_return_test.cc
+++ b/src/tint/writer/msl/generator_impl_return_test.cc
@@ -14,6 +14,8 @@
 
 #include "src/tint/writer/msl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::msl {
 namespace {
 
@@ -32,7 +34,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_ReturnWithValue) {
-    auto* r = Return(123);
+    auto* r = Return(123_i);
     Func("f", {}, ty.i32(), {r});
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/msl/generator_impl_switch_test.cc b/src/tint/writer/msl/generator_impl_switch_test.cc
index 6da8d73..ce8087b 100644
--- a/src/tint/writer/msl/generator_impl_switch_test.cc
+++ b/src/tint/writer/msl/generator_impl_switch_test.cc
@@ -14,6 +14,8 @@
 
 #include "src/tint/writer/msl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::msl {
 namespace {
 
@@ -26,7 +28,7 @@
     auto* def = create<ast::CaseStatement>(ast::CaseSelectorList{}, def_body);
 
     ast::CaseSelectorList case_val;
-    case_val.push_back(Expr(5));
+    case_val.push_back(Expr(5_i));
 
     auto* case_body = Block(create<ast::BreakStatement>());
 
diff --git a/src/tint/writer/msl/generator_impl_test.cc b/src/tint/writer/msl/generator_impl_test.cc
index 537bd21..b5af8e4 100644
--- a/src/tint/writer/msl/generator_impl_test.cc
+++ b/src/tint/writer/msl/generator_impl_test.cc
@@ -15,6 +15,8 @@
 #include "src/tint/ast/stage_attribute.h"
 #include "src/tint/writer/msl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::msl {
 namespace {
 
@@ -24,7 +26,7 @@
     Func("my_func", ast::VariableList{}, ty.void_(), ast::StatementList{},
          ast::AttributeList{
              Stage(ast::PipelineStage::kCompute),
-             WorkgroupSize(1),
+             WorkgroupSize(1_i),
          });
 
     GeneratorImpl& gen = Build();
@@ -132,7 +134,7 @@
 TEST_F(MslGeneratorImplTest, WorkgroupMatrix) {
     Global("m", ty.mat2x2<f32>(), ast::StorageClass::kWorkgroup);
     Func("comp_main", ast::VariableList{}, ty.void_(), {Decl(Let("x", nullptr, Expr("m")))},
-         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     GeneratorImpl& gen = SanitizeAndBuild();
 
@@ -167,9 +169,9 @@
 }
 
 TEST_F(MslGeneratorImplTest, WorkgroupMatrixInArray) {
-    Global("m", ty.array(ty.mat2x2<f32>(), 4), ast::StorageClass::kWorkgroup);
+    Global("m", ty.array(ty.mat2x2<f32>(), 4_i), ast::StorageClass::kWorkgroup);
     Func("comp_main", ast::VariableList{}, ty.void_(), {Decl(Let("x", nullptr, Expr("m")))},
-         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     GeneratorImpl& gen = SanitizeAndBuild();
 
@@ -218,7 +220,7 @@
                     });
     Global("s", ty.type_name("S2"), ast::StorageClass::kWorkgroup);
     Func("comp_main", ast::VariableList{}, ty.void_(), {Decl(Let("x", nullptr, Expr("s")))},
-         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     GeneratorImpl& gen = SanitizeAndBuild();
 
@@ -278,23 +280,23 @@
              Decl(Let("a2", nullptr, Expr("m2"))),
              Decl(Let("a3", nullptr, Expr("m3"))),
          },
-         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
     Func("main2", ast::VariableList{}, ty.void_(),
          {
              Decl(Let("a1", nullptr, Expr("m4"))),
              Decl(Let("a2", nullptr, Expr("m5"))),
              Decl(Let("a3", nullptr, Expr("m6"))),
          },
-         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
     Func("main3", ast::VariableList{}, ty.void_(),
          {
              Decl(Let("a1", nullptr, Expr("m7"))),
              Decl(Let("a2", nullptr, Expr("m8"))),
              Decl(Let("a3", nullptr, Expr("m9"))),
          },
-         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
     Func("main4_no_usages", ast::VariableList{}, ty.void_(), {},
-         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     GeneratorImpl& gen = SanitizeAndBuild();
 
diff --git a/src/tint/writer/msl/generator_impl_type_test.cc b/src/tint/writer/msl/generator_impl_type_test.cc
index 648b649..257468b 100644
--- a/src/tint/writer/msl/generator_impl_type_test.cc
+++ b/src/tint/writer/msl/generator_impl_type_test.cc
@@ -24,11 +24,13 @@
 #include "src/tint/sem/storage_texture.h"
 #include "src/tint/writer/msl/test_helper.h"
 
+using ::testing::HasSubstr;
+
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::msl {
 namespace {
 
-using ::testing::HasSubstr;
-
 #define CHECK_TYPE_SIZE_AND_ALIGN(TYPE, SIZE, ALIGN)      \
     static_assert(sizeof(TYPE) == SIZE, "Bad type size"); \
     static_assert(alignof(TYPE) == ALIGN, "Bad type alignment")
@@ -72,7 +74,7 @@
 
 TEST_F(MslGeneratorImplTest, EmitType_ArrayOfArray) {
     auto* a = ty.array<bool, 4>();
-    auto* b = ty.array(a, 5);
+    auto* b = ty.array(a, 5_u);
     Global("G", b, ast::StorageClass::kPrivate);
 
     GeneratorImpl& gen = Build();
@@ -84,8 +86,8 @@
 
 TEST_F(MslGeneratorImplTest, EmitType_ArrayOfArrayOfArray) {
     auto* a = ty.array<bool, 4>();
-    auto* b = ty.array(a, 5);
-    auto* c = ty.array(b, 6);
+    auto* b = ty.array(a, 5_u);
+    auto* c = ty.array(b, 6_u);
     Global("G", c, ast::StorageClass::kPrivate);
 
     GeneratorImpl& gen = Build();
@@ -412,7 +414,7 @@
     auto* array_x = ty.array<f32, 7>();
 
     // array_y: size(4096), align(512)
-    auto* array_y = ty.array(ty.Of(inner), 4);
+    auto* array_y = ty.array(ty.Of(inner), 4_u);
 
     // array_z: size(4), align(4)
     auto* array_z = ty.array<f32>();
@@ -500,7 +502,7 @@
 
 TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_ArrayVec3DefaultStride) {
     // array: size(64), align(16)
-    auto* array = ty.array(ty.vec3<f32>(), 4);
+    auto* array = ty.array(ty.vec3<f32>(), 4_u);
 
     auto* s = Structure("S", {
                                  Member("a", ty.i32()),
diff --git a/src/tint/writer/msl/generator_impl_unary_op_test.cc b/src/tint/writer/msl/generator_impl_unary_op_test.cc
index 64ef733..a1aecd9 100644
--- a/src/tint/writer/msl/generator_impl_unary_op_test.cc
+++ b/src/tint/writer/msl/generator_impl_unary_op_test.cc
@@ -83,7 +83,7 @@
 
 TEST_F(MslUnaryOpTest, NegationOfIntMin) {
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kNegation,
-                                              Expr(std::numeric_limits<int32_t>::min()));
+                                              Expr(i32(std::numeric_limits<int32_t>::min())));
     WrapInFunction(op);
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/spirv/builder_accessor_expression_test.cc b/src/tint/writer/spirv/builder_accessor_expression_test.cc
index bb1fc26..67ee185 100644
--- a/src/tint/writer/spirv/builder_accessor_expression_test.cc
+++ b/src/tint/writer/spirv/builder_accessor_expression_test.cc
@@ -15,6 +15,8 @@
 #include "src/tint/writer/spirv/spv_dump.h"
 #include "src/tint/writer/spirv/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::spirv {
 namespace {
 
@@ -27,7 +29,7 @@
     auto* var = Var("ary", ty.vec3<f32>());
 
     auto* ary = Expr("ary");
-    auto* idx_expr = Expr(1);
+    auto* idx_expr = Expr(1_i);
 
     auto* expr = IndexAccessor(ary, idx_expr);
     WrapInFunction(var, expr);
@@ -104,7 +106,7 @@
 
     auto* ary = Expr("ary");
 
-    auto* expr = IndexAccessor(ary, Add(1, 2));
+    auto* expr = IndexAccessor(ary, Add(1_i, 2_i));
     WrapInFunction(var, expr);
 
     spirv::Builder& b = Build();
@@ -133,14 +135,14 @@
 }
 
 TEST_F(BuilderTest, IndexAccessor_ArrayRef_MultiLevel) {
-    auto* ary4 = ty.array(ty.vec3<f32>(), 4);
+    auto* ary4 = ty.array(ty.vec3<f32>(), 4_u);
 
-    // var ary : array<vec3<f32>, 4>
-    // ary[3][2];
+    // var ary : array<vec3<f32>, 4u>
+    // ary[3i][2i];
 
     auto* var = Var("ary", ary4);
 
-    auto* expr = IndexAccessor(IndexAccessor("ary", 3), 2);
+    auto* expr = IndexAccessor(IndexAccessor("ary", 3_i), 2_i);
     WrapInFunction(var, expr);
 
     spirv::Builder& b = Build();
@@ -171,14 +173,14 @@
 }
 
 TEST_F(BuilderTest, IndexAccessor_ArrayRef_ArrayWithSwizzle) {
-    auto* ary4 = ty.array(ty.vec3<f32>(), 4);
+    auto* ary4 = ty.array(ty.vec3<f32>(), 4_u);
 
-    // var a : array<vec3<f32>, 4>;
-    // a[2].xy;
+    // var a : array<vec3<f32>, 4u>;
+    // a[2i].xy;
 
     auto* var = Var("ary", ary4);
 
-    auto* expr = MemberAccessor(IndexAccessor("ary", 2), "xy");
+    auto* expr = MemberAccessor(IndexAccessor("ary", 2_i), "xy");
     WrapInFunction(var, expr);
 
     spirv::Builder& b = Build();
@@ -647,11 +649,11 @@
 }
 
 TEST_F(BuilderTest, MemberAccessor_Array_of_Swizzle) {
-    // index.yxz[1]
+    // index.yxz[1i]
 
     auto* var = Var("ident", ty.vec3<f32>());
 
-    auto* expr = IndexAccessor(MemberAccessor("ident", "yxz"), 1);
+    auto* expr = IndexAccessor(MemberAccessor("ident", "yxz"), 1_i);
     WrapInFunction(var, expr);
 
     spirv::Builder& b = Build();
@@ -688,20 +690,20 @@
     // type A = struct {
     //   foo : array<B, 3>
     // }
-    // var index : array<A, 2>
-    // index[0].foo[2].bar.baz.yx
+    // var index : array<A, 2u>
+    // index[0i].foo[2i].bar.baz.yx
 
     auto* c_type = Structure("C", {Member("baz", ty.vec3<f32>())});
 
     auto* b_type = Structure("B", {Member("bar", ty.Of(c_type))});
-    auto* b_ary_type = ty.array(ty.Of(b_type), 3);
+    auto* b_ary_type = ty.array(ty.Of(b_type), 3_u);
     auto* a_type = Structure("A", {Member("foo", b_ary_type)});
 
-    auto* a_ary_type = ty.array(ty.Of(a_type), 2);
+    auto* a_ary_type = ty.array(ty.Of(a_type), 2_u);
     auto* var = Var("index", a_ary_type);
     auto* expr = MemberAccessor(
         MemberAccessor(
-            MemberAccessor(IndexAccessor(MemberAccessor(IndexAccessor("index", 0), "foo"), 2),
+            MemberAccessor(IndexAccessor(MemberAccessor(IndexAccessor("index", 0_i), "foo"), 2_i),
                            "bar"),
             "baz"),
         "yx");
@@ -744,17 +746,17 @@
 }
 
 TEST_F(BuilderTest, IndexAccessor_Of_Vec) {
-    // let pos : array<vec2<f32>, 3> = array<vec2<f32>, 3>(
+    // let pos : array<vec2<f32>, 3u> = array<vec2<f32>, 3u>(
     //   vec2<f32>(0.0, 0.5),
     //   vec2<f32>(-0.5, -0.5),
     //   vec2<f32>(0.5, -0.5));
-    // pos[1]
+    // pos[1u]
 
-    auto* var = Let("pos", ty.array(ty.vec2<f32>(), 3),
-                    Construct(ty.array(ty.vec2<f32>(), 3), vec2<f32>(0.0f, 0.5f),
+    auto* var = Let("pos", ty.array(ty.vec2<f32>(), 3_u),
+                    Construct(ty.array(ty.vec2<f32>(), 3_u), vec2<f32>(0.0f, 0.5f),
                               vec2<f32>(-0.5f, -0.5f), vec2<f32>(0.5f, -0.5f)));
 
-    auto* expr = IndexAccessor("pos", 1u);
+    auto* expr = IndexAccessor("pos", 1_u);
     WrapInFunction(var, expr);
 
     spirv::Builder& b = SanitizeAndBuild();
@@ -787,17 +789,17 @@
 }
 
 TEST_F(BuilderTest, IndexAccessor_Of_Array_Of_f32) {
-    // let pos : array<array<f32, 2>, 3> = array<vec2<f32, 2>, 3>(
+    // let pos : array<array<f32, 2>, 3u> = array<vec2<f32, 2>, 3u>(
     //   array<f32, 2>(0.0, 0.5),
     //   array<f32, 2>(-0.5, -0.5),
     //   array<f32, 2>(0.5, -0.5));
-    // pos[2][1]
+    // pos[2u][1u]
 
-    auto* var = Let("pos", ty.array(ty.vec2<f32>(), 3),
-                    Construct(ty.array(ty.vec2<f32>(), 3), vec2<f32>(0.0f, 0.5f),
+    auto* var = Let("pos", ty.array(ty.vec2<f32>(), 3_u),
+                    Construct(ty.array(ty.vec2<f32>(), 3_u), vec2<f32>(0.0f, 0.5f),
                               vec2<f32>(-0.5f, -0.5f), vec2<f32>(0.5f, -0.5f)));
 
-    auto* expr = IndexAccessor(IndexAccessor("pos", 2u), 1u);
+    auto* expr = IndexAccessor(IndexAccessor("pos", 2_u), 1_u);
     WrapInFunction(var, expr);
 
     spirv::Builder& b = SanitizeAndBuild();
@@ -837,7 +839,7 @@
 
     auto* var = Let("pos", ty.vec2<f32>(), vec2<f32>(0.0f, 0.5f));
 
-    auto* expr = IndexAccessor("pos", 1u);
+    auto* expr = IndexAccessor("pos", 1_u);
     WrapInFunction(var, expr);
 
     spirv::Builder& b = Build();
@@ -897,11 +899,11 @@
 }
 
 TEST_F(BuilderTest, IndexAccessor_Array_Literal) {
-    // let a : array<f32, 3>;
-    // a[2]
+    // let a : array<f32, 3u>;
+    // a[2i]
 
     auto* var = Let("a", ty.array<f32, 3>(), Construct(ty.array<f32, 3>(), 0.0f, 0.5f, 1.0f));
-    auto* expr = IndexAccessor("a", 2);
+    auto* expr = IndexAccessor("a", 2_i);
     WrapInFunction(var, expr);
 
     spirv::Builder& b = SanitizeAndBuild();
diff --git a/src/tint/writer/spirv/builder_assign_test.cc b/src/tint/writer/spirv/builder_assign_test.cc
index b94e1c1..1e02e27 100644
--- a/src/tint/writer/spirv/builder_assign_test.cc
+++ b/src/tint/writer/spirv/builder_assign_test.cc
@@ -15,6 +15,8 @@
 #include "src/tint/writer/spirv/spv_dump.h"
 #include "src/tint/writer/spirv/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::spirv {
 namespace {
 
@@ -282,7 +284,7 @@
 
     auto* v = Global("var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
 
-    auto* assign = Assign(IndexAccessor("var", 1), Expr(1.f));
+    auto* assign = Assign(IndexAccessor("var", 1_i), Expr(1.f));
 
     WrapInFunction(assign);
 
diff --git a/src/tint/writer/spirv/builder_binary_expression_test.cc b/src/tint/writer/spirv/builder_binary_expression_test.cc
index ce71cad..17ca134 100644
--- a/src/tint/writer/spirv/builder_binary_expression_test.cc
+++ b/src/tint/writer/spirv/builder_binary_expression_test.cc
@@ -15,6 +15,8 @@
 #include "src/tint/writer/spirv/spv_dump.h"
 #include "src/tint/writer/spirv/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::spirv {
 namespace {
 
@@ -33,8 +35,8 @@
 TEST_P(BinaryArithSignedIntegerTest, Scalar) {
     auto param = GetParam();
 
-    auto* lhs = Expr(3);
-    auto* rhs = Expr(4);
+    auto* lhs = Expr(3_i);
+    auto* rhs = Expr(4_i);
 
     auto* expr = create<ast::BinaryExpression>(param.op, lhs, rhs);
 
@@ -62,8 +64,8 @@
         return;
     }
 
-    auto* lhs = vec3<i32>(1, 1, 1);
-    auto* rhs = vec3<i32>(1, 1, 1);
+    auto* lhs = vec3<i32>(1_i, 1_i, 1_i);
+    auto* rhs = vec3<i32>(1_i, 1_i, 1_i);
 
     auto* expr = create<ast::BinaryExpression>(param.op, lhs, rhs);
 
@@ -127,8 +129,8 @@
 TEST_P(BinaryArithUnsignedIntegerTest, Scalar) {
     auto param = GetParam();
 
-    auto* lhs = Expr(3u);
-    auto* rhs = Expr(4u);
+    auto* lhs = Expr(3_u);
+    auto* rhs = Expr(4_u);
 
     auto* expr = create<ast::BinaryExpression>(param.op, lhs, rhs);
 
@@ -155,8 +157,8 @@
         return;
     }
 
-    auto* lhs = vec3<u32>(1u, 1u, 1u);
-    auto* rhs = vec3<u32>(1u, 1u, 1u);
+    auto* lhs = vec3<u32>(1_u, 1_u, 1_u);
+    auto* rhs = vec3<u32>(1_u, 1_u, 1_u);
 
     auto* expr = create<ast::BinaryExpression>(param.op, lhs, rhs);
 
@@ -304,8 +306,8 @@
 TEST_P(BinaryCompareUnsignedIntegerTest, Scalar) {
     auto param = GetParam();
 
-    auto* lhs = Expr(3u);
-    auto* rhs = Expr(4u);
+    auto* lhs = Expr(3_u);
+    auto* rhs = Expr(4_u);
 
     auto* expr = create<ast::BinaryExpression>(param.op, lhs, rhs);
 
@@ -328,8 +330,8 @@
 TEST_P(BinaryCompareUnsignedIntegerTest, Vector) {
     auto param = GetParam();
 
-    auto* lhs = vec3<u32>(1u, 1u, 1u);
-    auto* rhs = vec3<u32>(1u, 1u, 1u);
+    auto* lhs = vec3<u32>(1_u, 1_u, 1_u);
+    auto* rhs = vec3<u32>(1_u, 1_u, 1_u);
 
     auto* expr = create<ast::BinaryExpression>(param.op, lhs, rhs);
 
@@ -364,8 +366,8 @@
 TEST_P(BinaryCompareSignedIntegerTest, Scalar) {
     auto param = GetParam();
 
-    auto* lhs = Expr(3);
-    auto* rhs = Expr(4);
+    auto* lhs = Expr(3_i);
+    auto* rhs = Expr(4_i);
 
     auto* expr = create<ast::BinaryExpression>(param.op, lhs, rhs);
 
@@ -388,8 +390,8 @@
 TEST_P(BinaryCompareSignedIntegerTest, Vector) {
     auto param = GetParam();
 
-    auto* lhs = vec3<i32>(1, 1, 1);
-    auto* rhs = vec3<i32>(1, 1, 1);
+    auto* lhs = vec3<i32>(1_i, 1_i, 1_i);
+    auto* rhs = vec3<i32>(1_i, 1_i, 1_i);
 
     auto* expr = create<ast::BinaryExpression>(param.op, lhs, rhs);
 
@@ -666,9 +668,9 @@
 }
 
 TEST_F(BuilderTest, Binary_LogicalAnd) {
-    auto* lhs = create<ast::BinaryExpression>(ast::BinaryOp::kEqual, Expr(1), Expr(2));
+    auto* lhs = create<ast::BinaryExpression>(ast::BinaryOp::kEqual, Expr(1_i), Expr(2_i));
 
-    auto* rhs = create<ast::BinaryExpression>(ast::BinaryOp::kEqual, Expr(3), Expr(4));
+    auto* rhs = create<ast::BinaryExpression>(ast::BinaryOp::kEqual, Expr(3_i), Expr(4_i));
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, lhs, rhs);
 
@@ -819,9 +821,9 @@
 }
 
 TEST_F(BuilderTest, Binary_LogicalOr) {
-    auto* lhs = create<ast::BinaryExpression>(ast::BinaryOp::kEqual, Expr(1), Expr(2));
+    auto* lhs = create<ast::BinaryExpression>(ast::BinaryOp::kEqual, Expr(1_i), Expr(2_i));
 
-    auto* rhs = create<ast::BinaryExpression>(ast::BinaryOp::kEqual, Expr(3), Expr(4));
+    auto* rhs = create<ast::BinaryExpression>(ast::BinaryOp::kEqual, Expr(3_i), Expr(4_i));
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, lhs, rhs);
 
@@ -897,11 +899,11 @@
 static const ast::Expression* MakeVectorExpr(ProgramBuilder* builder, Type type) {
     switch (type) {
         case Type::f32:
-            return builder->vec3<ProgramBuilder::f32>(1.f, 1.f, 1.f);
+            return builder->vec3<f32>(1.f, 1.f, 1.f);
         case Type::i32:
-            return builder->vec3<ProgramBuilder::i32>(1, 1, 1);
+            return builder->vec3<i32>(1_i, 1_i, 1_i);
         case Type::u32:
-            return builder->vec3<ProgramBuilder::u32>(1u, 1u, 1u);
+            return builder->vec3<u32>(1_u, 1_u, 1_u);
     }
     return nullptr;
 }
@@ -910,9 +912,9 @@
         case Type::f32:
             return builder->Expr(1.f);
         case Type::i32:
-            return builder->Expr(1);
+            return builder->Expr(1_i);
         case Type::u32:
-            return builder->Expr(1u);
+            return builder->Expr(1_u);
     }
     return nullptr;
 }
diff --git a/src/tint/writer/spirv/builder_builtin_test.cc b/src/tint/writer/spirv/builder_builtin_test.cc
index 955b457..901abad 100644
--- a/src/tint/writer/spirv/builder_builtin_test.cc
+++ b/src/tint/writer/spirv/builder_builtin_test.cc
@@ -19,6 +19,8 @@
 #include "src/tint/writer/spirv/spv_dump.h"
 #include "src/tint/writer/spirv/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::spirv {
 namespace {
 
@@ -962,7 +964,7 @@
 using Builtin_Builtin_SingleParam_Sint_Test = BuiltinBuilderTestWithParam<BuiltinData>;
 TEST_P(Builtin_Builtin_SingleParam_Sint_Test, Call_Scalar) {
     auto param = GetParam();
-    auto* expr = Call(param.name, 1);
+    auto* expr = Call(param.name, 1_i);
     auto* func = Func("a_func", {}, ty.void_(),
                       {
                           Assign(Phony(), expr),
@@ -989,7 +991,7 @@
 
 TEST_P(Builtin_Builtin_SingleParam_Sint_Test, Call_Vector) {
     auto param = GetParam();
-    auto* expr = Call(param.name, vec2<i32>(1, 1));
+    auto* expr = Call(param.name, vec2<i32>(1_i, 1_i));
     auto* func = Func("a_func", {}, ty.void_(),
                       {
                           Assign(Phony(), expr),
@@ -1022,7 +1024,7 @@
 // Calling abs() on an unsigned integer scalar / vector is a no-op.
 using Builtin_Builtin_Abs_Uint_Test = BuiltinBuilderTest;
 TEST_F(Builtin_Builtin_Abs_Uint_Test, Call_Scalar) {
-    auto* expr = Call("abs", 1u);
+    auto* expr = Call("abs", 1_u);
     auto* func = Func("a_func", {}, ty.void_(),
                       {
                           Assign(Phony(), expr),
@@ -1045,7 +1047,7 @@
 }
 
 TEST_F(Builtin_Builtin_Abs_Uint_Test, Call_Vector) {
-    auto* expr = Call("abs", vec2<u32>(1u, 1u));
+    auto* expr = Call("abs", vec2<u32>(1_u, 1_u));
     auto* func = Func("a_func", {}, ty.void_(),
                       {
                           Assign(Phony(), expr),
@@ -1072,7 +1074,7 @@
 using Builtin_Builtin_DualParam_SInt_Test = BuiltinBuilderTestWithParam<BuiltinData>;
 TEST_P(Builtin_Builtin_DualParam_SInt_Test, Call_Scalar) {
     auto param = GetParam();
-    auto* expr = Call(param.name, 1, 1);
+    auto* expr = Call(param.name, 1_i, 1_i);
     auto* func = Func("a_func", {}, ty.void_(),
                       {
                           Assign(Phony(), expr),
@@ -1099,7 +1101,7 @@
 
 TEST_P(Builtin_Builtin_DualParam_SInt_Test, Call_Vector) {
     auto param = GetParam();
-    auto* expr = Call(param.name, vec2<i32>(1, 1), vec2<i32>(1, 1));
+    auto* expr = Call(param.name, vec2<i32>(1_i, 1_i), vec2<i32>(1_i, 1_i));
     auto* func = Func("a_func", {}, ty.void_(),
                       {
                           Assign(Phony(), expr),
@@ -1132,7 +1134,7 @@
 using Builtin_Builtin_DualParam_UInt_Test = BuiltinBuilderTestWithParam<BuiltinData>;
 TEST_P(Builtin_Builtin_DualParam_UInt_Test, Call_Scalar) {
     auto param = GetParam();
-    auto* expr = Call(param.name, 1u, 1u);
+    auto* expr = Call(param.name, 1_u, 1_u);
     auto* func = Func("a_func", {}, ty.void_(),
                       {
                           Assign(Phony(), expr),
@@ -1159,7 +1161,7 @@
 
 TEST_P(Builtin_Builtin_DualParam_UInt_Test, Call_Vector) {
     auto param = GetParam();
-    auto* expr = Call(param.name, vec2<u32>(1u, 1u), vec2<u32>(1u, 1u));
+    auto* expr = Call(param.name, vec2<u32>(1_u, 1_u), vec2<u32>(1_u, 1_u));
     auto* func = Func("a_func", {}, ty.void_(),
                       {
                           Assign(Phony(), expr),
@@ -1192,7 +1194,7 @@
 using Builtin_Builtin_ThreeParam_Sint_Test = BuiltinBuilderTestWithParam<BuiltinData>;
 TEST_P(Builtin_Builtin_ThreeParam_Sint_Test, Call_Scalar) {
     auto param = GetParam();
-    auto* expr = Call(param.name, 1, 1, 1);
+    auto* expr = Call(param.name, 1_i, 1_i, 1_i);
     auto* func = Func("a_func", {}, ty.void_(),
                       {
                           Assign(Phony(), expr),
@@ -1219,7 +1221,7 @@
 
 TEST_P(Builtin_Builtin_ThreeParam_Sint_Test, Call_Vector) {
     auto param = GetParam();
-    auto* expr = Call(param.name, vec2<i32>(1, 1), vec2<i32>(1, 1), vec2<i32>(1, 1));
+    auto* expr = Call(param.name, vec2<i32>(1_i, 1_i), vec2<i32>(1_i, 1_i), vec2<i32>(1_i, 1_i));
     auto* func = Func("a_func", {}, ty.void_(),
                       {
                           Assign(Phony(), expr),
@@ -1252,7 +1254,7 @@
 using Builtin_Builtin_ThreeParam_Uint_Test = BuiltinBuilderTestWithParam<BuiltinData>;
 TEST_P(Builtin_Builtin_ThreeParam_Uint_Test, Call_Scalar) {
     auto param = GetParam();
-    auto* expr = Call(param.name, 1u, 1u, 1u);
+    auto* expr = Call(param.name, 1_u, 1_u, 1_u);
     auto* func = Func("a_func", {}, ty.void_(),
                       {
                           Assign(Phony(), expr),
@@ -1279,7 +1281,7 @@
 
 TEST_P(Builtin_Builtin_ThreeParam_Uint_Test, Call_Vector) {
     auto param = GetParam();
-    auto* expr = Call(param.name, vec2<u32>(1u, 1u), vec2<u32>(1u, 1u), vec2<u32>(1u, 1u));
+    auto* expr = Call(param.name, vec2<u32>(1_u, 1_u), vec2<u32>(1_u, 1_u), vec2<u32>(1_u, 1_u));
     auto* func = Func("a_func", {}, ty.void_(),
                       {
                           Assign(Phony(), expr),
@@ -1475,7 +1477,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    ASSERT_EQ(b.functions().size(), 1u);
+    ASSERT_EQ(b.functions().size(), 1_u);
 
     auto* expected_types = R"(%5 = OpTypeFloat 32
 %4 = OpTypeRuntimeArray %5
@@ -1522,7 +1524,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    ASSERT_EQ(b.functions().size(), 1u);
+    ASSERT_EQ(b.functions().size(), 1_u);
 
     auto* expected_types = R"(%4 = OpTypeFloat 32
 %5 = OpTypeRuntimeArray %4
@@ -1571,7 +1573,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    ASSERT_EQ(b.functions().size(), 1u);
+    ASSERT_EQ(b.functions().size(), 1_u);
 
     auto* expected_types = R"(%5 = OpTypeFloat 32
 %4 = OpTypeRuntimeArray %5
@@ -1633,7 +1635,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    ASSERT_EQ(b.functions().size(), 1u);
+    ASSERT_EQ(b.functions().size(), 1_u);
 
     auto* expected_types = R"(%5 = OpTypeFloat 32
 %4 = OpTypeRuntimeArray %5
@@ -1689,7 +1691,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    ASSERT_EQ(b.functions().size(), 1u);
+    ASSERT_EQ(b.functions().size(), 1_u);
 
     auto* expected_types = R"(%4 = OpTypeInt 32 0
 %5 = OpTypeInt 32 1
@@ -1727,7 +1729,7 @@
     // @binding(1) @group(2) var<storage, read_write> b : S;
     //
     // fn a_func() {
-    //   var u = 1u;
+    //   var u = 1_u;
     //   var i = 2;
     //   atomicStore(&b.u, u);
     //   atomicStore(&b.i, i);
@@ -1744,8 +1746,8 @@
 
     Func("a_func", {}, ty.void_(),
          ast::StatementList{
-             Decl(Var("u", nullptr, Expr(1u))),
-             Decl(Var("i", nullptr, Expr(2))),
+             Decl(Var("u", nullptr, Expr(1_u))),
+             Decl(Var("i", nullptr, Expr(2_i))),
              CallStmt(Call("atomicStore", AddressOf(MemberAccessor("b", "u")), "u")),
              CallStmt(Call("atomicStore", AddressOf(MemberAccessor("b", "i")), "i")),
          },
@@ -1755,7 +1757,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    ASSERT_EQ(b.functions().size(), 1u);
+    ASSERT_EQ(b.functions().size(), 1_u);
 
     auto* expected_types = R"(%4 = OpTypeInt 32 0
 %5 = OpTypeInt 32 1
@@ -1816,7 +1818,7 @@
 
     Func("a_func", {}, ty.void_(),
          ast::StatementList{
-             Decl(Var("v", nullptr, Expr(10))),
+             Decl(Var("v", nullptr, Expr(10_i))),
              Decl(Let("x", ty.i32(),
                       Call(GetParam().name, AddressOf(MemberAccessor("b", "v")), "v"))),
          },
@@ -1826,7 +1828,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    ASSERT_EQ(b.functions().size(), 1u);
+    ASSERT_EQ(b.functions().size(), 1_u);
 
     std::string expected_types = R"(%4 = OpTypeInt 32 1
 %3 = OpTypeStruct %4
@@ -1889,7 +1891,7 @@
 
     Func("a_func", {}, ty.void_(),
          ast::StatementList{
-             Decl(Var("v", nullptr, Expr(10u))),
+             Decl(Var("v", nullptr, Expr(10_u))),
              Decl(Let("x", ty.u32(),
                       Call(GetParam().name, AddressOf(MemberAccessor("b", "v")), "v"))),
          },
@@ -1899,7 +1901,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    ASSERT_EQ(b.functions().size(), 1u);
+    ASSERT_EQ(b.functions().size(), 1_u);
 
     std::string expected_types = R"(%4 = OpTypeInt 32 0
 %3 = OpTypeStruct %4
@@ -1948,7 +1950,7 @@
     //
     // fn a_func() {
     //   var u = 10u;
-    //   var i = 10;
+    //   var i = 10i;
     //   let r : u32 = atomicExchange(&b.u, u);
     //   let s : i32 = atomicExchange(&b.i, i);
     // }
@@ -1964,8 +1966,8 @@
 
     Func("a_func", {}, ty.void_(),
          ast::StatementList{
-             Decl(Var("u", nullptr, Expr(10u))),
-             Decl(Var("i", nullptr, Expr(10))),
+             Decl(Var("u", nullptr, Expr(10_u))),
+             Decl(Var("i", nullptr, Expr(10_i))),
              Decl(Let("r", ty.u32(),
                       Call("atomicExchange", AddressOf(MemberAccessor("b", "u")), "u"))),
              Decl(Let("s", ty.i32(),
@@ -1977,7 +1979,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    ASSERT_EQ(b.functions().size(), 1u);
+    ASSERT_EQ(b.functions().size(), 1_u);
 
     auto* expected_types = R"(%4 = OpTypeInt 32 0
 %5 = OpTypeInt 32 1
@@ -2040,12 +2042,12 @@
 
     Func("a_func", {}, ty.void_(),
          ast::StatementList{
-             Decl(Let(
-                 "u", ty.vec2<u32>(),
-                 Call("atomicCompareExchangeWeak", AddressOf(MemberAccessor("b", "u")), 10u, 20u))),
-             Decl(Let(
-                 "i", ty.vec2<i32>(),
-                 Call("atomicCompareExchangeWeak", AddressOf(MemberAccessor("b", "i")), 10, 20))),
+             Decl(Let("u", ty.vec2<u32>(),
+                      Call("atomicCompareExchangeWeak", AddressOf(MemberAccessor("b", "u")), 10_u,
+                           20_u))),
+             Decl(Let("i", ty.vec2<i32>(),
+                      Call("atomicCompareExchangeWeak", AddressOf(MemberAccessor("b", "i")), 10_i,
+                           20_i))),
          },
          ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
 
@@ -2053,7 +2055,7 @@
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    ASSERT_EQ(b.functions().size(), 1u);
+    ASSERT_EQ(b.functions().size(), 1_u);
 
     auto* expected_types = R"(%4 = OpTypeInt 32 0
 %5 = OpTypeInt 32 1
@@ -2160,7 +2162,7 @@
     auto param = GetParam();
 
     bool pack4 = param.name == "unpack4x8snorm" || param.name == "unpack4x8unorm";
-    auto* func = Func("a_func", {}, ty.void_(), {CallStmt(Call(param.name, 1u))});
+    auto* func = Func("a_func", {}, ty.void_(), {CallStmt(Call(param.name, 1_u))});
 
     spirv::Builder& b = Build();
 
@@ -2216,14 +2218,14 @@
          },
          ast::AttributeList{
              Stage(ast::PipelineStage::kCompute),
-             WorkgroupSize(1),
+             WorkgroupSize(1_i),
          });
 
     spirv::Builder& b = Build();
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    ASSERT_EQ(b.functions().size(), 1u);
+    ASSERT_EQ(b.functions().size(), 1_u);
 
     auto* expected_types = R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
@@ -2250,14 +2252,14 @@
          },
          ast::AttributeList{
              Stage(ast::PipelineStage::kCompute),
-             WorkgroupSize(1),
+             WorkgroupSize(1_i),
          });
 
     spirv::Builder& b = Build();
 
     ASSERT_TRUE(b.Build()) << b.error();
 
-    ASSERT_EQ(b.functions().size(), 1u);
+    ASSERT_EQ(b.functions().size(), 1_u);
 
     auto* expected_types = R"(%2 = OpTypeVoid
 %1 = OpTypeFunction %2
diff --git a/src/tint/writer/spirv/builder_constructor_expression_test.cc b/src/tint/writer/spirv/builder_constructor_expression_test.cc
index 5e6f7d4..41409af 100644
--- a/src/tint/writer/spirv/builder_constructor_expression_test.cc
+++ b/src/tint/writer/spirv/builder_constructor_expression_test.cc
@@ -15,6 +15,8 @@
 #include "src/tint/writer/spirv/spv_dump.h"
 #include "src/tint/writer/spirv/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::spirv {
 namespace {
 
@@ -35,7 +37,7 @@
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_WithCasts_OutsideFunction_IsError) {
-    auto* t = Construct<f32>(Construct<u32>(1));
+    auto* t = Construct<f32>(Construct<u32>(1_i));
     WrapInFunction(t);
 
     spirv::Builder& b = Build();
@@ -65,7 +67,7 @@
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_WithCasts) {
-    auto* t = vec2<f32>(Construct<f32>(1), Construct<f32>(1));
+    auto* t = vec2<f32>(Construct<f32>(1_i), Construct<f32>(1_i));
     WrapInFunction(t);
 
     spirv::Builder& b = Build();
@@ -140,7 +142,7 @@
 }
 
 TEST_F(SpvBuilderConstructorTest, Vector_Bitcast_Params) {
-    auto* t = vec2<u32>(Construct<u32>(1), Construct<u32>(1));
+    auto* t = vec2<u32>(Construct<u32>(1_i), Construct<u32>(1_i));
     WrapInFunction(t);
 
     spirv::Builder& b = Build();
@@ -181,7 +183,7 @@
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_I32_With_I32) {
-    auto* cast = Construct<i32>(2);
+    auto* cast = Construct<i32>(2_i);
     WrapInFunction(cast);
 
     spirv::Builder& b = Build();
@@ -196,7 +198,7 @@
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_U32_With_U32) {
-    auto* cast = Construct<u32>(2u);
+    auto* cast = Construct<u32>(2_u);
     WrapInFunction(cast);
 
     spirv::Builder& b = Build();
@@ -1162,7 +1164,7 @@
 TEST_F(SpvBuilderConstructorTest, Type_Array_2_Vec3) {
     auto* first = vec3<f32>(1.f, 2.f, 3.f);
     auto* second = vec3<f32>(1.f, 2.f, 3.f);
-    auto* t = Construct(ty.array(ty.vec3<f32>(), 2), first, second);
+    auto* t = Construct(ty.array(ty.vec3<f32>(), 2_u), first, second);
     WrapInFunction(t);
     spirv::Builder& b = Build();
 
@@ -1425,7 +1427,7 @@
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Convert_U32_To_I32) {
-    auto* cast = Construct<i32>(2u);
+    auto* cast = Construct<i32>(2_u);
     WrapInFunction(cast);
 
     spirv::Builder& b = Build();
@@ -1443,7 +1445,7 @@
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Convert_I32_To_U32) {
-    auto* cast = Construct<u32>(2);
+    auto* cast = Construct<u32>(2_i);
     WrapInFunction(cast);
 
     spirv::Builder& b = Build();
@@ -1497,7 +1499,7 @@
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Convert_I32_To_F32) {
-    auto* cast = Construct<f32>(2);
+    auto* cast = Construct<f32>(2_i);
     WrapInFunction(cast);
 
     spirv::Builder& b = Build();
@@ -1515,7 +1517,7 @@
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Convert_U32_To_F32) {
-    auto* cast = Construct<f32>(2u);
+    auto* cast = Construct<f32>(2_u);
     WrapInFunction(cast);
 
     spirv::Builder& b = Build();
@@ -1700,10 +1702,10 @@
 }
 
 TEST_F(SpvBuilderConstructorTest, IsConstructorConst_GlobalArrayWithAllConstConstructors) {
-    // array<vec3<f32>, 2>(vec3<f32>(1.0, 2.0, 3.0), vec3<f32>(1.0, 2.0, 3.0))
+    // array<vec3<f32>, 2u>(vec3<f32>(1.0, 2.0, 3.0), vec3<f32>(1.0, 2.0, 3.0))
     //   -> true
-    auto* t =
-        Construct(ty.array(ty.vec3<f32>(), 2), vec3<f32>(1.f, 2.f, 3.f), vec3<f32>(1.f, 2.f, 3.f));
+    auto* t = Construct(ty.array(ty.vec3<f32>(), 2_u), vec3<f32>(1.f, 2.f, 3.f),
+                        vec3<f32>(1.f, 2.f, 3.f));
     WrapInFunction(t);
 
     spirv::Builder& b = Build();
@@ -1727,7 +1729,7 @@
 TEST_F(SpvBuilderConstructorTest, IsConstructorConst_GlobalWithTypeConversionConstructor) {
     // vec2<f32>(f32(1), f32(2)) -> false
 
-    auto* t = vec2<f32>(Construct<f32>(1), Construct<f32>(2));
+    auto* t = vec2<f32>(Construct<f32>(1_i), Construct<f32>(2_i));
     WrapInFunction(t);
 
     spirv::Builder& b = Build();
@@ -1765,13 +1767,13 @@
 }
 
 TEST_F(SpvBuilderConstructorTest, IsConstructorConst_ArrayWithAllConstConstructors) {
-    // array<vec3<f32>, 2>(vec3<f32>(1.0, 2.0, 3.0), vec3<f32>(1.0, 2.0, 3.0))
+    // array<vec3<f32>, 2u>(vec3<f32>(1.0, 2.0, 3.0), vec3<f32>(1.0, 2.0, 3.0))
     //   -> true
 
     auto* first = vec3<f32>(1.f, 2.f, 3.f);
     auto* second = vec3<f32>(1.f, 2.f, 3.f);
 
-    auto* t = Construct(ty.array(ty.vec3<f32>(), 2), first, second);
+    auto* t = Construct(ty.array(ty.vec3<f32>(), 2_u), first, second);
     WrapInFunction(t);
 
     spirv::Builder& b = Build();
@@ -1783,7 +1785,7 @@
 TEST_F(SpvBuilderConstructorTest, IsConstructorConst_VectorWithTypeConversionConstConstructors) {
     // vec2<f32>(f32(1), f32(2))  -> false
 
-    auto* t = vec2<f32>(Construct<f32>(1), Construct<f32>(2));
+    auto* t = vec2<f32>(Construct<f32>(1_i), Construct<f32>(2_i));
     WrapInFunction(t);
 
     spirv::Builder& b = Build();
@@ -1793,7 +1795,7 @@
 }
 
 TEST_F(SpvBuilderConstructorTest, IsConstructorConst_BitCastScalars) {
-    auto* t = vec2<u32>(Construct<u32>(1), Construct<u32>(1));
+    auto* t = vec2<u32>(Construct<u32>(1_i), Construct<u32>(1_i));
     WrapInFunction(t);
 
     spirv::Builder& b = Build();
diff --git a/src/tint/writer/spirv/builder_entry_point_test.cc b/src/tint/writer/spirv/builder_entry_point_test.cc
index 2f7dc82..a38bb8e 100644
--- a/src/tint/writer/spirv/builder_entry_point_test.cc
+++ b/src/tint/writer/spirv/builder_entry_point_test.cc
@@ -29,6 +29,8 @@
 #include "src/tint/writer/spirv/spv_dump.h"
 #include "src/tint/writer/spirv/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::spirv {
 namespace {
 
@@ -113,7 +115,7 @@
     // }
     auto* loc_in = Param("loc_in", ty.u32(), {Location(0), Flat()});
     auto* cond =
-        create<ast::BinaryExpression>(ast::BinaryOp::kGreaterThan, Expr("loc_in"), Expr(10u));
+        create<ast::BinaryExpression>(ast::BinaryOp::kGreaterThan, Expr("loc_in"), Expr(10_u));
     Func("frag_main", ast::VariableList{loc_in}, ty.f32(),
          ast::StatementList{
              If(cond, Block(Return(0.5f))),
diff --git a/src/tint/writer/spirv/builder_function_attribute_test.cc b/src/tint/writer/spirv/builder_function_attribute_test.cc
index 8fa7b12..f4fdf6e 100644
--- a/src/tint/writer/spirv/builder_function_attribute_test.cc
+++ b/src/tint/writer/spirv/builder_function_attribute_test.cc
@@ -17,6 +17,8 @@
 #include "src/tint/writer/spirv/spv_dump.h"
 #include "src/tint/writer/spirv/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::spirv {
 namespace {
 
@@ -62,7 +64,7 @@
 
     auto deco_list = ast::AttributeList{Stage(params.stage)};
     if (params.stage == ast::PipelineStage::kCompute) {
-        deco_list.push_back(WorkgroupSize(1));
+        deco_list.push_back(WorkgroupSize(1_i));
     }
 
     auto* func = Func("main", {}, ret_type, body, deco_list, ret_type_attrs);
@@ -104,7 +106,7 @@
 
 TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_Default) {
     auto* func = Func("main", {}, ty.void_(), ast::StatementList{},
-                      ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+                      ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
 
     spirv::Builder& b = Build();
 
@@ -117,7 +119,7 @@
 TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_Literals) {
     auto* func = Func("main", {}, ty.void_(), ast::StatementList{},
                       ast::AttributeList{
-                          WorkgroupSize(2, 4, 6),
+                          WorkgroupSize(2_i, 4_i, 6_i),
                           Stage(ast::PipelineStage::kCompute),
                       });
 
@@ -130,9 +132,9 @@
 }
 
 TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_Const) {
-    GlobalConst("width", ty.i32(), Construct(ty.i32(), 2));
-    GlobalConst("height", ty.i32(), Construct(ty.i32(), 3));
-    GlobalConst("depth", ty.i32(), Construct(ty.i32(), 4));
+    GlobalConst("width", ty.i32(), Construct(ty.i32(), 2_i));
+    GlobalConst("height", ty.i32(), Construct(ty.i32(), 3_i));
+    GlobalConst("depth", ty.i32(), Construct(ty.i32(), 4_i));
     auto* func = Func("main", {}, ty.void_(), ast::StatementList{},
                       ast::AttributeList{
                           WorkgroupSize("width", "height", "depth"),
@@ -148,9 +150,9 @@
 }
 
 TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_OverridableConst) {
-    Override("width", ty.i32(), Construct(ty.i32(), 2), {Id(7u)});
-    Override("height", ty.i32(), Construct(ty.i32(), 3), {Id(8u)});
-    Override("depth", ty.i32(), Construct(ty.i32(), 4), {Id(9u)});
+    Override("width", ty.i32(), Construct(ty.i32(), 2_i), {Id(7u)});
+    Override("height", ty.i32(), Construct(ty.i32(), 3_i), {Id(8u)});
+    Override("depth", ty.i32(), Construct(ty.i32(), 4_i), {Id(9u)});
     auto* func = Func("main", {}, ty.void_(), ast::StatementList{},
                       ast::AttributeList{
                           WorkgroupSize("width", "height", "depth"),
@@ -178,11 +180,11 @@
 }
 
 TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_LiteralAndConst) {
-    Override("height", ty.i32(), Construct(ty.i32(), 2), {Id(7u)});
-    GlobalConst("depth", ty.i32(), Construct(ty.i32(), 3));
+    Override("height", ty.i32(), Construct(ty.i32(), 2_i), {Id(7u)});
+    GlobalConst("depth", ty.i32(), Construct(ty.i32(), 3_i));
     auto* func = Func("main", {}, ty.void_(), ast::StatementList{},
                       ast::AttributeList{
-                          WorkgroupSize(4, "height", "depth"),
+                          WorkgroupSize(4_i, "height", "depth"),
                           Stage(ast::PipelineStage::kCompute),
                       });
 
diff --git a/src/tint/writer/spirv/builder_function_test.cc b/src/tint/writer/spirv/builder_function_test.cc
index 32e87ba..fdb6a34 100644
--- a/src/tint/writer/spirv/builder_function_test.cc
+++ b/src/tint/writer/spirv/builder_function_test.cc
@@ -16,6 +16,8 @@
 #include "src/tint/writer/spirv/spv_dump.h"
 #include "src/tint/writer/spirv/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::spirv {
 namespace {
 
@@ -210,7 +212,7 @@
                  Decl(var),
                  Return(),
              },
-             ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+             ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
     }
 
     {
@@ -221,7 +223,7 @@
                  Decl(var),
                  Return(),
              },
-             ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
+             ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
     }
 
     spirv::Builder& b = SanitizeAndBuild();
diff --git a/src/tint/writer/spirv/builder_ident_expression_test.cc b/src/tint/writer/spirv/builder_ident_expression_test.cc
index d719a4e..540b5c1 100644
--- a/src/tint/writer/spirv/builder_ident_expression_test.cc
+++ b/src/tint/writer/spirv/builder_ident_expression_test.cc
@@ -15,6 +15,8 @@
 #include "src/tint/writer/spirv/spv_dump.h"
 #include "src/tint/writer/spirv/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::spirv {
 namespace {
 
@@ -136,7 +138,7 @@
 }
 
 TEST_F(BuilderTest, IdentifierExpression_NoLoadConst) {
-    auto* var = GlobalConst("var", ty.i32(), Expr(2));
+    auto* var = GlobalConst("var", ty.i32(), Expr(2_i));
 
     auto* expr = Add("var", "var");
     WrapInFunction(expr);
diff --git a/src/tint/writer/spirv/builder_if_test.cc b/src/tint/writer/spirv/builder_if_test.cc
index 17a2f50..a32f409 100644
--- a/src/tint/writer/spirv/builder_if_test.cc
+++ b/src/tint/writer/spirv/builder_if_test.cc
@@ -15,6 +15,8 @@
 #include "src/tint/writer/spirv/spv_dump.h"
 #include "src/tint/writer/spirv/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::spirv {
 namespace {
 
@@ -67,7 +69,7 @@
     // }
 
     auto* var = Global("v", ty.i32(), ast::StorageClass::kPrivate);
-    auto* body = Block(Assign("v", 2));
+    auto* body = Block(Assign("v", 2_i));
     auto* expr = If(true, body);
     WrapInFunction(expr);
 
@@ -97,14 +99,14 @@
 
 TEST_F(BuilderTest, If_WithElse) {
     // if (true) {
-    //   v = 2;
+    //   v = 2i;
     // } else {
-    //   v = 3;
+    //   v = 3i;
     // }
 
     auto* var = Global("v", ty.i32(), ast::StorageClass::kPrivate);
-    auto* body = Block(Assign("v", 2));
-    auto* else_body = Block(Assign("v", 3));
+    auto* body = Block(Assign("v", 2_i));
+    auto* else_body = Block(Assign("v", 3_i));
 
     auto* expr = If(true, body, Else(else_body));
     WrapInFunction(expr);
@@ -139,14 +141,14 @@
 
 TEST_F(BuilderTest, If_WithElseIf) {
     // if (true) {
-    //   v = 2;
+    //   v = 2i;
     // } else if (true) {
-    //   v = 3;
+    //   v = 3i;
     // }
 
     auto* var = Global("v", ty.i32(), ast::StorageClass::kPrivate);
-    auto* body = Block(Assign("v", 2));
-    auto* else_body = Block(Assign("v", 3));
+    auto* body = Block(Assign("v", 2_i));
+    auto* else_body = Block(Assign("v", 3_i));
 
     auto* expr = If(true, body, Else(If(true, else_body)));
     WrapInFunction(expr);
@@ -186,20 +188,20 @@
 
 TEST_F(BuilderTest, If_WithMultiple) {
     // if (true) {
-    //   v = 2;
+    //   v = 2i;
     // } else if (true) {
-    //   v = 3;
+    //   v = 3i;
     // } else if (false) {
-    //   v = 4;
+    //   v = 4i;
     // } else {
-    //   v = 5;
+    //   v = 5i;
     // }
 
     auto* var = Global("v", ty.i32(), ast::StorageClass::kPrivate);
-    auto* body = Block(Assign("v", 2));
-    auto* elseif_1_body = Block(Assign("v", 3));
-    auto* elseif_2_body = Block(Assign("v", 4));
-    auto* else_body = Block(Assign("v", 5));
+    auto* body = Block(Assign("v", 2_i));
+    auto* elseif_1_body = Block(Assign("v", 3_i));
+    auto* elseif_2_body = Block(Assign("v", 4_i));
+    auto* else_body = Block(Assign("v", 5_i));
 
     auto* expr = If(true, body,                            //
                     Else(If(true, elseif_1_body,           //
diff --git a/src/tint/writer/spirv/builder_literal_test.cc b/src/tint/writer/spirv/builder_literal_test.cc
index a23713c..d8a0311 100644
--- a/src/tint/writer/spirv/builder_literal_test.cc
+++ b/src/tint/writer/spirv/builder_literal_test.cc
@@ -15,6 +15,8 @@
 #include "src/tint/writer/spirv/spv_dump.h"
 #include "src/tint/writer/spirv/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::spirv {
 
 using BuilderTest = TestHelper;
@@ -70,7 +72,7 @@
 }
 
 TEST_F(BuilderTest, Literal_I32) {
-    auto* i = Expr(-23);
+    auto* i = Expr(i32(-23));
     WrapInFunction(i);
     spirv::Builder& b = Build();
 
@@ -84,8 +86,8 @@
 }
 
 TEST_F(BuilderTest, Literal_I32_Dedup) {
-    auto* i1 = Expr(-23);
-    auto* i2 = Expr(-23);
+    auto* i1 = Expr(i32(-23));
+    auto* i2 = Expr(i32(-23));
     WrapInFunction(i1, i2);
 
     spirv::Builder& b = Build();
@@ -100,7 +102,7 @@
 }
 
 TEST_F(BuilderTest, Literal_U32) {
-    auto* i = Expr(23u);
+    auto* i = Expr(23_u);
     WrapInFunction(i);
 
     spirv::Builder& b = Build();
@@ -115,8 +117,8 @@
 }
 
 TEST_F(BuilderTest, Literal_U32_Dedup) {
-    auto* i1 = Expr(23u);
-    auto* i2 = Expr(23u);
+    auto* i1 = Expr(23_u);
+    auto* i2 = Expr(23_u);
     WrapInFunction(i1, i2);
 
     spirv::Builder& b = Build();
diff --git a/src/tint/writer/spirv/builder_loop_test.cc b/src/tint/writer/spirv/builder_loop_test.cc
index 5532f6a..b4c2baa 100644
--- a/src/tint/writer/spirv/builder_loop_test.cc
+++ b/src/tint/writer/spirv/builder_loop_test.cc
@@ -15,6 +15,8 @@
 #include "src/tint/writer/spirv/spv_dump.h"
 #include "src/tint/writer/spirv/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::spirv {
 namespace {
 
@@ -48,12 +50,12 @@
 
 TEST_F(BuilderTest, Loop_WithoutContinuing) {
     // loop {
-    //   v = 2;
+    //   v = 2i;
     //   break;
     // }
 
     auto* var = Global("v", ty.i32(), ast::StorageClass::kPrivate);
-    auto* body = Block(Assign("v", 2),  //
+    auto* body = Block(Assign("v", 2_i),  //
                        Break());
 
     auto* loop = Loop(body, Block());
@@ -87,17 +89,17 @@
 
 TEST_F(BuilderTest, Loop_WithContinuing) {
     // loop {
-    //   a = 2;
+    //   a = 2i;
     //   break;
     //   continuing {
-    //     a = 3;
+    //     a = 3i;
     //   }
     // }
 
     auto* var = Global("v", ty.i32(), ast::StorageClass::kPrivate);
-    auto* body = Block(Assign("v", 2),  //
+    auto* body = Block(Assign("v", 2_i),  //
                        Break());
-    auto* continuing = Block(Assign("v", 3));
+    auto* continuing = Block(Assign("v", 3_i));
 
     auto* loop = Loop(body, continuing);
     WrapInFunction(loop);
@@ -135,13 +137,13 @@
     //   var a : i32;
     //   break;
     //   continuing {
-    //     a = 3;
+    //     a = 3i;
     //   }
     // }
 
     auto* body = Block(Decl(Var("a", ty.i32())),  //
                        Break());
-    auto* continuing = Block(Assign("a", 3));
+    auto* continuing = Block(Assign("a", 3_i));
 
     auto* loop = Loop(body, continuing);
     WrapInFunction(loop);
diff --git a/src/tint/writer/spirv/builder_switch_test.cc b/src/tint/writer/spirv/builder_switch_test.cc
index 12bfa7a..7ddd1bd 100644
--- a/src/tint/writer/spirv/builder_switch_test.cc
+++ b/src/tint/writer/spirv/builder_switch_test.cc
@@ -16,17 +16,19 @@
 #include "src/tint/writer/spirv/spv_dump.h"
 #include "src/tint/writer/spirv/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::spirv {
 namespace {
 
 using BuilderTest = TestHelper;
 
 TEST_F(BuilderTest, Switch_Empty) {
-    // switch (1) {
+    // switch (1i) {
     //   default: {}
     // }
 
-    auto* expr = Switch(1, DefaultCase());
+    auto* expr = Switch(1_i, DefaultCase());
     WrapInFunction(expr);
 
     spirv::Builder& b = Build();
@@ -48,10 +50,10 @@
 
 TEST_F(BuilderTest, Switch_WithCase) {
     // switch(a) {
-    //   case 1:
-    //     v = 1;
-    //   case 2:
-    //     v = 2;
+    //   case 1i:
+    //     v = 1i;
+    //   case 2i:
+    //     v = 2i;
     //   default: {}
     // }
 
@@ -60,9 +62,9 @@
 
     auto* func = Func("a_func", {}, ty.void_(),
                       {
-                          Switch("a",                                   //
-                                 Case(Expr(1), Block(Assign("v", 1))),  //
-                                 Case(Expr(2), Block(Assign("v", 2))),  //
+                          Switch("a",                                       //
+                                 Case(Expr(1_i), Block(Assign("v", 1_i))),  //
+                                 Case(Expr(2_i), Block(Assign("v", 2_i))),  //
                                  DefaultCase()),
                       });
 
@@ -106,9 +108,9 @@
 TEST_F(BuilderTest, Switch_WithCase_Unsigned) {
     // switch(a) {
     //   case 1u:
-    //     v = 1;
+    //     v = 1i;
     //   case 2u:
-    //     v = 2;
+    //     v = 2i;
     //   default: {}
     // }
 
@@ -117,9 +119,9 @@
 
     auto* func = Func("a_func", {}, ty.void_(),
                       {
-                          Switch("a",                                    //
-                                 Case(Expr(1u), Block(Assign("v", 1))),  //
-                                 Case(Expr(2u), Block(Assign("v", 2))),  //
+                          Switch("a",                                       //
+                                 Case(Expr(1_u), Block(Assign("v", 1_i))),  //
+                                 Case(Expr(2_u), Block(Assign("v", 2_i))),  //
                                  DefaultCase()),
                       });
 
@@ -166,7 +168,7 @@
 TEST_F(BuilderTest, Switch_WithDefault) {
     // switch(true) {
     //   default: {}
-    //     v = 1;
+    //     v = 1i;
     //  }
 
     auto* v = Global("v", ty.i32(), ast::StorageClass::kPrivate);
@@ -174,8 +176,8 @@
 
     auto* func = Func("a_func", {}, ty.void_(),
                       {
-                          Switch("a",                                  //
-                                 DefaultCase(Block(Assign("v", 1)))),  //
+                          Switch("a",                                    //
+                                 DefaultCase(Block(Assign("v", 1_i)))),  //
                       });
 
     spirv::Builder& b = Build();
@@ -211,12 +213,12 @@
 
 TEST_F(BuilderTest, Switch_WithCaseAndDefault) {
     // switch(a) {
-    //   case 1:
-    //      v = 1;
-    //   case 2, 3:
-    //      v = 2;
+    //   case 1i:
+    //      v = 1i;
+    //   case 2i, 3i:
+    //      v = 2i;
     //   default: {}
-    //      v = 3;
+    //      v = 3i;
     //  }
 
     auto* v = Global("v", ty.i32(), ast::StorageClass::kPrivate);
@@ -224,12 +226,12 @@
 
     auto* func = Func("a_func", {}, ty.void_(),
                       {
-                          Switch(Expr("a"),                    //
-                                 Case(Expr(1),                 //
-                                      Block(Assign("v", 1))),  //
-                                 Case({Expr(2), Expr(3)},      //
-                                      Block(Assign("v", 2))),  //
-                                 DefaultCase(Block(Assign("v", 3)))),
+                          Switch(Expr("a"),                      //
+                                 Case(Expr(1_i),                 //
+                                      Block(Assign("v", 1_i))),  //
+                                 Case({Expr(2_i), Expr(3_i)},    //
+                                      Block(Assign("v", 2_i))),  //
+                                 DefaultCase(Block(Assign("v", 3_i)))),
                       });
 
     spirv::Builder& b = Build();
@@ -273,13 +275,13 @@
 
 TEST_F(BuilderTest, Switch_CaseWithFallthrough) {
     // switch(a) {
-    //   case 1:
-    //      v = 1;
+    //   case 1i:
+    //      v = 1i;
     //      fallthrough;
-    //   case 2:
-    //      v = 2;
+    //   case 2i:
+    //      v = 2i;
     //   default: {}
-    //      v = 3;
+    //      v = 3i;
     //  }
 
     auto* v = Global("v", ty.i32(), ast::StorageClass::kPrivate);
@@ -287,12 +289,12 @@
 
     auto* func = Func("a_func", {}, ty.void_(),
                       {
-                          Switch(Expr("a"),                                   //
-                                 Case(Expr(1),                                //
-                                      Block(Assign("v", 1), Fallthrough())),  //
-                                 Case(Expr(2),                                //
-                                      Block(Assign("v", 2))),                 //
-                                 DefaultCase(Block(Assign("v", 3)))),
+                          Switch(Expr("a"),                                     //
+                                 Case(Expr(1_i),                                //
+                                      Block(Assign("v", 1_i), Fallthrough())),  //
+                                 Case(Expr(2_i),                                //
+                                      Block(Assign("v", 2_i))),                 //
+                                 DefaultCase(Block(Assign("v", 3_i)))),
                       });
 
     spirv::Builder& b = Build();
@@ -340,22 +342,22 @@
     //     if (true) {
     //       break;
     //     }
-    //     v = 1;
+    //     v = 1i;
     //   default: {}
     // }
 
     auto* v = Global("v", ty.i32(), ast::StorageClass::kPrivate);
     auto* a = Global("a", ty.i32(), ast::StorageClass::kPrivate);
 
-    auto* func = Func(
-        "a_func", {}, ty.void_(),
-        {
-            Switch("a",           //
-                   Case(Expr(1),  //
-                        Block(    //
-                            If(Expr(true), Block(create<ast::BreakStatement>())), Assign("v", 1))),
-                   DefaultCase()),
-        });
+    auto* func = Func("a_func", {}, ty.void_(),
+                      {
+                          Switch("a",             //
+                                 Case(Expr(1_i),  //
+                                      Block(      //
+                                          If(Expr(true), Block(create<ast::BreakStatement>())),
+                                          Assign("v", 1_i))),
+                                 DefaultCase()),
+                      });
 
     spirv::Builder& b = Build();
 
@@ -398,24 +400,24 @@
 }
 
 TEST_F(BuilderTest, Switch_AllReturn) {
-    // switch (1) {
-    //   case 1: {
-    //     return 1;
+    // switch (1i) {
+    //   case 1i: {
+    //     return 1i;
     //   }
-    //   case 2: {
+    //   case 2i: {
     //     fallthrough;
     //   }
     //   default: {
-    //     return 3;
+    //     return 3i;
     //   }
     // }
 
     auto* fn = Func("f", {}, ty.i32(),
                     {
-                        Switch(1,                                    //
-                               Case(Expr(1), Block(Return(1))),      //
-                               Case(Expr(2), Block(Fallthrough())),  //
-                               DefaultCase(Block(Return(3)))),
+                        Switch(1_i,                                    //
+                               Case(Expr(1_i), Block(Return(1_i))),    //
+                               Case(Expr(2_i), Block(Fallthrough())),  //
+                               DefaultCase(Block(Return(3_i)))),
                     });
 
     spirv::Builder& b = Build();
diff --git a/src/tint/writer/spirv/builder_type_test.cc b/src/tint/writer/spirv/builder_type_test.cc
index 4e4cf5b..8dc048e 100644
--- a/src/tint/writer/spirv/builder_type_test.cc
+++ b/src/tint/writer/spirv/builder_type_test.cc
@@ -18,6 +18,8 @@
 #include "src/tint/writer/spirv/spv_dump.h"
 #include "src/tint/writer/spirv/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::spirv {
 namespace {
 
@@ -64,7 +66,7 @@
 }
 
 TEST_F(BuilderTest_Type, GenerateArray) {
-    auto* ary = ty.array(ty.i32(), 4);
+    auto* ary = ty.array(ty.i32(), 4_u);
     Global("a", ary, ast::StorageClass::kPrivate);
 
     spirv::Builder& b = Build();
@@ -81,7 +83,7 @@
 }
 
 TEST_F(BuilderTest_Type, GenerateArray_WithStride) {
-    auto* ary = ty.array(ty.i32(), 4, 16u);
+    auto* ary = ty.array(ty.i32(), 4_u, 16u);
     Global("a", ary, ast::StorageClass::kPrivate);
 
     spirv::Builder& b = Build();
@@ -101,7 +103,7 @@
 }
 
 TEST_F(BuilderTest_Type, ReturnsGeneratedArray) {
-    auto* ary = ty.array(ty.i32(), 4);
+    auto* ary = ty.array(ty.i32(), 4_u);
     Global("a", ary, ast::StorageClass::kPrivate);
 
     spirv::Builder& b = Build();
@@ -383,9 +385,9 @@
     // We have to infer layout for matrix when it also has an offset.
     // The decoration goes on the struct member, even if the matrix is buried
     // in levels of arrays.
-    auto* arr_mat2x2 = ty.array(ty.mat2x2<f32>(), 1);      // Singly nested array
-    auto* arr_arr_mat2x3 = ty.array(ty.mat2x3<f32>(), 1);  // Doubly nested array
-    auto* rtarr_mat4x4 = ty.array(ty.mat4x4<f32>());       // Runtime array
+    auto* arr_mat2x2 = ty.array(ty.mat2x2<f32>(), 1_u);      // Singly nested array
+    auto* arr_arr_mat2x3 = ty.array(ty.mat2x3<f32>(), 1_u);  // Doubly nested array
+    auto* rtarr_mat4x4 = ty.array(ty.mat4x4<f32>());         // Runtime array
 
     auto* s = Structure("S", {
                                  Member("a", arr_mat2x2),
diff --git a/src/tint/writer/spirv/builder_unary_op_expression_test.cc b/src/tint/writer/spirv/builder_unary_op_expression_test.cc
index 4c82e35..c34ae32 100644
--- a/src/tint/writer/spirv/builder_unary_op_expression_test.cc
+++ b/src/tint/writer/spirv/builder_unary_op_expression_test.cc
@@ -15,13 +15,15 @@
 #include "src/tint/writer/spirv/spv_dump.h"
 #include "src/tint/writer/spirv/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::spirv {
 namespace {
 
 using BuilderTest = TestHelper;
 
 TEST_F(BuilderTest, UnaryOp_Negation_Integer) {
-    auto* expr = create<ast::UnaryOpExpression>(ast::UnaryOp::kNegation, Expr(1));
+    auto* expr = create<ast::UnaryOpExpression>(ast::UnaryOp::kNegation, Expr(1_i));
     WrapInFunction(expr);
 
     spirv::Builder& b = Build();
@@ -53,7 +55,7 @@
 }
 
 TEST_F(BuilderTest, UnaryOp_Complement) {
-    auto* expr = create<ast::UnaryOpExpression>(ast::UnaryOp::kComplement, Expr(1));
+    auto* expr = create<ast::UnaryOpExpression>(ast::UnaryOp::kComplement, Expr(1_i));
     WrapInFunction(expr);
 
     spirv::Builder& b = Build();
diff --git a/src/tint/writer/wgsl/generator_impl_array_accessor_test.cc b/src/tint/writer/wgsl/generator_impl_array_accessor_test.cc
index 9648584..2b4e8b4 100644
--- a/src/tint/writer/wgsl/generator_impl_array_accessor_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_array_accessor_test.cc
@@ -14,6 +14,8 @@
 
 #include "src/tint/writer/wgsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::wgsl {
 namespace {
 
@@ -21,28 +23,28 @@
 
 TEST_F(WgslGeneratorImplTest, IndexAccessor) {
     Global("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
-    auto* expr = IndexAccessor("ary", 5);
+    auto* expr = IndexAccessor("ary", 5_i);
     WrapInFunction(expr);
 
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
     ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
-    EXPECT_EQ(out.str(), "ary[5]");
+    EXPECT_EQ(out.str(), "ary[5i]");
 }
 
 TEST_F(WgslGeneratorImplTest, IndexAccessor_OfDref) {
     Global("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
 
     auto* p = Let("p", nullptr, AddressOf("ary"));
-    auto* expr = IndexAccessor(Deref("p"), 5);
+    auto* expr = IndexAccessor(Deref("p"), 5_i);
     WrapInFunction(p, expr);
 
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
     ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
-    EXPECT_EQ(out.str(), "(*(p))[5]");
+    EXPECT_EQ(out.str(), "(*(p))[5i]");
 }
 
 }  // namespace
diff --git a/src/tint/writer/wgsl/generator_impl_bitcast_test.cc b/src/tint/writer/wgsl/generator_impl_bitcast_test.cc
index 754743b..c71a8d1 100644
--- a/src/tint/writer/wgsl/generator_impl_bitcast_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_bitcast_test.cc
@@ -14,20 +14,22 @@
 
 #include "src/tint/writer/wgsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::wgsl {
 namespace {
 
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, EmitExpression_Bitcast) {
-    auto* bitcast = create<ast::BitcastExpression>(ty.f32(), Expr(1));
+    auto* bitcast = create<ast::BitcastExpression>(ty.f32(), Expr(1_i));
     WrapInFunction(bitcast);
 
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
     ASSERT_TRUE(gen.EmitExpression(out, bitcast)) << gen.error();
-    EXPECT_EQ(out.str(), "bitcast<f32>(1)");
+    EXPECT_EQ(out.str(), "bitcast<f32>(1i)");
 }
 
 }  // namespace
diff --git a/src/tint/writer/wgsl/generator_impl_case_test.cc b/src/tint/writer/wgsl/generator_impl_case_test.cc
index dba1a5c..c12997e 100644
--- a/src/tint/writer/wgsl/generator_impl_case_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_case_test.cc
@@ -14,13 +14,15 @@
 
 #include "src/tint/writer/wgsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::wgsl {
 namespace {
 
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, Emit_Case) {
-    auto* s = Switch(1, Case(Expr(5), Block(create<ast::BreakStatement>())), DefaultCase());
+    auto* s = Switch(1_i, Case(Expr(5_i), Block(create<ast::BreakStatement>())), DefaultCase());
     WrapInFunction(s);
 
     GeneratorImpl& gen = Build();
@@ -28,15 +30,15 @@
     gen.increment_indent();
 
     ASSERT_TRUE(gen.EmitCase(s->body[0])) << gen.error();
-    EXPECT_EQ(gen.result(), R"(  case 5: {
+    EXPECT_EQ(gen.result(), R"(  case 5i: {
     break;
   }
 )");
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_Case_MultipleSelectors) {
-    auto* s =
-        Switch(1, Case({Expr(5), Expr(6)}, Block(create<ast::BreakStatement>())), DefaultCase());
+    auto* s = Switch(1_i, Case({Expr(5_i), Expr(6_i)}, Block(create<ast::BreakStatement>())),
+                     DefaultCase());
     WrapInFunction(s);
 
     GeneratorImpl& gen = Build();
@@ -44,14 +46,14 @@
     gen.increment_indent();
 
     ASSERT_TRUE(gen.EmitCase(s->body[0])) << gen.error();
-    EXPECT_EQ(gen.result(), R"(  case 5, 6: {
+    EXPECT_EQ(gen.result(), R"(  case 5i, 6i: {
     break;
   }
 )");
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_Case_Default) {
-    auto* s = Switch(1, DefaultCase(Block(create<ast::BreakStatement>())));
+    auto* s = Switch(1_i, DefaultCase(Block(create<ast::BreakStatement>())));
     WrapInFunction(s);
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/wgsl/generator_impl_cast_test.cc b/src/tint/writer/wgsl/generator_impl_cast_test.cc
index 97eb753..c423943 100644
--- a/src/tint/writer/wgsl/generator_impl_cast_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_cast_test.cc
@@ -14,31 +14,33 @@
 
 #include "src/tint/writer/wgsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::wgsl {
 namespace {
 
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, EmitExpression_Cast_Scalar) {
-    auto* cast = Construct<f32>(1);
+    auto* cast = Construct<f32>(1_i);
     WrapInFunction(cast);
 
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
     ASSERT_TRUE(gen.EmitExpression(out, cast)) << gen.error();
-    EXPECT_EQ(out.str(), "f32(1)");
+    EXPECT_EQ(out.str(), "f32(1i)");
 }
 
 TEST_F(WgslGeneratorImplTest, EmitExpression_Cast_Vector) {
-    auto* cast = vec3<f32>(vec3<i32>(1, 2, 3));
+    auto* cast = vec3<f32>(vec3<i32>(1_i, 2_i, 3_i));
     WrapInFunction(cast);
 
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
     ASSERT_TRUE(gen.EmitExpression(out, cast)) << gen.error();
-    EXPECT_EQ(out.str(), "vec3<f32>(vec3<i32>(1, 2, 3))");
+    EXPECT_EQ(out.str(), "vec3<f32>(vec3<i32>(1i, 2i, 3i))");
 }
 
 }  // namespace
diff --git a/src/tint/writer/wgsl/generator_impl_constructor_test.cc b/src/tint/writer/wgsl/generator_impl_constructor_test.cc
index 906e182..3fbf3f1 100644
--- a/src/tint/writer/wgsl/generator_impl_constructor_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_constructor_test.cc
@@ -15,11 +15,13 @@
 #include "gmock/gmock.h"
 #include "src/tint/writer/wgsl/test_helper.h"
 
+using ::testing::HasSubstr;
+
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::wgsl {
 namespace {
 
-using ::testing::HasSubstr;
-
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Bool) {
@@ -32,7 +34,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Int) {
-    WrapInFunction(Expr(-12345));
+    WrapInFunction(Expr(i32(-12345)));
 
     GeneratorImpl& gen = Build();
 
@@ -41,7 +43,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitConstructor_UInt) {
-    WrapInFunction(Expr(56779u));
+    WrapInFunction(Expr(56779_u));
 
     GeneratorImpl& gen = Build();
 
@@ -51,7 +53,7 @@
 
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Float) {
     // Use a number close to 1<<30 but whose decimal representation ends in 0.
-    WrapInFunction(Expr(static_cast<float>((1 << 30) - 4)));
+    WrapInFunction(Expr(f32((1 << 30) - 4)));
 
     GeneratorImpl& gen = Build();
 
@@ -78,16 +80,16 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Int) {
-    WrapInFunction(Construct<i32>(-12345));
+    WrapInFunction(Construct<i32>(i32(-12345)));
 
     GeneratorImpl& gen = Build();
 
     ASSERT_TRUE(gen.Generate()) << gen.error();
-    EXPECT_THAT(gen.result(), HasSubstr("i32(-12345)"));
+    EXPECT_THAT(gen.result(), HasSubstr("i32(-12345i)"));
 }
 
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Uint) {
-    WrapInFunction(Construct<u32>(12345u));
+    WrapInFunction(Construct<u32>(12345_u));
 
     GeneratorImpl& gen = Build();
 
@@ -115,13 +117,13 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Array) {
-    WrapInFunction(Construct(ty.array(ty.vec3<f32>(), 3), vec3<f32>(1.0f, 2.0f, 3.0f),
+    WrapInFunction(Construct(ty.array(ty.vec3<f32>(), 3_u), vec3<f32>(1.0f, 2.0f, 3.0f),
                              vec3<f32>(4.0f, 5.0f, 6.0f), vec3<f32>(7.0f, 8.0f, 9.0f)));
 
     GeneratorImpl& gen = Build();
 
     ASSERT_TRUE(gen.Generate()) << gen.error();
-    EXPECT_THAT(gen.result(), HasSubstr("array<vec3<f32>, 3>(vec3<f32>(1.0, 2.0, 3.0), "
+    EXPECT_THAT(gen.result(), HasSubstr("array<vec3<f32>, 3u>(vec3<f32>(1.0, 2.0, 3.0), "
                                         "vec3<f32>(4.0, 5.0, 6.0), vec3<f32>(7.0, 8.0, 9.0))"));
 }
 
diff --git a/src/tint/writer/wgsl/generator_impl_fallthrough_test.cc b/src/tint/writer/wgsl/generator_impl_fallthrough_test.cc
index d629394..2b12051 100644
--- a/src/tint/writer/wgsl/generator_impl_fallthrough_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_fallthrough_test.cc
@@ -14,6 +14,8 @@
 
 #include "src/tint/writer/wgsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::wgsl {
 namespace {
 
@@ -21,8 +23,8 @@
 
 TEST_F(WgslGeneratorImplTest, Emit_Fallthrough) {
     auto* f = create<ast::FallthroughStatement>();
-    WrapInFunction(Switch(1,                        //
-                          Case(Expr(1), Block(f)),  //
+    WrapInFunction(Switch(1_i,                        //
+                          Case(Expr(1_i), Block(f)),  //
                           DefaultCase()));
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/wgsl/generator_impl_function_test.cc b/src/tint/writer/wgsl/generator_impl_function_test.cc
index bdabbd1..79a95d5 100644
--- a/src/tint/writer/wgsl/generator_impl_function_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_function_test.cc
@@ -17,6 +17,8 @@
 #include "src/tint/ast/workgroup_attribute.h"
 #include "src/tint/writer/wgsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::wgsl {
 namespace {
 
@@ -63,7 +65,7 @@
     auto* func = Func("my_func", ast::VariableList{}, ty.void_(), ast::StatementList{Return()},
                       ast::AttributeList{
                           Stage(ast::PipelineStage::kCompute),
-                          WorkgroupSize(2, 4, 6),
+                          WorkgroupSize(2_i, 4_i, 6_i),
                       });
 
     GeneratorImpl& gen = Build();
@@ -71,7 +73,7 @@
     gen.increment_indent();
 
     ASSERT_TRUE(gen.EmitFunction(func));
-    EXPECT_EQ(gen.result(), R"(  @stage(compute) @workgroup_size(2, 4, 6)
+    EXPECT_EQ(gen.result(), R"(  @stage(compute) @workgroup_size(2i, 4i, 6i)
   fn my_func() {
     return;
   }
@@ -79,11 +81,11 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_Function_WithAttribute_WorkgroupSize_WithIdent) {
-    GlobalConst("height", ty.i32(), Expr(2));
+    GlobalConst("height", ty.i32(), Expr(2_i));
     auto* func = Func("my_func", ast::VariableList{}, ty.void_(), ast::StatementList{Return()},
                       ast::AttributeList{
                           Stage(ast::PipelineStage::kCompute),
-                          WorkgroupSize(2, "height"),
+                          WorkgroupSize(2_i, "height"),
                       });
 
     GeneratorImpl& gen = Build();
@@ -91,7 +93,7 @@
     gen.increment_indent();
 
     ASSERT_TRUE(gen.EmitFunction(func));
-    EXPECT_EQ(gen.result(), R"(  @stage(compute) @workgroup_size(2, height)
+    EXPECT_EQ(gen.result(), R"(  @stage(compute) @workgroup_size(2i, height)
   fn my_func() {
     return;
   }
@@ -177,7 +179,7 @@
              },
              ast::AttributeList{
                  Stage(ast::PipelineStage::kCompute),
-                 WorkgroupSize(1),
+                 WorkgroupSize(1_i),
              });
     }
 
@@ -191,7 +193,7 @@
              },
              ast::AttributeList{
                  Stage(ast::PipelineStage::kCompute),
-                 WorkgroupSize(1),
+                 WorkgroupSize(1_i),
              });
     }
 
@@ -204,13 +206,13 @@
 
 @binding(0) @group(0) var<storage, read_write> data : Data;
 
-@stage(compute) @workgroup_size(1)
+@stage(compute) @workgroup_size(1i)
 fn a() {
   var v : f32 = data.d;
   return;
 }
 
-@stage(compute) @workgroup_size(1)
+@stage(compute) @workgroup_size(1i)
 fn b() {
   var v : f32 = data.d;
   return;
diff --git a/src/tint/writer/wgsl/generator_impl_global_decl_test.cc b/src/tint/writer/wgsl/generator_impl_global_decl_test.cc
index d3051c7..8e1c9a6 100644
--- a/src/tint/writer/wgsl/generator_impl_global_decl_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_global_decl_test.cc
@@ -17,6 +17,8 @@
 #include "src/tint/sem/sampled_texture.h"
 #include "src/tint/writer/wgsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::wgsl {
 namespace {
 
@@ -33,7 +35,7 @@
     gen.increment_indent();
 
     ASSERT_TRUE(gen.Generate()) << gen.error();
-    EXPECT_EQ(gen.result(), R"(  @stage(compute) @workgroup_size(1, 1, 1)
+    EXPECT_EQ(gen.result(), R"(  @stage(compute) @workgroup_size(1i, 1i, 1i)
   fn test_function() {
     var a : f32;
   }
@@ -65,7 +67,7 @@
          },
          ast::AttributeList{
              Stage(ast::PipelineStage::kCompute),
-             WorkgroupSize(1),
+             WorkgroupSize(1_i),
          });
 
     GeneratorImpl& gen = Build();
@@ -89,7 +91,7 @@
     a : i32,
   }
 
-  @stage(compute) @workgroup_size(1)
+  @stage(compute) @workgroup_size(1i)
   fn main() {
     var s0 : S0;
     var s1 : S1;
diff --git a/src/tint/writer/wgsl/generator_impl_loop_test.cc b/src/tint/writer/wgsl/generator_impl_loop_test.cc
index 4fdc5fa..2d6a8f4 100644
--- a/src/tint/writer/wgsl/generator_impl_loop_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_loop_test.cc
@@ -14,6 +14,8 @@
 
 #include "src/tint/writer/wgsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::wgsl {
 namespace {
 
@@ -63,11 +65,11 @@
 
 TEST_F(WgslGeneratorImplTest, Emit_ForLoopWithMultiStmtInit) {
     // var<workgroup> a : atomic<i32>;
-    // for({ignore(1); ignore(2);}; ; ) {
+    // for({ignore(1i); ignore(2i);}; ; ) {
     //   return;
     // }
     Global("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
-    auto* multi_stmt = Block(Ignore(1), Ignore(2));
+    auto* multi_stmt = Block(Ignore(1_i), Ignore(2_i));
     auto* f = For(multi_stmt, nullptr, nullptr, Block(Return()));
     WrapInFunction(f);
 
@@ -77,8 +79,8 @@
 
     ASSERT_TRUE(gen.EmitStatement(f)) << gen.error();
     EXPECT_EQ(gen.result(), R"(  for({
-    _ = 1;
-    _ = 2;
+    _ = 1i;
+    _ = 2i;
   }; ; ) {
     return;
   }
@@ -105,12 +107,12 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_ForLoopWithSimpleCont) {
-    // for(; ; i = i + 1) {
+    // for(; ; i = i + 1i) {
     //   return;
     // }
 
     auto* v = Decl(Var("i", ty.i32()));
-    auto* f = For(nullptr, nullptr, Assign("i", Add("i", 1)), Block(Return()));
+    auto* f = For(nullptr, nullptr, Assign("i", Add("i", 1_i)), Block(Return()));
     WrapInFunction(v, f);
 
     GeneratorImpl& gen = Build();
@@ -118,7 +120,7 @@
     gen.increment_indent();
 
     ASSERT_TRUE(gen.EmitStatement(f)) << gen.error();
-    EXPECT_EQ(gen.result(), R"(  for(; ; i = (i + 1)) {
+    EXPECT_EQ(gen.result(), R"(  for(; ; i = (i + 1i)) {
     return;
   }
 )");
@@ -126,12 +128,12 @@
 
 TEST_F(WgslGeneratorImplTest, Emit_ForLoopWithMultiStmtCont) {
     // var<workgroup> a : atomic<i32>;
-    // for(; ; { ignore(1); ignore(2); }) {
+    // for(; ; { ignore(1i); ignore(2i); }) {
     //   return;
     // }
 
     Global("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
-    auto* multi_stmt = Block(Ignore(1), Ignore(2));
+    auto* multi_stmt = Block(Ignore(1_i), Ignore(2_i));
     auto* f = For(nullptr, nullptr, multi_stmt, Block(Return()));
     WrapInFunction(f);
 
@@ -141,8 +143,8 @@
 
     ASSERT_TRUE(gen.EmitStatement(f)) << gen.error();
     EXPECT_EQ(gen.result(), R"(  for(; ; {
-    _ = 1;
-    _ = 2;
+    _ = 1i;
+    _ = 2i;
   }) {
     return;
   }
@@ -150,11 +152,11 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_ForLoopWithSimpleInitCondCont) {
-    // for(var i : i32; true; i = i + 1) {
+    // for(var i : i32; true; i = i + 1i) {
     //   return;
     // }
 
-    auto* f = For(Decl(Var("i", ty.i32())), true, Assign("i", Add("i", 1)), Block(Return()));
+    auto* f = For(Decl(Var("i", ty.i32())), true, Assign("i", Add("i", 1_i)), Block(Return()));
     WrapInFunction(f);
 
     GeneratorImpl& gen = Build();
@@ -162,7 +164,7 @@
     gen.increment_indent();
 
     ASSERT_TRUE(gen.EmitStatement(f)) << gen.error();
-    EXPECT_EQ(gen.result(), R"(  for(var i : i32; true; i = (i + 1)) {
+    EXPECT_EQ(gen.result(), R"(  for(var i : i32; true; i = (i + 1i)) {
     return;
   }
 )");
@@ -170,12 +172,12 @@
 
 TEST_F(WgslGeneratorImplTest, Emit_ForLoopWithMultiStmtInitCondCont) {
     // var<workgroup> a : atomic<i32>;
-    // for({ ignore(1); ignore(2); }; true; { ignore(3); ignore(4); }) {
+    // for({ ignore(1i); ignore(2i); }; true; { ignore(3i); ignore(4i); }) {
     //   return;
     // }
     Global("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
-    auto* multi_stmt_a = Block(Ignore(1), Ignore(2));
-    auto* multi_stmt_b = Block(Ignore(3), Ignore(4));
+    auto* multi_stmt_a = Block(Ignore(1_i), Ignore(2_i));
+    auto* multi_stmt_b = Block(Ignore(3_i), Ignore(4_i));
     auto* f = For(multi_stmt_a, Expr(true), multi_stmt_b, Block(Return()));
     WrapInFunction(f);
 
@@ -185,11 +187,11 @@
 
     ASSERT_TRUE(gen.EmitStatement(f)) << gen.error();
     EXPECT_EQ(gen.result(), R"(  for({
-    _ = 1;
-    _ = 2;
+    _ = 1i;
+    _ = 2i;
   }; true; {
-    _ = 3;
-    _ = 4;
+    _ = 3i;
+    _ = 4i;
   }) {
     return;
   }
diff --git a/src/tint/writer/wgsl/generator_impl_return_test.cc b/src/tint/writer/wgsl/generator_impl_return_test.cc
index cc384c7..ed1027d 100644
--- a/src/tint/writer/wgsl/generator_impl_return_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_return_test.cc
@@ -14,6 +14,8 @@
 
 #include "src/tint/writer/wgsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::wgsl {
 namespace {
 
@@ -32,7 +34,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_ReturnWithValue) {
-    auto* r = Return(123);
+    auto* r = Return(123_i);
     Func("f", {}, ty.i32(), {r});
 
     GeneratorImpl& gen = Build();
@@ -40,7 +42,7 @@
     gen.increment_indent();
 
     ASSERT_TRUE(gen.EmitStatement(r)) << gen.error();
-    EXPECT_EQ(gen.result(), "  return 123;\n");
+    EXPECT_EQ(gen.result(), "  return 123i;\n");
 }
 
 }  // namespace
diff --git a/src/tint/writer/wgsl/generator_impl_switch_test.cc b/src/tint/writer/wgsl/generator_impl_switch_test.cc
index 03e0a3f..11424f0 100644
--- a/src/tint/writer/wgsl/generator_impl_switch_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_switch_test.cc
@@ -14,6 +14,8 @@
 
 #include "src/tint/writer/wgsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::wgsl {
 namespace {
 
@@ -26,7 +28,7 @@
     auto* def = create<ast::CaseStatement>(ast::CaseSelectorList{}, def_body);
 
     ast::CaseSelectorList case_val;
-    case_val.push_back(Expr(5));
+    case_val.push_back(Expr(5_i));
 
     auto* case_body = Block(create<ast::BreakStatement>());
 
@@ -46,7 +48,7 @@
 
     ASSERT_TRUE(gen.EmitStatement(s)) << gen.error();
     EXPECT_EQ(gen.result(), R"(  switch(cond) {
-    case 5: {
+    case 5i: {
       break;
     }
     default: {
diff --git a/src/tint/writer/wgsl/generator_impl_type_test.cc b/src/tint/writer/wgsl/generator_impl_type_test.cc
index 3d8c43e..0973ffa 100644
--- a/src/tint/writer/wgsl/generator_impl_type_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_type_test.cc
@@ -17,6 +17,8 @@
 #include "src/tint/sem/sampled_texture.h"
 #include "src/tint/writer/wgsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::wgsl {
 namespace {
 
@@ -35,25 +37,25 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitType_Array) {
-    auto* arr = ty.array<bool, 4>();
+    auto* arr = ty.array<bool, 4u>();
     Alias("make_type_reachable", arr);
 
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
     ASSERT_TRUE(gen.EmitType(out, arr)) << gen.error();
-    EXPECT_EQ(out.str(), "array<bool, 4>");
+    EXPECT_EQ(out.str(), "array<bool, 4u>");
 }
 
 TEST_F(WgslGeneratorImplTest, EmitType_Array_Attribute) {
-    auto* a = ty.array(ty.bool_(), 4, 16u);
+    auto* a = ty.array(ty.bool_(), 4_u, 16u);
     Alias("make_type_reachable", a);
 
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
     ASSERT_TRUE(gen.EmitType(out, a)) << gen.error();
-    EXPECT_EQ(out.str(), "@stride(16) array<bool, 4>");
+    EXPECT_EQ(out.str(), "@stride(16) array<bool, 4u>");
 }
 
 TEST_F(WgslGeneratorImplTest, EmitType_RuntimeArray) {
diff --git a/src/tint/writer/wgsl/generator_impl_variable_decl_statement_test.cc b/src/tint/writer/wgsl/generator_impl_variable_decl_statement_test.cc
index 03bf3e5..a68932c 100644
--- a/src/tint/writer/wgsl/generator_impl_variable_decl_statement_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_variable_decl_statement_test.cc
@@ -15,6 +15,8 @@
 #include "src/tint/ast/variable_decl_statement.h"
 #include "src/tint/writer/wgsl/test_helper.h"
 
+using namespace tint::number_suffixes;  // NOLINT
+
 namespace tint::writer::wgsl {
 namespace {
 
@@ -35,7 +37,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_InferredType) {
-    auto* var = Var("a", nullptr, ast::StorageClass::kNone, Expr(123));
+    auto* var = Var("a", nullptr, ast::StorageClass::kNone, Expr(123_i));
 
     auto* stmt = Decl(var);
     WrapInFunction(stmt);
@@ -45,7 +47,7 @@
     gen.increment_indent();
 
     ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error();
-    EXPECT_EQ(gen.result(), "  var a = 123;\n");
+    EXPECT_EQ(gen.result(), "  var a = 123i;\n");
 }
 
 }  // namespace