Use type helpers.

Convert several places where we use the TypeManager::Get method to use
the specific type methods instead.

Change-Id: I78a4c57da5d7fc64b3221c4b10434f00e035a9b7
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/234515
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/tint/lang/core/intrinsic/type_matchers.h b/src/tint/lang/core/intrinsic/type_matchers.h
index adfad34..5fa3efe 100644
--- a/src/tint/lang/core/intrinsic/type_matchers.h
+++ b/src/tint/lang/core/intrinsic/type_matchers.h
@@ -201,7 +201,7 @@
 inline const type::Vector* BuildPackedVec3(intrinsic::MatchState& state,
                                            const type::Type*,
                                            const type::Type* el) {
-    return state.types.Get<type::Vector>(el, 3u, /* packed */ true);
+    return state.types.packed_vec(el, 3u);
 }
 
 inline bool MatchMat(intrinsic::MatchState&,
@@ -333,17 +333,7 @@
                                      const type::Type*,
                                      const type::Type* el,
                                      intrinsic::Number C) {
-    uint32_t el_align = el->Align();
-    uint32_t el_size = el->Size();
-    uint32_t stride = tint::RoundUp<uint32_t>(el_align, el_size);
-    uint32_t size = C.Value() * stride;
-    return state.types.Get<type::Array>(
-        el,
-        /* count */ state.types.Get<type::ConstantArrayCount>(C.Value()),
-        /* align */ el_align,
-        /* size */ size,
-        /* stride */ stride,
-        /* stride_implicit */ stride);
+    return state.types.array(el, C.Value());
 }
 
 inline bool MatchRuntimeArray(intrinsic::MatchState&, const type::Type* ty, const type::Type*& T) {
@@ -364,20 +354,14 @@
 inline const type::Array* BuildRuntimeArray(intrinsic::MatchState& state,
                                             const type::Type*,
                                             const type::Type* el) {
-    return state.types.Get<type::Array>(el,
-                                        /* count */ state.types.Get<type::RuntimeArrayCount>(),
-                                        /* align */ 0u,
-                                        /* size */ 0u,
-                                        /* stride */ 0u,
-                                        /* stride_implicit */ 0u);
+    return state.types.runtime_array(el);
 }
 
 inline const type::BindingArray* BuildBindingArray(intrinsic::MatchState& state,
                                                    const type::Type*,
                                                    const type::Type* el,
                                                    intrinsic::Number N) {
-    return state.types.Get<type::BindingArray>(
-        el, state.types.Get<type::ConstantArrayCount>(N.Value()));
+    return state.types.binding_array(el, N.Value());
 }
 
 inline bool MatchBindingArray(intrinsic::MatchState&,
@@ -529,7 +513,7 @@
     }                                                                                           \
     inline const type::SampledTexture* JOIN(BuildTexture, suffix)(                              \
         intrinsic::MatchState & state, const type::Type*, const type::Type* T) {                \
-        return state.types.Get<type::SampledTexture>(dim, T);                                   \
+        return state.types.sampled_texture(dim, T);                                             \
     }
 
 DECLARE_SAMPLED_TEXTURE(1D, type::TextureDimension::k1d)
@@ -564,7 +548,7 @@
     }                                                                                \
     inline const type::MultisampledTexture* JOIN(BuildTextureMultisampled, suffix)(  \
         intrinsic::MatchState & state, const type::Type*, const type::Type* T) {     \
-        return state.types.Get<type::MultisampledTexture>(dim, T);                   \
+        return state.types.multisampled_texture(dim, T);                             \
     }
 
 DECLARE_MULTISAMPLED_TEXTURE(2D, type::TextureDimension::k2d)
@@ -586,7 +570,7 @@
     }                                                                          \
     inline const type::DepthTexture* JOIN(BuildTextureDepth, suffix)(          \
         intrinsic::MatchState & state, const type::Type*) {                    \
-        return state.types.Get<type::DepthTexture>(dim);                       \
+        return state.types.depth_texture(dim);                                 \
     }
 
 DECLARE_DEPTH_TEXTURE(2D, type::TextureDimension::k2d)
@@ -604,9 +588,10 @@
     });
 }
 
-inline type::DepthMultisampledTexture* BuildTextureDepthMultisampled2D(intrinsic::MatchState& state,
-                                                                       const type::Type*) {
-    return state.types.Get<type::DepthMultisampledTexture>(type::TextureDimension::k2d);
+inline const type::DepthMultisampledTexture* BuildTextureDepthMultisampled2D(
+    intrinsic::MatchState& state,
+    const type::Type*) {
+    return state.types.depth_multisampled_texture(type::TextureDimension::k2d);
 }
 
 inline bool MatchTextureStorage(intrinsic::MatchState&,
@@ -640,8 +625,7 @@
         intrinsic::Number A) {                                                                \
         auto format = static_cast<TexelFormat>(F.Value());                                    \
         auto access = static_cast<Access>(A.Value());                                         \
-        auto* T = type::StorageTexture::SubtypeFor(format, state.types);                      \
-        return state.types.Get<type::StorageTexture>(dim, format, access, T);                 \
+        return state.types.storage_texture(dim, format, access);                              \
     }
 
 DECLARE_STORAGE_TEXTURE(1D, type::TextureDimension::k1d)
@@ -656,7 +640,7 @@
 
 inline const type::ExternalTexture* BuildTextureExternal(intrinsic::MatchState& state,
                                                          const type::Type*) {
-    return state.types.Get<type::ExternalTexture>();
+    return state.types.external_texture();
 }
 
 inline bool MatchInputAttachment(intrinsic::MatchState&,
@@ -676,7 +660,7 @@
 inline const type::InputAttachment* BuildInputAttachment(intrinsic::MatchState& state,
                                                          const type::Type*,
                                                          const type::Type* T) {
-    return state.types.Get<type::InputAttachment>(T);
+    return state.types.input_attachment(T);
 }
 
 // Builtin types starting with a _ prefix cannot be declared in WGSL, so they
diff --git a/src/tint/lang/core/ir/binary/decode.cc b/src/tint/lang/core/ir/binary/decode.cc
index fa1514c..0624e3e 100644
--- a/src/tint/lang/core/ir/binary/decode.cc
+++ b/src/tint/lang/core/ir/binary/decode.cc
@@ -712,17 +712,17 @@
     const type::Type* CreateTypeBasic(pb::TypeBasic basic_in) {
         switch (basic_in) {
             case pb::TypeBasic::void_:
-                return mod_out_.Types().Get<void>();
+                return mod_out_.Types().void_();
             case pb::TypeBasic::bool_:
-                return mod_out_.Types().Get<bool>();
+                return mod_out_.Types().bool_();
             case pb::TypeBasic::i32:
-                return mod_out_.Types().Get<i32>();
+                return mod_out_.Types().i32();
             case pb::TypeBasic::u32:
-                return mod_out_.Types().Get<u32>();
+                return mod_out_.Types().u32();
             case pb::TypeBasic::f32:
-                return mod_out_.Types().Get<f32>();
+                return mod_out_.Types().f32();
             case pb::TypeBasic::f16:
-                return mod_out_.Types().Get<f16>();
+                return mod_out_.Types().f16();
 
             case pb::TypeBasic::TypeBasic_INT_MIN_SENTINEL_DO_NOT_USE_:
             case pb::TypeBasic::TypeBasic_INT_MAX_SENTINEL_DO_NOT_USE_:
@@ -876,20 +876,20 @@
             err_ << "invalid DepthTexture dimension\n";
             return mod_out_.Types().invalid();
         }
-        return mod_out_.Types().Get<type::DepthTexture>(dimension);
+        return mod_out_.Types().depth_texture(dimension);
     }
 
     const type::SampledTexture* CreateTypeSampledTexture(const pb::TypeSampledTexture& texture_in) {
         auto dimension = TextureDimension(texture_in.dimension());
         auto sub_type = Type(texture_in.sub_type());
-        return mod_out_.Types().Get<type::SampledTexture>(dimension, sub_type);
+        return mod_out_.Types().sampled_texture(dimension, sub_type);
     }
 
     const type::MultisampledTexture* CreateTypeMultisampledTexture(
         const pb::TypeMultisampledTexture& texture_in) {
         auto dimension = TextureDimension(texture_in.dimension());
         auto sub_type = Type(texture_in.sub_type());
-        return mod_out_.Types().Get<type::MultisampledTexture>(dimension, sub_type);
+        return mod_out_.Types().multisampled_texture(dimension, sub_type);
     }
 
     const type::Type* CreateTypeDepthMultisampledTexture(
@@ -899,20 +899,18 @@
             err_ << "invalid DepthMultisampledTexture dimension\n";
             return mod_out_.Types().invalid();
         }
-        return mod_out_.Types().Get<type::DepthMultisampledTexture>(dimension);
+        return mod_out_.Types().depth_multisampled_texture(dimension);
     }
 
     const type::StorageTexture* CreateTypeStorageTexture(const pb::TypeStorageTexture& texture_in) {
         auto dimension = TextureDimension(texture_in.dimension());
         auto texel_format = TexelFormat(texture_in.texel_format());
         auto access = AccessControl(texture_in.access());
-        return mod_out_.Types().Get<type::StorageTexture>(
-            dimension, texel_format, access,
-            type::StorageTexture::SubtypeFor(texel_format, b.ir.Types()));
+        return mod_out_.Types().storage_texture(dimension, texel_format, access);
     }
 
     const type::ExternalTexture* CreateTypeExternalTexture(const pb::TypeExternalTexture&) {
-        return mod_out_.Types().Get<type::ExternalTexture>();
+        return mod_out_.Types().external_texture();
     }
 
     const type::Sampler* CreateTypeSampler(const pb::TypeSampler& sampler_in) {
@@ -923,15 +921,14 @@
     const type::InputAttachment* CreateTypeInputAttachment(
         const pb::TypeInputAttachment& input_in) {
         auto sub_type = Type(input_in.sub_type());
-        return mod_out_.Types().Get<type::InputAttachment>(sub_type);
+        return mod_out_.Types().input_attachment(sub_type);
     }
 
     const type::SubgroupMatrix* CreateTypeSubgroupMatrix(
         SubgroupMatrixKind kind,
         const pb::TypeSubgroupMatrix& subgroup_matrix) {
-        return mod_out_.Types().Get<type::SubgroupMatrix>(kind, Type(subgroup_matrix.sub_type()),
-                                                          subgroup_matrix.columns(),
-                                                          subgroup_matrix.rows());
+        return mod_out_.Types().subgroup_matrix(kind, Type(subgroup_matrix.sub_type()),
+                                                subgroup_matrix.columns(), subgroup_matrix.rows());
     }
 
     const type::Type* CreateTypeBuiltinStruct(pb::TypeBuiltinStruct builtin_struct_in) {
diff --git a/src/tint/lang/core/ir/binary/roundtrip_test.cc b/src/tint/lang/core/ir/binary/roundtrip_test.cc
index e5867e4..3663a6d 100644
--- a/src/tint/lang/core/ir/binary/roundtrip_test.cc
+++ b/src/tint/lang/core/ir/binary/roundtrip_test.cc
@@ -303,7 +303,7 @@
 }
 
 TEST_F(IRBinaryRoundtripTest, depth_texture) {
-    auto* tex = ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d);
+    auto* tex = ty.depth_texture(core::type::TextureDimension::k2d);
     b.Append(b.ir.root_block, [&] { b.Var(ty.ptr(handle, tex, read)); });
     RUN_TEST();
 }
@@ -315,14 +315,13 @@
 }
 
 TEST_F(IRBinaryRoundtripTest, multisampled_texture) {
-    auto* tex =
-        ty.Get<core::type::MultisampledTexture>(core::type::TextureDimension::k2d, ty.f32());
+    auto* tex = ty.multisampled_texture(core::type::TextureDimension::k2d, ty.f32());
     b.Append(b.ir.root_block, [&] { b.Var(ty.ptr(handle, tex, read)); });
     RUN_TEST();
 }
 
 TEST_F(IRBinaryRoundtripTest, depth_multisampled_texture) {
-    auto* tex = ty.Get<core::type::DepthMultisampledTexture>(core::type::TextureDimension::k2d);
+    auto* tex = ty.depth_multisampled_texture(core::type::TextureDimension::k2d);
     b.Append(b.ir.root_block, [&] { b.Var(ty.ptr(handle, tex, read)); });
     RUN_TEST();
 }
@@ -335,7 +334,7 @@
 }
 
 TEST_F(IRBinaryRoundtripTest, external_texture) {
-    auto* tex = ty.Get<core::type::ExternalTexture>();
+    auto* tex = ty.external_texture();
     b.Append(b.ir.root_block, [&] { b.Var(ty.ptr(handle, tex, read)); });
     RUN_TEST();
 }
@@ -737,7 +736,7 @@
 
 TEST_F(IRBinaryRoundtripTest, InputAttachment) {
     b.Append(b.ir.root_block, [&] {
-        auto* input_type = ty.Get<core::type::InputAttachment>(ty.i32());
+        auto* input_type = ty.input_attachment(ty.i32());
         auto* v = b.Var(ty.ptr(handle, input_type, read));
         v->SetBindingPoint(10, 20);
         v->SetInputAttachmentIndex(11);
diff --git a/src/tint/lang/core/ir/transform/multiplanar_external_texture_test.cc b/src/tint/lang/core/ir/transform/multiplanar_external_texture_test.cc
index 9089411..637ec95 100644
--- a/src/tint/lang/core/ir/transform/multiplanar_external_texture_test.cc
+++ b/src/tint/lang/core/ir/transform/multiplanar_external_texture_test.cc
@@ -58,7 +58,7 @@
 }
 
 TEST_F(IR_MultiplanarExternalTextureTest, DeclWithNoUses) {
-    auto* var = b.Var("texture", ty.ptr(handle, ty.Get<core::type::ExternalTexture>()));
+    auto* var = b.Var("texture", ty.ptr(handle, ty.external_texture()));
     var->SetBindingPoint(1, 2);
     mod.root_block->Append(var);
 
@@ -129,7 +129,7 @@
 }
 
 TEST_F(IR_MultiplanarExternalTextureTest, LoadWithNoUses) {
-    auto* var = b.Var("texture", ty.ptr(handle, ty.Get<core::type::ExternalTexture>()));
+    auto* var = b.Var("texture", ty.ptr(handle, ty.external_texture()));
     var->SetBindingPoint(1, 2);
     mod.root_block->Append(var);
 
@@ -205,7 +205,7 @@
 }
 
 TEST_F(IR_MultiplanarExternalTextureTest, TextureDimensions) {
-    auto* var = b.Var("texture", ty.ptr(handle, ty.Get<core::type::ExternalTexture>()));
+    auto* var = b.Var("texture", ty.ptr(handle, ty.external_texture()));
     var->SetBindingPoint(1, 2);
     mod.root_block->Append(var);
 
@@ -286,7 +286,7 @@
 }
 
 TEST_F(IR_MultiplanarExternalTextureTest, TextureLoad) {
-    auto* var = b.Var("texture", ty.ptr(handle, ty.Get<core::type::ExternalTexture>()));
+    auto* var = b.Var("texture", ty.ptr(handle, ty.external_texture()));
     var->SetBindingPoint(1, 2);
     mod.root_block->Append(var);
 
@@ -447,7 +447,7 @@
 }
 
 TEST_F(IR_MultiplanarExternalTextureTest, TextureLoad_SignedCoords) {
-    auto* var = b.Var("texture", ty.ptr(handle, ty.Get<core::type::ExternalTexture>()));
+    auto* var = b.Var("texture", ty.ptr(handle, ty.external_texture()));
     var->SetBindingPoint(1, 2);
     mod.root_block->Append(var);
 
@@ -609,7 +609,7 @@
 }
 
 TEST_F(IR_MultiplanarExternalTextureTest, TextureSampleBaseClampToEdge) {
-    auto* var = b.Var("texture", ty.ptr(handle, ty.Get<core::type::ExternalTexture>()));
+    auto* var = b.Var("texture", ty.ptr(handle, ty.external_texture()));
     var->SetBindingPoint(1, 2);
     mod.root_block->Append(var);
 
@@ -770,13 +770,13 @@
 }
 
 TEST_F(IR_MultiplanarExternalTextureTest, ViaUserFunctionParameter) {
-    auto* var = b.Var("texture", ty.ptr(handle, ty.Get<core::type::ExternalTexture>()));
+    auto* var = b.Var("texture", ty.ptr(handle, ty.external_texture()));
     var->SetBindingPoint(1, 2);
     mod.root_block->Append(var);
 
     auto* foo = b.Function("foo", ty.vec4<f32>());
     {
-        auto* texture = b.FunctionParam("texture", ty.Get<core::type::ExternalTexture>());
+        auto* texture = b.FunctionParam("texture", ty.external_texture());
         auto* sampler = b.FunctionParam("sampler", ty.sampler());
         auto* coords = b.FunctionParam("coords", ty.vec2<f32>());
         foo->SetParams({texture, sampler, coords});
@@ -958,13 +958,13 @@
 }
 
 TEST_F(IR_MultiplanarExternalTextureTest, MultipleUses) {
-    auto* var = b.Var("texture", ty.ptr(handle, ty.Get<core::type::ExternalTexture>()));
+    auto* var = b.Var("texture", ty.ptr(handle, ty.external_texture()));
     var->SetBindingPoint(1, 2);
     mod.root_block->Append(var);
 
     auto* foo = b.Function("foo", ty.vec4<f32>());
     {
-        auto* texture = b.FunctionParam("texture", ty.Get<core::type::ExternalTexture>());
+        auto* texture = b.FunctionParam("texture", ty.external_texture());
         auto* sampler = b.FunctionParam("sampler", ty.sampler());
         auto* coords = b.FunctionParam("coords", ty.vec2<f32>());
         foo->SetParams({texture, sampler, coords});
@@ -1179,15 +1179,15 @@
 }
 
 TEST_F(IR_MultiplanarExternalTextureTest, MultipleTextures) {
-    auto* var_a = b.Var("texture_a", ty.ptr(handle, ty.Get<core::type::ExternalTexture>()));
+    auto* var_a = b.Var("texture_a", ty.ptr(handle, ty.external_texture()));
     var_a->SetBindingPoint(1, 2);
     mod.root_block->Append(var_a);
 
-    auto* var_b = b.Var("texture_b", ty.ptr(handle, ty.Get<core::type::ExternalTexture>()));
+    auto* var_b = b.Var("texture_b", ty.ptr(handle, ty.external_texture()));
     var_b->SetBindingPoint(2, 2);
     mod.root_block->Append(var_b);
 
-    auto* var_c = b.Var("texture_c", ty.ptr(handle, ty.Get<core::type::ExternalTexture>()));
+    auto* var_c = b.Var("texture_c", ty.ptr(handle, ty.external_texture()));
     var_c->SetBindingPoint(3, 2);
     mod.root_block->Append(var_c);
 
diff --git a/src/tint/lang/core/ir/transform/robustness_test.cc b/src/tint/lang/core/ir/transform/robustness_test.cc
index 0c1645a..660b314 100644
--- a/src/tint/lang/core/ir/transform/robustness_test.cc
+++ b/src/tint/lang/core/ir/transform/robustness_test.cc
@@ -2476,10 +2476,9 @@
 }
 
 TEST_P(IR_BindingVariableRobustnessTest, TextureLoad_Multisampled2D) {
-    auto* texture = b.Var(
-        "texture",
-        ty.ptr(handle, ty.Get<type::MultisampledTexture>(type::TextureDimension::k2d, ty.f32()),
-               read));
+    auto* texture =
+        b.Var("texture",
+              ty.ptr(handle, ty.multisampled_texture(type::TextureDimension::k2d, ty.f32()), read));
     texture->SetBindingPoint(0, 0);
     mod.root_block->Append(texture);
 
@@ -2567,8 +2566,8 @@
 }
 
 TEST_P(IR_BindingVariableRobustnessTest, TextureLoad_Depth2D) {
-    auto* texture = b.Var(
-        "texture", ty.ptr(handle, ty.Get<type::DepthTexture>(type::TextureDimension::k2d), read));
+    auto* texture =
+        b.Var("texture", ty.ptr(handle, ty.depth_texture(type::TextureDimension::k2d), read));
     texture->SetBindingPoint(0, 0);
     mod.root_block->Append(texture);
 
@@ -2662,8 +2661,7 @@
 
 TEST_P(IR_BindingVariableRobustnessTest, TextureLoad_Depth2DArray) {
     auto* texture =
-        b.Var("texture",
-              ty.ptr(handle, ty.Get<type::DepthTexture>(type::TextureDimension::k2dArray), read));
+        b.Var("texture", ty.ptr(handle, ty.depth_texture(type::TextureDimension::k2dArray), read));
     texture->SetBindingPoint(0, 0);
     mod.root_block->Append(texture);
 
@@ -2767,9 +2765,9 @@
 }
 
 TEST_P(IR_BindingVariableRobustnessTest, TextureLoad_DepthMultisampled2D) {
-    auto* texture = b.Var(
-        "texture",
-        ty.ptr(handle, ty.Get<type::DepthMultisampledTexture>(type::TextureDimension::k2d), read));
+    auto* texture =
+        b.Var("texture",
+              ty.ptr(handle, ty.depth_multisampled_texture(type::TextureDimension::k2d), read));
     texture->SetBindingPoint(0, 0);
     mod.root_block->Append(texture);
 
@@ -2855,7 +2853,7 @@
 }
 
 TEST_P(IR_BindingVariableRobustnessTest, TextureLoad_External) {
-    auto* texture = b.Var("texture", ty.ptr(handle, ty.Get<type::ExternalTexture>(), read));
+    auto* texture = b.Var("texture", ty.ptr(handle, ty.external_texture(), read));
     texture->SetBindingPoint(0, 0);
     mod.root_block->Append(texture);
 
diff --git a/src/tint/lang/core/ir/transform/value_to_let_test.cc b/src/tint/lang/core/ir/transform/value_to_let_test.cc
index db1ed2b..d83a7c2 100644
--- a/src/tint/lang/core/ir/transform/value_to_let_test.cc
+++ b/src/tint/lang/core/ir/transform/value_to_let_test.cc
@@ -990,8 +990,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
diff --git a/src/tint/lang/core/type/manager.cc b/src/tint/lang/core/type/manager.cc
index a8a95bb..1f8e016 100644
--- a/src/tint/lang/core/type/manager.cc
+++ b/src/tint/lang/core/type/manager.cc
@@ -54,6 +54,45 @@
 #include "src/tint/utils/macros/compiler.h"
 
 namespace tint::core::type {
+namespace {
+
+const Type* SubtypeFor(core::TexelFormat format, Manager& type_mgr) {
+    switch (format) {
+        case core::TexelFormat::kR32Uint:
+        case core::TexelFormat::kRgba8Uint:
+        case core::TexelFormat::kRg32Uint:
+        case core::TexelFormat::kRgba16Uint:
+        case core::TexelFormat::kRgba32Uint: {
+            return type_mgr.u32();
+        }
+
+        case core::TexelFormat::kR32Sint:
+        case core::TexelFormat::kRgba8Sint:
+        case core::TexelFormat::kRg32Sint:
+        case core::TexelFormat::kRgba16Sint:
+        case core::TexelFormat::kRgba32Sint: {
+            return type_mgr.i32();
+        }
+
+        case core::TexelFormat::kR8Unorm:
+        case core::TexelFormat::kBgra8Unorm:
+        case core::TexelFormat::kRgba8Unorm:
+        case core::TexelFormat::kRgba8Snorm:
+        case core::TexelFormat::kR32Float:
+        case core::TexelFormat::kRg32Float:
+        case core::TexelFormat::kRgba16Float:
+        case core::TexelFormat::kRgba32Float: {
+            return type_mgr.f32();
+        }
+
+        case core::TexelFormat::kUndefined:
+            break;
+    }
+
+    return nullptr;
+}
+
+}  // namespace
 
 Manager::Manager() = default;
 
@@ -167,7 +206,7 @@
 const core::type::StorageTexture* Manager::storage_texture(TextureDimension dim,
                                                            core::TexelFormat format,
                                                            core::Access access) {
-    const auto* subtype = StorageTexture::SubtypeFor(format, *this);
+    const auto* subtype = SubtypeFor(format, *this);
     return Get<core::type::StorageTexture>(dim, format, access, subtype);
 }
 
diff --git a/src/tint/lang/core/type/storage_texture.cc b/src/tint/lang/core/type/storage_texture.cc
index 1130544..e5044ea 100644
--- a/src/tint/lang/core/type/storage_texture.cc
+++ b/src/tint/lang/core/type/storage_texture.cc
@@ -62,42 +62,6 @@
     return out.str();
 }
 
-Type* StorageTexture::SubtypeFor(core::TexelFormat format, Manager& type_mgr) {
-    switch (format) {
-        case core::TexelFormat::kR32Uint:
-        case core::TexelFormat::kRgba8Uint:
-        case core::TexelFormat::kRg32Uint:
-        case core::TexelFormat::kRgba16Uint:
-        case core::TexelFormat::kRgba32Uint: {
-            return type_mgr.Get<U32>();
-        }
-
-        case core::TexelFormat::kR32Sint:
-        case core::TexelFormat::kRgba8Sint:
-        case core::TexelFormat::kRg32Sint:
-        case core::TexelFormat::kRgba16Sint:
-        case core::TexelFormat::kRgba32Sint: {
-            return type_mgr.Get<I32>();
-        }
-
-        case core::TexelFormat::kR8Unorm:
-        case core::TexelFormat::kBgra8Unorm:
-        case core::TexelFormat::kRgba8Unorm:
-        case core::TexelFormat::kRgba8Snorm:
-        case core::TexelFormat::kR32Float:
-        case core::TexelFormat::kRg32Float:
-        case core::TexelFormat::kRgba16Float:
-        case core::TexelFormat::kRgba32Float: {
-            return type_mgr.Get<F32>();
-        }
-
-        case core::TexelFormat::kUndefined:
-            break;
-    }
-
-    return nullptr;
-}
-
 StorageTexture* StorageTexture::Clone(CloneContext& ctx) const {
     auto* ty = subtype_->Clone(ctx);
     return ctx.dst.mgr->Get<StorageTexture>(Dim(), texel_format_, access_, ty);
diff --git a/src/tint/lang/core/type/storage_texture.h b/src/tint/lang/core/type/storage_texture.h
index f3266ab..cce2056 100644
--- a/src/tint/lang/core/type/storage_texture.h
+++ b/src/tint/lang/core/type/storage_texture.h
@@ -49,7 +49,7 @@
     /// @param dim the dimensionality of the texture
     /// @param format the texel format of the texture
     /// @param access the access control type of the texture
-    /// @param subtype the storage subtype. Use SubtypeFor() to calculate this.
+    /// @param subtype the storage subtype.
     StorageTexture(TextureDimension dim,
                    core::TexelFormat format,
                    core::Access access,
@@ -75,11 +75,6 @@
     /// declared in WGSL.
     std::string FriendlyName() const override;
 
-    /// @param format the storage texture image format
-    /// @param type_mgr the Manager used to build the returned type
-    /// @returns the storage texture subtype for the given TexelFormat
-    static type::Type* SubtypeFor(core::TexelFormat format, Manager& type_mgr);
-
     /// @param ctx the clone context
     /// @returns a clone of this type
     StorageTexture* Clone(CloneContext& ctx) const override;
diff --git a/src/tint/lang/glsl/writer/raise/texture_builtins_from_uniform_test.cc b/src/tint/lang/glsl/writer/raise/texture_builtins_from_uniform_test.cc
index 9975e65..180e05c 100644
--- a/src/tint/lang/glsl/writer/raise/texture_builtins_from_uniform_test.cc
+++ b/src/tint/lang/glsl/writer/raise/texture_builtins_from_uniform_test.cc
@@ -103,9 +103,8 @@
 }
 
 TEST_F(GlslWriter_TextureBuiltinsFromUniformTest, TextureNumSamples) {
-    auto* t = b.Var(ty.ptr(
-        handle, ty.Get<core::type::DepthMultisampledTexture>(core::type::TextureDimension::k2d),
-        read_write));
+    auto* t = b.Var(ty.ptr(handle, ty.depth_multisampled_texture(core::type::TextureDimension::k2d),
+                           read_write));
     t->SetBindingPoint(0, 0);
     b.ir.root_block->Append(t);
 
@@ -218,9 +217,8 @@
 }
 
 TEST_F(GlslWriter_TextureBuiltinsFromUniformTest, SameBuiltinCalledMultipleTimesTextureNumSamples) {
-    auto* t = b.Var(ty.ptr(
-        handle, ty.Get<core::type::DepthMultisampledTexture>(core::type::TextureDimension::k2d),
-        read_write));
+    auto* t = b.Var(ty.ptr(handle, ty.depth_multisampled_texture(core::type::TextureDimension::k2d),
+                           read_write));
     t->SetBindingPoint(0, 0);
     b.ir.root_block->Append(t);
 
diff --git a/src/tint/lang/glsl/writer/raise/texture_polyfill_test.cc b/src/tint/lang/glsl/writer/raise/texture_polyfill_test.cc
index 8114948..bb6ff4e 100644
--- a/src/tint/lang/glsl/writer/raise/texture_polyfill_test.cc
+++ b/src/tint/lang/glsl/writer/raise/texture_polyfill_test.cc
@@ -301,7 +301,7 @@
 }
 
 TEST_F(GlslWriter_TexturePolyfillTest, TextureDimensions_DepthMultisampled) {
-    auto* type = ty.Get<core::type::DepthMultisampledTexture>(core::type::TextureDimension::k2d);
+    auto* type = ty.depth_multisampled_texture(core::type::TextureDimension::k2d);
     auto* var = b.Var("v", handle, type, core::Access::kReadWrite);
     var->SetBindingPoint(0, 0);
     b.ir.root_block->Append(var);
@@ -405,9 +405,8 @@
 }
 
 TEST_F(GlslWriter_TexturePolyfillTest, TextureNumLayers_Depth2DArray) {
-    auto* var =
-        b.Var("v", handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray),
-              core::Access::kReadWrite);
+    auto* var = b.Var("v", handle, ty.depth_texture(core::type::TextureDimension::k2dArray),
+                      core::Access::kReadWrite);
     var->SetBindingPoint(0, 0);
     b.ir.root_block->Append(var);
 
@@ -511,8 +510,7 @@
 }
 
 TEST_F(GlslWriter_TexturePolyfillTest, TextureNumLayers_DepthCubeArray) {
-    auto* var = b.Var("v", handle,
-                      ty.Get<core::type::DepthTexture>(core::type::TextureDimension::kCubeArray),
+    auto* var = b.Var("v", handle, ty.depth_texture(core::type::TextureDimension::kCubeArray),
                       core::Access::kReadWrite);
     var->SetBindingPoint(0, 0);
     b.ir.root_block->Append(var);
@@ -777,8 +775,7 @@
 }
 
 TEST_F(GlslWriter_TexturePolyfillTest, TextureLoad_Multisampled2DI32) {
-    auto* type =
-        ty.Get<core::type::MultisampledTexture>(core::type::TextureDimension::k2d, ty.i32());
+    auto* type = ty.multisampled_texture(core::type::TextureDimension::k2d, ty.i32());
     auto* var = b.Var("v", handle, type, core::Access::kReadWrite);
     var->SetBindingPoint(0, 0);
     b.ir.root_block->Append(var);
@@ -1199,8 +1196,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -1266,8 +1262,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -1336,8 +1331,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::kCubeArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::kCubeArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -1406,8 +1400,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -1751,8 +1744,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -1815,8 +1807,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -1881,8 +1872,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -1949,8 +1939,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -2616,8 +2605,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -2682,8 +2670,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -2749,8 +2736,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -2817,8 +2803,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -2888,8 +2873,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::kCubeArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::kCubeArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -4030,8 +4014,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -4097,8 +4080,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -4165,8 +4147,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -4234,8 +4215,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -4305,8 +4285,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::kCubeArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::kCubeArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -4959,8 +4938,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -5025,8 +5003,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -5092,8 +5069,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -5161,8 +5137,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -5233,8 +5208,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::kCube)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::kCube)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -5299,8 +5273,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::kCubeArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::kCubeArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -5368,8 +5341,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -5434,8 +5406,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -5502,8 +5473,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -5571,8 +5541,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -5641,8 +5610,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::kCube)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::kCube)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -5707,8 +5675,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::kCubeArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::kCubeArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
diff --git a/src/tint/lang/glsl/writer/type_test.cc b/src/tint/lang/glsl/writer/type_test.cc
index 32d755a..d4fbb0d 100644
--- a/src/tint/lang/glsl/writer/type_test.cc
+++ b/src/tint/lang/glsl/writer/type_test.cc
@@ -473,7 +473,7 @@
 TEST_P(GlslWriterDepthTextureESTest, Emit) {
     auto params = GetParam();
 
-    auto* t = ty.Get<core::type::DepthTexture>(params.dim);
+    auto* t = ty.depth_texture(params.dim);
     auto* var = b.Var("v", handle, t, core::Access::kReadWrite);
     var->SetBindingPoint(0, 0);
     b.ir.root_block->Append(var);
@@ -499,7 +499,7 @@
 TEST_P(GlslWriterDepthTextureNonESTest, Emit) {
     auto params = GetParam();
 
-    auto* t = ty.Get<core::type::DepthTexture>(params.dim);
+    auto* t = ty.depth_texture(params.dim);
     auto* var = b.Var("v", handle, t, core::Access::kReadWrite);
     var->SetBindingPoint(0, 0);
     b.ir.root_block->Append(var);
@@ -526,7 +526,7 @@
         GlslDepthTextureData{core::type::TextureDimension::kCubeArray, "samplerCubeArrayShadow"}));
 
 TEST_F(GlslWriterTest, EmitType_DepthMultisampledTexture) {
-    auto* t = ty.Get<core::type::DepthMultisampledTexture>(core::type::TextureDimension::k2d);
+    auto* t = ty.depth_multisampled_texture(core::type::TextureDimension::k2d);
     auto* var = b.Var("v", handle, t, core::Access::kReadWrite);
     var->SetBindingPoint(0, 0);
     b.ir.root_block->Append(var);
@@ -690,7 +690,7 @@
             break;
     }
 
-    auto* ms = ty.Get<core::type::MultisampledTexture>(params.dim, subtype);
+    auto* ms = ty.multisampled_texture(params.dim, subtype);
     auto* var = b.Var("v", handle, ms, core::Access::kReadWrite);
     var->SetBindingPoint(0, 0);
     b.ir.root_block->Append(var);
@@ -729,7 +729,7 @@
             subtype = ty.u32();
             break;
     }
-    auto* ms = ty.Get<core::type::MultisampledTexture>(params.dim, subtype);
+    auto* ms = ty.multisampled_texture(params.dim, subtype);
     auto* var = b.Var("v", handle, ms, core::Access::kReadWrite);
     var->SetBindingPoint(0, 0);
     b.ir.root_block->Append(var);
diff --git a/src/tint/lang/glsl/writer/var_and_let_test.cc b/src/tint/lang/glsl/writer/var_and_let_test.cc
index 066634c..8ebfd7b 100644
--- a/src/tint/lang/glsl/writer/var_and_let_test.cc
+++ b/src/tint/lang/glsl/writer/var_and_let_test.cc
@@ -349,9 +349,8 @@
 
 TEST_F(GlslWriterTest, VarHandleDepthTexture) {
     b.Append(b.ir.root_block, [&] {
-        auto* v =
-            b.Var("v", ty.ptr(core::AddressSpace::kHandle,
-                              ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        auto* v = b.Var("v", ty.ptr(core::AddressSpace::kHandle,
+                                    ty.depth_texture(core::type::TextureDimension::k2d)));
         v->SetBindingPoint(0, 1);
     });
 
diff --git a/src/tint/lang/hlsl/type/rasterizer_ordered_texture_2d.cc b/src/tint/lang/hlsl/type/rasterizer_ordered_texture_2d.cc
index 45e1bc7..0536a37 100644
--- a/src/tint/lang/hlsl/type/rasterizer_ordered_texture_2d.cc
+++ b/src/tint/lang/hlsl/type/rasterizer_ordered_texture_2d.cc
@@ -63,15 +63,15 @@
     return out.str();
 }
 
-core::type::Type* RasterizerOrderedTexture2D::SubtypeFor(core::TexelFormat format,
-                                                         core::type::Manager& type_mgr) {
+const core::type::Type* RasterizerOrderedTexture2D::SubtypeFor(core::TexelFormat format,
+                                                               core::type::Manager& type_mgr) {
     switch (format) {
         case core::TexelFormat::kR32Uint:
-            return type_mgr.Get<core::type::U32>();
+            return type_mgr.u32();
         case core::TexelFormat::kR32Sint:
-            return type_mgr.Get<core::type::I32>();
+            return type_mgr.i32();
         case core::TexelFormat::kR32Float:
-            return type_mgr.Get<core::type::F32>();
+            return type_mgr.f32();
         default:
             break;
     }
diff --git a/src/tint/lang/hlsl/type/rasterizer_ordered_texture_2d.h b/src/tint/lang/hlsl/type/rasterizer_ordered_texture_2d.h
index 3c8f8a6..8683e54 100644
--- a/src/tint/lang/hlsl/type/rasterizer_ordered_texture_2d.h
+++ b/src/tint/lang/hlsl/type/rasterizer_ordered_texture_2d.h
@@ -61,7 +61,8 @@
     /// @param format the storage texture image format
     /// @param type_mgr the Manager used to build the returned type
     /// @returns the storage texture subtype for the given TexelFormat
-    static core::type::Type* SubtypeFor(core::TexelFormat format, core::type::Manager& type_mgr);
+    static const core::type::Type* SubtypeFor(core::TexelFormat format,
+                                              core::type::Manager& type_mgr);
 
     /// @param ctx the clone context
     /// @returns a clone of this type
diff --git a/src/tint/lang/hlsl/writer/builtin_test.cc b/src/tint/lang/hlsl/writer/builtin_test.cc
index e48fa239..9c0dcfe 100644
--- a/src/tint/lang/hlsl/writer/builtin_test.cc
+++ b/src/tint/lang/hlsl/writer/builtin_test.cc
@@ -1056,8 +1056,8 @@
 }
 
 TEST_F(HlslWriterTest, BuiltinTextureNumSamples) {
-    auto* t = b.FunctionParam(
-        "t", ty.Get<core::type::DepthMultisampledTexture>(core::type::TextureDimension::k2d));
+    auto* t =
+        b.FunctionParam("t", ty.depth_multisampled_texture(core::type::TextureDimension::k2d));
 
     auto* func = b.Function("foo", ty.void_());
     func->SetParams({t});
@@ -1163,8 +1163,8 @@
 }
 
 TEST_F(HlslWriterTest, BuiltinTextureLoad_Multisampled2DI32) {
-    auto* t = b.Var(ty.ptr(handle, ty.Get<core::type::MultisampledTexture>(
-                                       core::type::TextureDimension::k2d, ty.i32())));
+    auto* t =
+        b.Var(ty.ptr(handle, ty.multisampled_texture(core::type::TextureDimension::k2d, ty.i32())));
     t->SetBindingPoint(0, 0);
     b.ir.root_block->Append(t);
 
@@ -1189,8 +1189,7 @@
 }
 
 TEST_F(HlslWriterTest, BuiltinTextureLoad_Depth2DLevelF32) {
-    auto* t =
-        b.Var(ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+    auto* t = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
     t->SetBindingPoint(0, 0);
     b.ir.root_block->Append(t);
 
@@ -1216,8 +1215,7 @@
 }
 
 TEST_F(HlslWriterTest, BuiltinTextureLoad_Depth2DArrayLevelF32) {
-    auto* t = b.Var(
-        ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+    auto* t = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
     t->SetBindingPoint(0, 0);
     b.ir.root_block->Append(t);
 
@@ -1244,8 +1242,8 @@
 }
 
 TEST_F(HlslWriterTest, BuiltinTextureLoad_DepthMultisampledF32) {
-    auto* t = b.Var(ty.ptr(
-        handle, ty.Get<core::type::DepthMultisampledTexture>(core::type::TextureDimension::k2d)));
+    auto* t =
+        b.Var(ty.ptr(handle, ty.depth_multisampled_texture(core::type::TextureDimension::k2d)));
     t->SetBindingPoint(0, 0);
     b.ir.root_block->Append(t);
 
@@ -1348,8 +1346,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -1385,8 +1382,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -1424,8 +1420,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::kCubeArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::kCubeArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -1463,8 +1458,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -1650,8 +1644,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -1684,8 +1677,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -1719,8 +1711,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -1755,8 +1746,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -2981,8 +2971,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -3014,8 +3003,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -3048,8 +3036,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -3084,8 +3071,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -3121,8 +3107,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::kCube)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::kCube)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -3154,8 +3139,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::kCubeArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::kCubeArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -3190,8 +3174,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -3223,8 +3206,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -3258,8 +3240,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -3294,8 +3275,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -3331,8 +3311,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::kCube)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::kCube)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -3364,8 +3343,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::kCubeArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::kCubeArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -3710,8 +3688,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -3743,8 +3720,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -3777,8 +3753,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -3812,8 +3787,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -3848,8 +3822,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::kCubeArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::kCubeArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -4161,8 +4134,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -4195,8 +4167,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -4230,8 +4201,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -4266,8 +4236,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -4304,8 +4273,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::kCubeArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::kCubeArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
diff --git a/src/tint/lang/hlsl/writer/raise/builtin_polyfill_test.cc b/src/tint/lang/hlsl/writer/raise/builtin_polyfill_test.cc
index fcf5ff7..676f38f 100644
--- a/src/tint/lang/hlsl/writer/raise/builtin_polyfill_test.cc
+++ b/src/tint/lang/hlsl/writer/raise/builtin_polyfill_test.cc
@@ -547,8 +547,8 @@
 }
 
 TEST_F(HlslWriter_BuiltinPolyfillTest, TextureNumSamples) {
-    auto* t = b.FunctionParam(
-        "t", ty.Get<core::type::MultisampledTexture>(core::type::TextureDimension::k2d, ty.f32()));
+    auto* t =
+        b.FunctionParam("t", ty.multisampled_texture(core::type::TextureDimension::k2d, ty.f32()));
     auto* func = b.Function("foo", ty.u32());
     func->SetParams({t});
     b.Append(func->Block(), [&] {
@@ -931,8 +931,8 @@
 }
 
 TEST_F(HlslWriter_BuiltinPolyfillTest, TextureLoad_Multisampled2DI32) {
-    auto* t = b.FunctionParam(
-        "t", ty.Get<core::type::MultisampledTexture>(core::type::TextureDimension::k2d, ty.i32()));
+    auto* t =
+        b.FunctionParam("t", ty.multisampled_texture(core::type::TextureDimension::k2d, ty.i32()));
     auto* func = b.Function("foo", ty.vec4<i32>());
     func->SetParams({t});
     b.Append(func->Block(), [&] {
@@ -968,8 +968,7 @@
 }
 
 TEST_F(HlslWriter_BuiltinPolyfillTest, TextureLoad_Depth2DLevelF32) {
-    auto* t =
-        b.FunctionParam("t", ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d));
+    auto* t = b.FunctionParam("t", ty.depth_texture(core::type::TextureDimension::k2d));
     auto* func = b.Function("foo", ty.f32());
     func->SetParams({t});
     b.Append(func->Block(), [&] {
@@ -1007,8 +1006,7 @@
 }
 
 TEST_F(HlslWriter_BuiltinPolyfillTest, TextureLoad_Depth2DArrayLevelF32) {
-    auto* t = b.FunctionParam(
-        "t", ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray));
+    auto* t = b.FunctionParam("t", ty.depth_texture(core::type::TextureDimension::k2dArray));
     auto* func = b.Function("foo", ty.f32());
     func->SetParams({t});
     b.Append(func->Block(), [&] {
@@ -1048,8 +1046,8 @@
 }
 
 TEST_F(HlslWriter_BuiltinPolyfillTest, TextureLoad_DepthMultisampledF32) {
-    auto* t = b.FunctionParam(
-        "t", ty.Get<core::type::DepthMultisampledTexture>(core::type::TextureDimension::k2d));
+    auto* t =
+        b.FunctionParam("t", ty.depth_multisampled_texture(core::type::TextureDimension::k2d));
     auto* func = b.Function("foo", ty.f32());
     func->SetParams({t});
     b.Append(func->Block(), [&] {
@@ -1238,8 +1236,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -1304,8 +1301,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -1373,8 +1369,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::kCubeArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::kCubeArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -1442,8 +1437,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -1778,8 +1772,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -1841,8 +1834,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -1905,8 +1897,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -1971,8 +1962,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -2609,8 +2599,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -2672,8 +2661,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -2736,8 +2724,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -2802,8 +2789,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -2869,8 +2855,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::kCubeArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::kCubeArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -3448,8 +3433,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -3510,8 +3494,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -3573,8 +3556,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -3639,8 +3621,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -3706,8 +3687,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::kCube)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::kCube)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -3768,8 +3748,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::kCubeArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::kCubeArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -3834,8 +3813,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -3896,8 +3874,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -3960,8 +3937,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -4026,8 +4002,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -4093,8 +4068,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::kCube)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::kCube)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -4155,8 +4129,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::kCubeArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::kCubeArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.comparison_sampler()));
@@ -5295,8 +5268,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -5359,8 +5331,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(
-            ty.ptr(handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2d)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -5424,8 +5395,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -5491,8 +5461,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::k2dArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
@@ -5560,8 +5529,7 @@
     core::ir::Var* tex = nullptr;
     core::ir::Var* sampler = nullptr;
     b.Append(b.ir.root_block, [&] {
-        tex = b.Var(ty.ptr(
-            handle, ty.Get<core::type::DepthTexture>(core::type::TextureDimension::kCubeArray)));
+        tex = b.Var(ty.ptr(handle, ty.depth_texture(core::type::TextureDimension::kCubeArray)));
         tex->SetBindingPoint(0, 0);
 
         sampler = b.Var(ty.ptr(handle, ty.sampler()));
diff --git a/src/tint/lang/hlsl/writer/raise/pixel_local.cc b/src/tint/lang/hlsl/writer/raise/pixel_local.cc
index 5e8baa9..5755307 100644
--- a/src/tint/lang/hlsl/writer/raise/pixel_local.cc
+++ b/src/tint/lang/hlsl/writer/raise/pixel_local.cc
@@ -63,7 +63,7 @@
     // A Rasterizer Order View (ROV)
     struct ROV {
         core::ir::Var* var;
-        core::type::Type* subtype;
+        const core::type::Type* subtype;
     };
     // Create ROV root variables, one per member of `pixel_local_struct`
     Vector<ROV, 4> CreateROVs(const core::type::Struct* pixel_local_struct) {
diff --git a/src/tint/lang/hlsl/writer/var_let_test.cc b/src/tint/lang/hlsl/writer/var_let_test.cc
index 70046d2..d62fb68 100644
--- a/src/tint/lang/hlsl/writer/var_let_test.cc
+++ b/src/tint/lang/hlsl/writer/var_let_test.cc
@@ -141,7 +141,7 @@
 TEST_P(VarDepthTextureTest, Emit) {
     auto params = GetParam();
 
-    auto* s = b.Var("tex", ty.ptr<handle>(ty.Get<core::type::DepthTexture>(params.dim)));
+    auto* s = b.Var("tex", ty.ptr<handle>(ty.depth_texture(params.dim)));
     s->SetBindingPoint(2, 1);
 
     b.ir.root_block->Append(s);
@@ -167,8 +167,8 @@
                                          "TextureCubeArray tex : register(t1, space2);"}));
 
 TEST_F(HlslWriterTest, VarDepthMultiSampled) {
-    auto* s = b.Var("tex", ty.ptr<handle>(ty.Get<core::type::DepthMultisampledTexture>(
-                               core::type::TextureDimension::k2d)));
+    auto* s = b.Var(
+        "tex", ty.ptr<handle>(ty.depth_multisampled_texture(core::type::TextureDimension::k2d)));
     s->SetBindingPoint(2, 1);
 
     b.ir.root_block->Append(s);
@@ -323,8 +323,9 @@
                              }));
 
 TEST_F(HlslWriterTest, VarMultisampledTexture) {
-    auto* s = b.Var("tex", ty.ptr<handle>(ty.Get<core::type::MultisampledTexture>(
-                               core::type::TextureDimension::k2d, ty.f32())));
+    auto* s =
+        b.Var("tex",
+              ty.ptr<handle>(ty.multisampled_texture(core::type::TextureDimension::k2d, ty.f32())));
     s->SetBindingPoint(2, 1);
 
     b.ir.root_block->Append(s);
diff --git a/src/tint/lang/msl/writer/raise/builtin_polyfill_test.cc b/src/tint/lang/msl/writer/raise/builtin_polyfill_test.cc
index 856423f..6146e57 100644
--- a/src/tint/lang/msl/writer/raise/builtin_polyfill_test.cc
+++ b/src/tint/lang/msl/writer/raise/builtin_polyfill_test.cc
@@ -1746,8 +1746,7 @@
 }
 
 TEST_F(MslWriter_BuiltinPolyfillTest, TextureGather_Depth2d) {
-    auto* t =
-        b.FunctionParam("t", ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d));
+    auto* t = b.FunctionParam("t", ty.depth_texture(core::type::TextureDimension::k2d));
     auto* s = b.FunctionParam("s", ty.sampler());
     auto* coords = b.FunctionParam("coords", ty.vec2<f32>());
     auto* func = b.Function("foo", ty.vec4<f32>());
@@ -1782,8 +1781,7 @@
 }
 
 TEST_F(MslWriter_BuiltinPolyfillTest, TextureGatherCompare) {
-    auto* t =
-        b.FunctionParam("t", ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d));
+    auto* t = b.FunctionParam("t", ty.depth_texture(core::type::TextureDimension::k2d));
     auto* s = b.FunctionParam("s", ty.comparison_sampler());
     auto* coords = b.FunctionParam("coords", ty.vec2<f32>());
     auto* depth = b.FunctionParam("depth", ty.f32());
@@ -2228,8 +2226,8 @@
 }
 
 TEST_F(MslWriter_BuiltinPolyfillTest, TextureNumSamples) {
-    auto* t = b.FunctionParam(
-        "t", ty.Get<core::type::MultisampledTexture>(core::type::TextureDimension::k2d, ty.f32()));
+    auto* t =
+        b.FunctionParam("t", ty.multisampled_texture(core::type::TextureDimension::k2d, ty.f32()));
     auto* func = b.Function("foo", ty.u32());
     func->SetParams({t});
     b.Append(func->Block(), [&] {
@@ -2374,8 +2372,7 @@
 }
 
 TEST_F(MslWriter_BuiltinPolyfillTest, TextureSampleCompare) {
-    auto* t =
-        b.FunctionParam("t", ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d));
+    auto* t = b.FunctionParam("t", ty.depth_texture(core::type::TextureDimension::k2d));
     auto* s = b.FunctionParam("s", ty.comparison_sampler());
     auto* coords = b.FunctionParam("coords", ty.vec2<f32>());
     auto* depth = b.FunctionParam("depth", ty.f32());
@@ -2411,8 +2408,7 @@
 }
 
 TEST_F(MslWriter_BuiltinPolyfillTest, TextureSampleCompareLevel) {
-    auto* t =
-        b.FunctionParam("t", ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d));
+    auto* t = b.FunctionParam("t", ty.depth_texture(core::type::TextureDimension::k2d));
     auto* s = b.FunctionParam("s", ty.comparison_sampler());
     auto* coords = b.FunctionParam("coords", ty.vec2<f32>());
     auto* depth = b.FunctionParam("depth", ty.f32());
@@ -2450,8 +2446,7 @@
 }
 
 TEST_F(MslWriter_BuiltinPolyfillTest, TextureSampleCompareLevel_WithOffset) {
-    auto* t =
-        b.FunctionParam("t", ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d));
+    auto* t = b.FunctionParam("t", ty.depth_texture(core::type::TextureDimension::k2d));
     auto* s = b.FunctionParam("s", ty.comparison_sampler());
     auto* coords = b.FunctionParam("coords", ty.vec2<f32>());
     auto* depth = b.FunctionParam("depth", ty.f32());
diff --git a/src/tint/lang/msl/writer/type_test.cc b/src/tint/lang/msl/writer/type_test.cc
index 870b1c09..ef96b19 100644
--- a/src/tint/lang/msl/writer/type_test.cc
+++ b/src/tint/lang/msl/writer/type_test.cc
@@ -1005,7 +1005,7 @@
 TEST_P(MslWriterDepthTexturesTest, Emit) {
     auto params = GetParam();
 
-    auto* t = ty.Get<core::type::DepthTexture>(params.dim);
+    auto* t = ty.depth_texture(params.dim);
     auto* func = b.Function("foo", ty.void_());
     auto* param = b.FunctionParam("a", t);
     func->SetParams({param});
@@ -1091,7 +1091,7 @@
                        "texturecube_array<float, access::sample>"}));
 
 TEST_F(MslWriterTest, EmitType_MultisampledTexture) {
-    auto* ms = ty.Get<core::type::MultisampledTexture>(core::type::TextureDimension::k2d, ty.u32());
+    auto* ms = ty.multisampled_texture(core::type::TextureDimension::k2d, ty.u32());
     auto* func = b.Function("foo", ty.void_());
     auto* param = b.FunctionParam("a", ms);
     func->SetParams({param});
diff --git a/src/tint/lang/spirv/writer/raise/builtin_polyfill_test.cc b/src/tint/lang/spirv/writer/raise/builtin_polyfill_test.cc
index cd70365..add2c03 100644
--- a/src/tint/lang/spirv/writer/raise/builtin_polyfill_test.cc
+++ b/src/tint/lang/spirv/writer/raise/builtin_polyfill_test.cc
@@ -1306,8 +1306,8 @@
 }
 
 TEST_F(SpirvWriter_BuiltinPolyfillTest, TextureLoad_Multisampled2D) {
-    auto* t = b.FunctionParam(
-        "t", ty.Get<core::type::MultisampledTexture>(core::type::TextureDimension::k2d, ty.f32()));
+    auto* t =
+        b.FunctionParam("t", ty.multisampled_texture(core::type::TextureDimension::k2d, ty.f32()));
     auto* coords = b.FunctionParam("coords", ty.vec2<i32>());
     auto* sample_idx = b.FunctionParam("sample_idx", ty.i32());
     auto* func = b.Function("foo", ty.vec4<f32>());
@@ -1343,8 +1343,7 @@
 }
 
 TEST_F(SpirvWriter_BuiltinPolyfillTest, TextureLoad_Depth2D) {
-    auto* t =
-        b.FunctionParam("t", ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d));
+    auto* t = b.FunctionParam("t", ty.depth_texture(core::type::TextureDimension::k2d));
     auto* coords = b.FunctionParam("coords", ty.vec2<i32>());
     auto* lod = b.FunctionParam("lod", ty.i32());
     auto* func = b.Function("foo", ty.f32());
@@ -1730,8 +1729,7 @@
 }
 
 TEST_F(SpirvWriter_BuiltinPolyfillTest, TextureSampleCompare_2D) {
-    auto* t =
-        b.FunctionParam("t", ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d));
+    auto* t = b.FunctionParam("t", ty.depth_texture(core::type::TextureDimension::k2d));
     auto* s = b.FunctionParam("s", ty.comparison_sampler());
     auto* coords = b.FunctionParam("coords", ty.vec2<f32>());
     auto* dref = b.FunctionParam("dref", ty.f32());
@@ -1769,8 +1767,7 @@
 }
 
 TEST_F(SpirvWriter_BuiltinPolyfillTest, TextureSampleCompare_2D_Offset) {
-    auto* t =
-        b.FunctionParam("t", ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d));
+    auto* t = b.FunctionParam("t", ty.depth_texture(core::type::TextureDimension::k2d));
     auto* s = b.FunctionParam("s", ty.comparison_sampler());
     auto* coords = b.FunctionParam("coords", ty.vec2<f32>());
     auto* dref = b.FunctionParam("dref", ty.f32());
@@ -1809,8 +1806,7 @@
 }
 
 TEST_F(SpirvWriter_BuiltinPolyfillTest, TextureSampleCompare_2DArray_Offset) {
-    auto* t = b.FunctionParam(
-        "t", ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray));
+    auto* t = b.FunctionParam("t", ty.depth_texture(core::type::TextureDimension::k2dArray));
     auto* s = b.FunctionParam("s", ty.comparison_sampler());
     auto* coords = b.FunctionParam("coords", ty.vec2<f32>());
     auto* array_idx = b.FunctionParam("array_idx", ty.i32());
@@ -1852,8 +1848,7 @@
 }
 
 TEST_F(SpirvWriter_BuiltinPolyfillTest, TextureSampleCompareLevel_2D) {
-    auto* t =
-        b.FunctionParam("t", ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d));
+    auto* t = b.FunctionParam("t", ty.depth_texture(core::type::TextureDimension::k2d));
     auto* s = b.FunctionParam("s", ty.comparison_sampler());
     auto* coords = b.FunctionParam("coords", ty.vec2<f32>());
     auto* dref = b.FunctionParam("dref", ty.f32());
@@ -1892,8 +1887,7 @@
 }
 
 TEST_F(SpirvWriter_BuiltinPolyfillTest, TextureSampleCompareLevel_2D_Offset) {
-    auto* t =
-        b.FunctionParam("t", ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d));
+    auto* t = b.FunctionParam("t", ty.depth_texture(core::type::TextureDimension::k2d));
     auto* s = b.FunctionParam("s", ty.comparison_sampler());
     auto* coords = b.FunctionParam("coords", ty.vec2<f32>());
     auto* dref = b.FunctionParam("dref", ty.f32());
@@ -1932,8 +1926,7 @@
 }
 
 TEST_F(SpirvWriter_BuiltinPolyfillTest, TextureSampleCompareLevel_2DArray_Offset) {
-    auto* t = b.FunctionParam(
-        "t", ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray));
+    auto* t = b.FunctionParam("t", ty.depth_texture(core::type::TextureDimension::k2dArray));
     auto* s = b.FunctionParam("s", ty.comparison_sampler());
     auto* coords = b.FunctionParam("coords", ty.vec2<f32>());
     auto* array_idx = b.FunctionParam("array_idx", ty.i32());
@@ -2341,8 +2334,7 @@
 }
 
 TEST_F(SpirvWriter_BuiltinPolyfillTest, TextureGather_Depth2D) {
-    auto* t =
-        b.FunctionParam("t", ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d));
+    auto* t = b.FunctionParam("t", ty.depth_texture(core::type::TextureDimension::k2d));
     auto* s = b.FunctionParam("s", ty.sampler());
     auto* coords = b.FunctionParam("coords", ty.vec2<f32>());
     auto* func = b.Function("foo", ty.vec4<f32>());
@@ -2379,8 +2371,7 @@
 }
 
 TEST_F(SpirvWriter_BuiltinPolyfillTest, TextureGatherCompare_Depth2D) {
-    auto* t =
-        b.FunctionParam("t", ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d));
+    auto* t = b.FunctionParam("t", ty.depth_texture(core::type::TextureDimension::k2d));
     auto* s = b.FunctionParam("s", ty.comparison_sampler());
     auto* coords = b.FunctionParam("coords", ty.vec2<f32>());
     auto* depth = b.FunctionParam("depth", ty.f32());
@@ -2419,8 +2410,7 @@
 }
 
 TEST_F(SpirvWriter_BuiltinPolyfillTest, TextureGatherCompare_Depth2D_Offset) {
-    auto* t =
-        b.FunctionParam("t", ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d));
+    auto* t = b.FunctionParam("t", ty.depth_texture(core::type::TextureDimension::k2d));
     auto* s = b.FunctionParam("s", ty.comparison_sampler());
     auto* coords = b.FunctionParam("coords", ty.vec2<f32>());
     auto* depth = b.FunctionParam("depth", ty.f32());
@@ -2459,8 +2449,7 @@
 }
 
 TEST_F(SpirvWriter_BuiltinPolyfillTest, TextureGatherCompare_Depth2DArray) {
-    auto* t = b.FunctionParam(
-        "t", ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray));
+    auto* t = b.FunctionParam("t", ty.depth_texture(core::type::TextureDimension::k2dArray));
     auto* s = b.FunctionParam("s", ty.comparison_sampler());
     auto* coords = b.FunctionParam("coords", ty.vec2<f32>());
     auto* array_idx = b.FunctionParam("array_idx", ty.u32());
@@ -2764,8 +2753,8 @@
 }
 
 TEST_F(SpirvWriter_BuiltinPolyfillTest, TextureDimensions_Multisampled) {
-    auto* t = b.FunctionParam(
-        "t", ty.Get<core::type::MultisampledTexture>(core::type::TextureDimension::k2d, ty.f32()));
+    auto* t =
+        b.FunctionParam("t", ty.multisampled_texture(core::type::TextureDimension::k2d, ty.f32()));
     auto* func = b.Function("foo", ty.vec2<u32>());
     func->SetParams({t});
 
@@ -3006,8 +2995,7 @@
 }
 
 TEST_F(SpirvWriter_BuiltinPolyfillTest, TextureNumLevels_depth_2d) {
-    auto* t =
-        b.FunctionParam("t", ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2d));
+    auto* t = b.FunctionParam("t", ty.depth_texture(core::type::TextureDimension::k2d));
     auto* func = b.Function("foo", ty.u32());
     func->SetParams({t});
 
@@ -3041,8 +3029,7 @@
 }
 
 TEST_F(SpirvWriter_BuiltinPolyfillTest, TextureNumLevels_depth_2dArray) {
-    auto* t = b.FunctionParam(
-        "t", ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray));
+    auto* t = b.FunctionParam("t", ty.depth_texture(core::type::TextureDimension::k2dArray));
     auto* func = b.Function("foo", ty.u32());
     func->SetParams({t});
 
@@ -3076,8 +3063,7 @@
 }
 
 TEST_F(SpirvWriter_BuiltinPolyfillTest, TextureNumLevels_depth_cube) {
-    auto* t =
-        b.FunctionParam("t", ty.Get<core::type::DepthTexture>(core::type::TextureDimension::kCube));
+    auto* t = b.FunctionParam("t", ty.depth_texture(core::type::TextureDimension::kCube));
     auto* func = b.Function("foo", ty.u32());
     func->SetParams({t});
 
@@ -3111,8 +3097,7 @@
 }
 
 TEST_F(SpirvWriter_BuiltinPolyfillTest, TextureNumLevels_depth_CubeArray) {
-    auto* t = b.FunctionParam(
-        "t", ty.Get<core::type::DepthTexture>(core::type::TextureDimension::kCubeArray));
+    auto* t = b.FunctionParam("t", ty.depth_texture(core::type::TextureDimension::kCubeArray));
     auto* func = b.Function("foo", ty.u32());
     func->SetParams({t});
 
@@ -3146,8 +3131,8 @@
 }
 
 TEST_F(SpirvWriter_BuiltinPolyfillTest, TextureNumSamples_ms_2d) {
-    auto* t = b.FunctionParam(
-        "t", ty.Get<core::type::MultisampledTexture>(core::type::TextureDimension::k2d, ty.i32()));
+    auto* t =
+        b.FunctionParam("t", ty.multisampled_texture(core::type::TextureDimension::k2d, ty.i32()));
     auto* func = b.Function("foo", ty.u32());
     func->SetParams({t});
 
@@ -3181,8 +3166,8 @@
 }
 
 TEST_F(SpirvWriter_BuiltinPolyfillTest, TextureNumSamples_depth_ms_2d) {
-    auto* t = b.FunctionParam(
-        "t", ty.Get<core::type::DepthMultisampledTexture>(core::type::TextureDimension::k2d));
+    auto* t =
+        b.FunctionParam("t", ty.depth_multisampled_texture(core::type::TextureDimension::k2d));
     auto* func = b.Function("foo", ty.u32());
     func->SetParams({t});
 
@@ -3288,8 +3273,7 @@
 }
 
 TEST_F(SpirvWriter_BuiltinPolyfillTest, TextureNumLayers_Depth2DArray) {
-    auto* t = b.FunctionParam(
-        "t", ty.Get<core::type::DepthTexture>(core::type::TextureDimension::k2dArray));
+    auto* t = b.FunctionParam("t", ty.depth_texture(core::type::TextureDimension::k2dArray));
     auto* func = b.Function("foo", ty.u32());
     func->SetParams({t});
 
@@ -3324,8 +3308,7 @@
 }
 
 TEST_F(SpirvWriter_BuiltinPolyfillTest, TextureNumLayers_DepthCubeArray) {
-    auto* t = b.FunctionParam(
-        "t", ty.Get<core::type::DepthTexture>(core::type::TextureDimension::kCubeArray));
+    auto* t = b.FunctionParam("t", ty.depth_texture(core::type::TextureDimension::kCubeArray));
     auto* func = b.Function("foo", ty.u32());
     func->SetParams({t});
 
@@ -3466,7 +3449,7 @@
 }
 
 TEST_F(SpirvWriter_BuiltinPolyfillTest, InputAttachmentLoad) {
-    auto* t = b.FunctionParam("t", ty.Get<core::type::InputAttachment>(ty.f32()));
+    auto* t = b.FunctionParam("t", ty.input_attachment(ty.f32()));
     auto* func = b.Function("foo", ty.vec4<f32>());
     func->SetParams({t});
 
diff --git a/src/tint/lang/spirv/writer/texture_builtin_test.cc b/src/tint/lang/spirv/writer/texture_builtin_test.cc
index 1723336..fb70af2 100644
--- a/src/tint/lang/spirv/writer/texture_builtin_test.cc
+++ b/src/tint/lang/spirv/writer/texture_builtin_test.cc
@@ -119,11 +119,11 @@
             case kSampledTexture:
                 return ty.sampled_texture(dim, MakeScalarType(texel_type));
             case kMultisampledTexture:
-                return ty.Get<core::type::MultisampledTexture>(dim, MakeScalarType(texel_type));
+                return ty.multisampled_texture(dim, MakeScalarType(texel_type));
             case kDepthTexture:
-                return ty.Get<core::type::DepthTexture>(dim);
+                return ty.depth_texture(dim);
             case kDepthMultisampledTexture:
-                return ty.Get<core::type::DepthMultisampledTexture>(dim);
+                return ty.depth_multisampled_texture(dim);
             case kStorageTexture:
                 core::TexelFormat format;
                 switch (texel_type) {
diff --git a/src/tint/lang/spirv/writer/type_test.cc b/src/tint/lang/spirv/writer/type_test.cc
index 81812d5..e88cb23 100644
--- a/src/tint/lang/spirv/writer/type_test.cc
+++ b/src/tint/lang/spirv/writer/type_test.cc
@@ -402,7 +402,7 @@
 TEST_P(Type_MultisampledTexture, Emit) {
     auto params = GetParam();
     b.Append(b.ir.root_block, [&] {
-        auto* v = b.Var("v", ty.ptr<handle, read_write>(ty.Get<core::type::MultisampledTexture>(
+        auto* v = b.Var("v", ty.ptr<handle, read_write>(ty.multisampled_texture(
                                  params.dim, MakeScalarType(params.format))));
         v->SetBindingPoint(0, 0);
     });
@@ -421,8 +421,7 @@
 TEST_P(Type_DepthTexture, Emit) {
     auto params = GetParam();
     b.Append(b.ir.root_block, [&] {  //
-        auto* v =
-            b.Var("v", ty.ptr<handle, read_write>(ty.Get<core::type::DepthTexture>(params.dim)));
+        auto* v = b.Var("v", ty.ptr<handle, read_write>(ty.depth_texture(params.dim)));
         v->SetBindingPoint(0, 0);
     });
 
@@ -440,8 +439,7 @@
 TEST_F(SpirvWriterTest, Type_DepthTexture_DedupWithSampledTexture) {
     b.Append(b.ir.root_block, [&] {
         auto* v1 = b.Var("v1", ty.ptr<handle, read_write>(ty.sampled_texture(Dim::k2d, ty.f32())));
-        auto* v2 =
-            b.Var("v2", ty.ptr<handle, read_write>(ty.Get<core::type::DepthTexture>(Dim::k2d)));
+        auto* v2 = b.Var("v2", ty.ptr<handle, read_write>(ty.depth_texture(Dim::k2d)));
         v1->SetBindingPoint(0, 1);
         v2->SetBindingPoint(0, 2);
     });
@@ -460,8 +458,7 @@
 
 TEST_F(SpirvWriterTest, Type_DepthMultiSampledTexture) {
     b.Append(b.ir.root_block, [&] {
-        auto* v = b.Var("v", ty.ptr<handle, read_write>(
-                                 ty.Get<core::type::DepthMultisampledTexture>(Dim::k2d)));
+        auto* v = b.Var("v", ty.ptr<handle, read_write>(ty.depth_multisampled_texture(Dim::k2d)));
         v->SetBindingPoint(0, 0);
     });
 
@@ -471,10 +468,9 @@
 
 TEST_F(SpirvWriterTest, Type_DepthMultisampledTexture_DedupWithMultisampledTexture) {
     b.Append(b.ir.root_block, [&] {
-        auto* v1 = b.Var("v1", ty.ptr<handle, read_write>(
-                                   ty.Get<core::type::MultisampledTexture>(Dim::k2d, ty.f32())));
-        auto* v2 = b.Var("v2", ty.ptr<handle, read_write>(
-                                   ty.Get<core::type::DepthMultisampledTexture>(Dim::k2d)));
+        auto* v1 =
+            b.Var("v1", ty.ptr<handle, read_write>(ty.multisampled_texture(Dim::k2d, ty.f32())));
+        auto* v2 = b.Var("v2", ty.ptr<handle, read_write>(ty.depth_multisampled_texture(Dim::k2d)));
         v1->SetBindingPoint(0, 1);
         v2->SetBindingPoint(0, 2);
     });
diff --git a/src/tint/lang/wgsl/intrinsic/table_test.cc b/src/tint/lang/wgsl/intrinsic/table_test.cc
index 8011f1e..a3678c9 100644
--- a/src/tint/lang/wgsl/intrinsic/table_test.cc
+++ b/src/tint/lang/wgsl/intrinsic/table_test.cc
@@ -392,10 +392,8 @@
     auto* i32 = create<core::type::I32>();
     auto* vec2i = create<core::type::Vector>(i32, 2u);
     auto* vec4f = create<core::type::Vector>(f32, 4u);
-    auto* subtype = core::type::StorageTexture::SubtypeFor(core::TexelFormat::kR32Float, Types());
-    auto* tex = create<core::type::StorageTexture>(core::type::TextureDimension::k2d,
-                                                   core::TexelFormat::kR32Float,
-                                                   core::Access::kWrite, subtype);
+    auto* tex = Types().storage_texture(core::type::TextureDimension::k2d,
+                                        core::TexelFormat::kR32Float, core::Access::kWrite);
 
     auto result = table.Lookup(wgsl::BuiltinFn::kTextureStore, Empty, Vector{tex, vec2i, vec4f},
                                core::EvaluationStage::kConstant);
diff --git a/src/tint/lang/wgsl/resolver/resolver.cc b/src/tint/lang/wgsl/resolver/resolver.cc
index ae92315..5fe4907 100644
--- a/src/tint/lang/wgsl/resolver/resolver.cc
+++ b/src/tint/lang/wgsl/resolver/resolver.cc
@@ -845,7 +845,7 @@
         return nullptr;
     }
 
-    core::type::Type* ty = Type(param->type);
+    const core::type::Type* ty = Type(param->type);
     if (DAWN_UNLIKELY(!ty)) {
         return nullptr;
     }
@@ -1075,7 +1075,7 @@
     }
 
     // Resolve the return type
-    core::type::Type* return_type = nullptr;
+    const core::type::Type* return_type = nullptr;
     if (auto ty = decl->return_type) {
         return_type = Type(ty);
         if (!return_type) {
@@ -1164,7 +1164,7 @@
         }
     }
 
-    if (auto* str = return_type->As<core::type::Struct>()) {
+    if (auto* str = const_cast<core::type::Struct*>(return_type->As<core::type::Struct>())) {
         if (!ApplyAddressSpaceUsageToType(core::AddressSpace::kUndefined, str,
                                           decl->return_type->source)) {
             AddNote(decl->return_type->source)
@@ -1625,7 +1625,7 @@
     return sem_.AsFunctionExpression(Expression(expr));
 }
 
-core::type::Type* Resolver::Type(const ast::Expression* ast) {
+const core::type::Type* Resolver::Type(const ast::Expression* ast) {
     Vector<const sem::GlobalVariable*, 4> referenced_overrides;
     on_transitively_reference_global_.Push([&](const sem::GlobalVariable* ref) {
         if (ref->Declaration()->Is<ast::Override>()) {
@@ -2633,9 +2633,9 @@
     return call;
 }
 
-core::type::Type* Resolver::BuiltinType(core::BuiltinType builtin_ty,
-                                        const ast::Identifier* ident) {
-    auto check_no_tmpl_args = [&](core::type::Type* ty) -> core::type::Type* {
+const core::type::Type* Resolver::BuiltinType(core::BuiltinType builtin_ty,
+                                              const ast::Identifier* ident) {
+    auto check_no_tmpl_args = [&](const core::type::Type* ty) -> const core::type::Type* {
         return DAWN_LIKELY(CheckNotTemplated("type", ident)) ? ty : nullptr;
     };
 
@@ -2854,27 +2854,29 @@
     ICE(ident->source) << " unhandled builtin type '" << ident->symbol.NameView() << "'";
 }
 
-core::type::AbstractFloat* Resolver::AF() {
+const core::type::AbstractFloat* Resolver::AF() {
     return b.create<core::type::AbstractFloat>();
 }
 
-core::type::F32* Resolver::F32() {
+const core::type::F32* Resolver::F32() {
     return b.create<core::type::F32>();
 }
 
-core::type::I32* Resolver::I32() {
+const core::type::I32* Resolver::I32() {
     return b.create<core::type::I32>();
 }
 
-core::type::U32* Resolver::U32() {
+const core::type::U32* Resolver::U32() {
     return b.create<core::type::U32>();
 }
 
-core::type::F16* Resolver::F16(const ast::Identifier* ident) {
+const core::type::F16* Resolver::F16(const ast::Identifier* ident) {
     return validator_.CheckF16Enabled(ident->source) ? b.create<core::type::F16>() : nullptr;
 }
 
-core::type::Vector* Resolver::Vec(const ast::Identifier* ident, core::type::Type* el, uint32_t n) {
+const core::type::Vector* Resolver::Vec(const ast::Identifier* ident,
+                                        const core::type::Type* el,
+                                        uint32_t n) {
     if (DAWN_UNLIKELY(!el)) {
         return nullptr;
     }
@@ -2884,9 +2886,9 @@
     return b.create<core::type::Vector>(el, n);
 }
 
-core::type::Type* Resolver::VecT(const ast::Identifier* ident,
-                                 core::BuiltinType builtin,
-                                 uint32_t n) {
+const core::type::Type* Resolver::VecT(const ast::Identifier* ident,
+                                       core::BuiltinType builtin,
+                                       uint32_t n) {
     auto* tmpl_ident = ident->As<ast::TemplatedIdentifier>();
     if (!tmpl_ident) {
         // 'vecN' has no template arguments, so return an incomplete type.
@@ -2905,10 +2907,10 @@
     return Vec(ident, const_cast<core::type::Type*>(ty), n);
 }
 
-core::type::Matrix* Resolver::Mat(const ast::Identifier* ident,
-                                  core::type::Type* el,
-                                  uint32_t num_columns,
-                                  uint32_t num_rows) {
+const core::type::Matrix* Resolver::Mat(const ast::Identifier* ident,
+                                        const core::type::Type* el,
+                                        uint32_t num_columns,
+                                        uint32_t num_rows) {
     if (DAWN_UNLIKELY(!el)) {
         return nullptr;
     }
@@ -2922,10 +2924,10 @@
     return b.create<core::type::Matrix>(column, num_columns);
 }
 
-core::type::Type* Resolver::MatT(const ast::Identifier* ident,
-                                 core::BuiltinType builtin,
-                                 uint32_t num_columns,
-                                 uint32_t num_rows) {
+const core::type::Type* Resolver::MatT(const ast::Identifier* ident,
+                                       core::BuiltinType builtin,
+                                       uint32_t num_columns,
+                                       uint32_t num_rows) {
     auto* tmpl_ident = ident->As<ast::TemplatedIdentifier>();
     if (!tmpl_ident) {
         // 'vecN' has no template arguments, so return an incomplete type.
@@ -2944,7 +2946,7 @@
     return Mat(ident, const_cast<core::type::Type*>(el_ty), num_columns, num_rows);
 }
 
-core::type::Type* Resolver::Array(const ast::Identifier* ident) {
+const core::type::Type* Resolver::Array(const ast::Identifier* ident) {
     auto* tmpl_ident = ident->As<ast::TemplatedIdentifier>();
     if (!tmpl_ident) {
         // 'array' has no template arguments, so return an incomplete type.
@@ -2996,7 +2998,7 @@
     return out;
 }
 
-core::type::BindingArray* Resolver::BindingArray(const ast::Identifier* ident) {
+const core::type::BindingArray* Resolver::BindingArray(const ast::Identifier* ident) {
     auto* tmpl_ident = TemplatedIdentifier(ident, 2);
     if (DAWN_UNLIKELY(!tmpl_ident)) {
         return nullptr;
@@ -3020,7 +3022,7 @@
     return out;
 }
 
-core::type::Atomic* Resolver::Atomic(const ast::Identifier* ident) {
+const core::type::Atomic* Resolver::Atomic(const ast::Identifier* ident) {
     auto* tmpl_ident = TemplatedIdentifier(ident, 1);  // atomic<type>
     if (DAWN_UNLIKELY(!tmpl_ident)) {
         return nullptr;
@@ -3038,7 +3040,7 @@
     return out;
 }
 
-core::type::Pointer* Resolver::Ptr(const ast::Identifier* ident) {
+const core::type::Pointer* Resolver::Ptr(const ast::Identifier* ident) {
     auto* tmpl_ident = TemplatedIdentifier(ident, 2, 3);  // ptr<address, type [, access]>
     if (DAWN_UNLIKELY(!tmpl_ident)) {
         return nullptr;
@@ -3076,8 +3078,8 @@
     return out;
 }
 
-core::type::SampledTexture* Resolver::SampledTexture(const ast::Identifier* ident,
-                                                     core::type::TextureDimension dim) {
+const core::type::SampledTexture* Resolver::SampledTexture(const ast::Identifier* ident,
+                                                           core::type::TextureDimension dim) {
     auto* tmpl_ident = TemplatedIdentifier(ident, 1);
     if (DAWN_UNLIKELY(!tmpl_ident)) {
         return nullptr;
@@ -3092,8 +3094,9 @@
     return validator_.SampledTexture(out, ident->source) ? out : nullptr;
 }
 
-core::type::MultisampledTexture* Resolver::MultisampledTexture(const ast::Identifier* ident,
-                                                               core::type::TextureDimension dim) {
+const core::type::MultisampledTexture* Resolver::MultisampledTexture(
+    const ast::Identifier* ident,
+    core::type::TextureDimension dim) {
     auto* tmpl_ident = TemplatedIdentifier(ident, 1);
     if (DAWN_UNLIKELY(!tmpl_ident)) {
         return nullptr;
@@ -3108,8 +3111,8 @@
     return validator_.MultisampledTexture(out, ident->source) ? out : nullptr;
 }
 
-core::type::StorageTexture* Resolver::StorageTexture(const ast::Identifier* ident,
-                                                     core::type::TextureDimension dim) {
+const core::type::StorageTexture* Resolver::StorageTexture(const ast::Identifier* ident,
+                                                           core::type::TextureDimension dim) {
     auto* tmpl_ident = TemplatedIdentifier(ident, 2);
     if (DAWN_UNLIKELY(!tmpl_ident)) {
         return nullptr;
@@ -3125,8 +3128,7 @@
         return nullptr;
     }
 
-    auto* subtype = core::type::StorageTexture::SubtypeFor(format, b.Types());
-    auto* tex = b.create<core::type::StorageTexture>(dim, format, access, subtype);
+    auto* tex = b.Types().storage_texture(dim, format, access);
     if (!validator_.StorageTexture(tex, ident->source)) {
         return nullptr;
     }
@@ -3134,7 +3136,7 @@
     return tex;
 }
 
-core::type::InputAttachment* Resolver::InputAttachment(const ast::Identifier* ident) {
+const core::type::InputAttachment* Resolver::InputAttachment(const ast::Identifier* ident) {
     auto* tmpl_ident = TemplatedIdentifier(ident, 1);
     if (DAWN_UNLIKELY(!tmpl_ident)) {
         return nullptr;
@@ -3149,8 +3151,8 @@
     return validator_.InputAttachment(out, ident->source) ? out : nullptr;
 }
 
-core::type::SubgroupMatrix* Resolver::SubgroupMatrix(const ast::Identifier* ident,
-                                                     core::SubgroupMatrixKind kind) {
+const core::type::SubgroupMatrix* Resolver::SubgroupMatrix(const ast::Identifier* ident,
+                                                           core::SubgroupMatrixKind kind) {
     auto* tmpl_ident = TemplatedIdentifier(ident, 3);
     if (DAWN_UNLIKELY(!tmpl_ident)) {
         return nullptr;
@@ -4198,10 +4200,10 @@
     return true;
 }
 
-core::type::Type* Resolver::TypeDecl(const ast::TypeDecl* named_type) {
+const core::type::Type* Resolver::TypeDecl(const ast::TypeDecl* named_type) {
     Mark(named_type->name);
 
-    core::type::Type* result = nullptr;
+    const core::type::Type* result = nullptr;
     if (auto* alias = named_type->As<ast::Alias>()) {
         result = Alias(alias);
     } else if (auto* str = named_type->As<ast::Struct>()) {
@@ -4347,7 +4349,7 @@
     return out;
 }
 
-core::type::Type* Resolver::Alias(const ast::Alias* alias) {
+const core::type::Type* Resolver::Alias(const ast::Alias* alias) {
     auto* ty = Type(alias->type);
     if (DAWN_UNLIKELY(!ty)) {
         return nullptr;
@@ -4989,11 +4991,11 @@
 }
 
 bool Resolver::ApplyAddressSpaceUsageToType(core::AddressSpace address_space,
-                                            core::type::Type* ty,
+                                            const core::type::Type* ty,
                                             const Source& usage) {
     ty = const_cast<core::type::Type*>(ty->UnwrapRef());
 
-    if (auto* str = ty->As<sem::Struct>()) {
+    if (auto* str = const_cast<sem::Struct*>(ty->As<sem::Struct>())) {
         if (str->AddressSpaceUsage().Contains(address_space)) {
             return true;  // Already applied
         }
diff --git a/src/tint/lang/wgsl/resolver/resolver.h b/src/tint/lang/wgsl/resolver/resolver.h
index ee22feb..deb039e 100644
--- a/src/tint/lang/wgsl/resolver/resolver.h
+++ b/src/tint/lang/wgsl/resolver/resolver.h
@@ -161,79 +161,83 @@
     sem::FunctionExpression* FunctionExpression(const ast::Expression* expr);
 
     /// @returns the resolved type from an expression, or nullptr on error
-    core::type::Type* Type(const ast::Expression* ast);
+    const core::type::Type* Type(const ast::Expression* ast);
 
     /// @returns a new abstract-float
-    core::type::AbstractFloat* AF();
+    const core::type::AbstractFloat* AF();
 
     /// @returns a new f32
-    core::type::F32* F32();
+    const core::type::F32* F32();
 
     /// @returns a new i32
-    core::type::I32* I32();
+    const core::type::I32* I32();
 
     /// @returns a new u32
-    core::type::U32* U32();
+    const core::type::U32* U32();
 
     /// @returns a new f16, if the f16 extension is enabled, otherwise nullptr
-    core::type::F16* F16(const ast::Identifier* ident);
+    const core::type::F16* F16(const ast::Identifier* ident);
 
     /// @returns a vector with the element type @p el of width @p n resolved from the identifier @p
     /// ident.
-    core::type::Vector* Vec(const ast::Identifier* ident, core::type::Type* el, uint32_t n);
+    const core::type::Vector* Vec(const ast::Identifier* ident,
+                                  const core::type::Type* el,
+                                  uint32_t n);
 
     /// @returns a vector of width @p n resolved from the templated identifier @p ident, or an
     /// IncompleteType if the identifier is not templated.
-    core::type::Type* VecT(const ast::Identifier* ident, core::BuiltinType builtin, uint32_t n);
+    const core::type::Type* VecT(const ast::Identifier* ident,
+                                 core::BuiltinType builtin,
+                                 uint32_t n);
 
     /// @returns a matrix with the element type @p el of dimensions @p num_columns x @p num_rows
     /// resolved from the identifier @p ident.
-    core::type::Matrix* Mat(const ast::Identifier* ident,
-                            core::type::Type* el,
-                            uint32_t num_columns,
-                            uint32_t num_rows);
+    const core::type::Matrix* Mat(const ast::Identifier* ident,
+                                  const core::type::Type* el,
+                                  uint32_t num_columns,
+                                  uint32_t num_rows);
 
     /// @returns a matrix of dimensions @p num_columns x @p num_rows resolved from the templated
     /// identifier @p ident, or an IncompleteType if the identifier is not templated.
-    core::type::Type* MatT(const ast::Identifier* ident,
-                           core::BuiltinType builtin,
-                           uint32_t num_columns,
-                           uint32_t num_rows);
+    const core::type::Type* MatT(const ast::Identifier* ident,
+                                 core::BuiltinType builtin,
+                                 uint32_t num_columns,
+                                 uint32_t num_rows);
 
     /// @returns an array resolved from the templated identifier @p ident, or an IncompleteType if
     /// the identifier is not templated.
-    core::type::Type* Array(const ast::Identifier* ident);
+    const core::type::Type* Array(const ast::Identifier* ident);
 
     /// @returns a binding_array resolved from the templated identifier @p ident.
-    core::type::BindingArray* BindingArray(const ast::Identifier* ident);
+    const core::type::BindingArray* BindingArray(const ast::Identifier* ident);
 
     /// @returns an atomic resolved from the templated identifier @p ident.
-    core::type::Atomic* Atomic(const ast::Identifier* ident);
+    const core::type::Atomic* Atomic(const ast::Identifier* ident);
 
     /// @returns a pointer resolved from the templated identifier @p ident.
-    core::type::Pointer* Ptr(const ast::Identifier* ident);
+    const core::type::Pointer* Ptr(const ast::Identifier* ident);
 
     /// @returns a sampled texture resolved from the templated identifier @p ident with the
     /// dimensions @p dim.
-    core::type::SampledTexture* SampledTexture(const ast::Identifier* ident,
-                                               core::type::TextureDimension dim);
+    const core::type::SampledTexture* SampledTexture(const ast::Identifier* ident,
+                                                     core::type::TextureDimension dim);
 
     /// @returns a multisampled texture resolved from the templated identifier @p ident with the
     /// dimensions @p dim.
-    core::type::MultisampledTexture* MultisampledTexture(const ast::Identifier* ident,
-                                                         core::type::TextureDimension dim);
+    const core::type::MultisampledTexture* MultisampledTexture(const ast::Identifier* ident,
+                                                               core::type::TextureDimension dim);
 
     /// @returns a storage texture resolved from the templated identifier @p ident with the
     /// dimensions @p dim.
-    core::type::StorageTexture* StorageTexture(const ast::Identifier* ident,
-                                               core::type::TextureDimension dim);
+    const core::type::StorageTexture* StorageTexture(const ast::Identifier* ident,
+                                                     core::type::TextureDimension dim);
 
     /// @returns an input attachment resolved from the templated identifier @p ident
-    core::type::InputAttachment* InputAttachment(const ast::Identifier* ident);
+    const core::type::InputAttachment* InputAttachment(const ast::Identifier* ident);
 
     /// @returns a subgroup matrix resolved from the templated identifier @p ident
-    core::type::SubgroupMatrix* SubgroupMatrix(const ast::Identifier* ident,
-                                               core::SubgroupMatrixKind kind);
+    const core::type::SubgroupMatrix* SubgroupMatrix(const ast::Identifier* ident,
+                                                     core::SubgroupMatrixKind kind);
 
     /// @returns @p ident cast to an ast::TemplatedIdentifier, if the identifier is templated and
     /// the number of templated arguments are between @p min_args and @p max_args.
@@ -473,7 +477,7 @@
 
     /// @param named_type the named type to resolve
     /// @returns the resolved semantic type
-    core::type::Type* TypeDecl(const ast::TypeDecl* named_type);
+    const core::type::Type* TypeDecl(const ast::TypeDecl* named_type);
 
     /// Resolves and validates the expression used as the count parameter of an array.
     /// @param count_expr the expression used as the second template parameter to an array<>.
@@ -510,7 +514,7 @@
     /// This method does not mark the ast::Alias node, nor attach the generated
     /// semantic information to the AST node.
     /// @returns the aliased type, or nullptr if an error is raised.
-    core::type::Type* Alias(const ast::Alias* alias);
+    const core::type::Type* Alias(const ast::Alias* alias);
 
     /// Builds and returns the semantic information for the structure `str`.
     /// This method does not mark the ast::Struct node, nor attach the generated
@@ -577,7 +581,7 @@
     /// messages.
     /// @returns true on success, false on error
     bool ApplyAddressSpaceUsageToType(core::AddressSpace sc,
-                                      core::type::Type* ty,
+                                      const core::type::Type* ty,
                                       const Source& usage);
 
     /// @param address_space the address space
@@ -638,7 +642,7 @@
     /// @returns the core::type::Type for the builtin type @p builtin_ty with the identifier @p
     /// ident
     /// @note: Will raise an ICE if @p symbol is not a builtin type.
-    core::type::Type* BuiltinType(core::BuiltinType builtin_ty, const ast::Identifier* ident);
+    const core::type::Type* BuiltinType(core::BuiltinType builtin_ty, const ast::Identifier* ident);
 
     /// @returns the nesting depth of @ty as defined in
     /// https://gpuweb.github.io/gpuweb/wgsl/#composite-types
diff --git a/src/tint/lang/wgsl/writer/raise/ptr_to_ref.cc b/src/tint/lang/wgsl/writer/raise/ptr_to_ref.cc
index d34d889..19401b3 100644
--- a/src/tint/lang/wgsl/writer/raise/ptr_to_ref.cc
+++ b/src/tint/lang/wgsl/writer/raise/ptr_to_ref.cc
@@ -110,8 +110,7 @@
     }
 
     const core::type::Pointer* RefToPtr(const core::type::Reference* ref_ty) {
-        return mod.Types().Get<core::type::Pointer>(ref_ty->AddressSpace(), ref_ty->StoreType(),
-                                                    ref_ty->Access());
+        return mod.Types().ptr(ref_ty->AddressSpace(), ref_ty->StoreType(), ref_ty->Access());
     }
 
     void OperandPtrToRef(const core::ir::Usage& use) {
@@ -132,8 +131,7 @@
     }
 
     const core::type::Reference* PtrToRef(const core::type::Pointer* ptr_ty) {
-        return mod.Types().Get<core::type::Reference>(ptr_ty->AddressSpace(), ptr_ty->StoreType(),
-                                                      ptr_ty->Access());
+        return mod.Types().ref(ptr_ty->AddressSpace(), ptr_ty->StoreType(), ptr_ty->Access());
     }
 };