Import Tint changes from Dawn

Changes:
  - ffe356d558bce8b912890d8080dc7be94c0b0c2d tint/lexer: Add 'diagnostic' keyword by James Price <jrprice@google.com>
  - 57c0bbc2a5167f6ac63bd2f3b7fe0511c141a195 Move ast/texel_format to type/texel_format. by dan sinclair <dsinclair@chromium.org>
  - 61c16eb4487e54e0f6b816573b2fe2594b7d8e62 Move ast/access to type/access. by dan sinclair <dsinclair@chromium.org>
  - e2ff3431f420f4738624e99360f3f502fc15d9b0 Split transforms out to their on source target. by dan sinclair <dsinclair@chromium.org>
  - 18b2158b4e1431defc212a4b9e16b09ab036523d Move ast/address_space to type/ by dan sinclair <dsinclair@chromium.org>
  - 3cbf3fc4c520306ab15a54a4e22020fdfd4bb31c Move TextureDimension to type/ by dan sinclair <dsinclair@chromium.org>
  - d54dabeab522febb901a6567d3b1cd7d063faff8 Split the reader/ and writer/ out of libtint_core_all_src. by dan sinclair <dsinclair@chromium.org>
GitOrigin-RevId: ffe356d558bce8b912890d8080dc7be94c0b0c2d
Change-Id: I664de48ac60d7f6b49eb040f50e099a75d8e52f7
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/117524
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn
index 941fc83..4f6e892 100644
--- a/src/tint/BUILD.gn
+++ b/src/tint/BUILD.gn
@@ -113,7 +113,7 @@
     sources += [ "utils/io/tmpfile_other.cc" ]
   }
 
-  public_deps = [ ":libtint_core_all_src" ]
+  deps = [ ":libtint_core_all_src" ]
 }
 
 ###############################################################################
@@ -127,7 +127,10 @@
     "val/msl.cc",
     "val/val.h",
   ]
-  public_deps = [ ":tint_utils_io" ]
+  deps = [
+    ":libtint_core_all_src",
+    ":tint_utils_io",
+  ]
 }
 
 ###############################################################################
@@ -178,10 +181,6 @@
 
 libtint_source_set("libtint_core_all_src") {
   sources = [
-    "ast/access.cc",
-    "ast/access.h",
-    "ast/address_space.cc",
-    "ast/address_space.h",
     "ast/alias.cc",
     "ast/alias.h",
     "ast/array.cc",
@@ -332,8 +331,6 @@
     "ast/struct_member_size_attribute.h",
     "ast/switch_statement.cc",
     "ast/switch_statement.h",
-    "ast/texel_format.cc",
-    "ast/texel_format.h",
     "ast/texture.cc",
     "ast/texture.h",
     "ast/traverse_expressions.h",
@@ -398,8 +395,6 @@
     "program_builder.h",
     "program_id.cc",
     "program_id.h",
-    "reader/reader.cc",
-    "reader/reader.h",
     "reflection.h",
     "resolver/const_eval.cc",
     "resolver/const_eval.h",
@@ -457,6 +452,76 @@
     "text/unicode.h",
     "tint.cc",
     "traits.h",
+    "type/abstract_float.h",
+    "type/abstract_int.h",
+    "type/abstract_numeric.h",
+    "type/access.h",
+    "type/address_space.h",
+    "type/array.h",
+    "type/array_count.h",
+    "type/atomic.h",
+    "type/bool.h",
+    "type/clone_context.h",
+    "type/depth_multisampled_texture.h",
+    "type/depth_texture.h",
+    "type/external_texture.h",
+    "type/f16.h",
+    "type/f32.h",
+    "type/i32.h",
+    "type/manager.h",
+    "type/matrix.h",
+    "type/multisampled_texture.h",
+    "type/node.h",
+    "type/pointer.h",
+    "type/reference.h",
+    "type/sampled_texture.h",
+    "type/sampler.h",
+    "type/short_name.h",
+    "type/storage_texture.h",
+    "type/struct.h",
+    "type/texel_format.h",
+    "type/texture.h",
+    "type/texture_dimension.h",
+    "type/type.h",
+    "type/u32.h",
+    "type/unique_node.h",
+    "type/vector.h",
+    "type/void.h",
+    "utils/bitcast.h",
+    "utils/bitset.h",
+    "utils/block_allocator.h",
+    "utils/compiler_macros.h",
+    "utils/concat.h",
+    "utils/crc32.h",
+    "utils/debugger.cc",
+    "utils/debugger.h",
+    "utils/enum_set.h",
+    "utils/foreach_macro.h",
+    "utils/hash.h",
+    "utils/hashmap.h",
+    "utils/hashmap_base.h",
+    "utils/hashset.h",
+    "utils/map.h",
+    "utils/math.h",
+    "utils/scoped_assignment.h",
+    "utils/string.cc",
+    "utils/string.h",
+    "utils/unique_allocator.h",
+    "utils/unique_vector.h",
+    "utils/vector.h",
+  ]
+
+  if (is_linux || is_mac) {
+    sources += [ "diagnostic/printer_posix.cc" ]
+  } else if (is_win) {
+    sources += [ "diagnostic/printer_windows.cc" ]
+  } else {
+    sources += [ "diagnostic/printer_other.cc" ]
+  }
+}
+
+libtint_source_set("libtint_transform_src") {
+  sources = [
     "transform/add_block_attribute.cc",
     "transform/add_block_attribute.h",
     "transform/add_empty_entry_point.cc",
@@ -559,86 +624,8 @@
     "transform/while_to_loop.h",
     "transform/zero_init_workgroup_memory.cc",
     "transform/zero_init_workgroup_memory.h",
-    "type/abstract_float.h",
-    "type/abstract_int.h",
-    "type/abstract_numeric.h",
-    "type/array.h",
-    "type/array_count.h",
-    "type/atomic.h",
-    "type/bool.h",
-    "type/clone_context.h",
-    "type/depth_multisampled_texture.h",
-    "type/depth_texture.h",
-    "type/external_texture.h",
-    "type/f16.h",
-    "type/f32.h",
-    "type/i32.h",
-    "type/manager.h",
-    "type/matrix.h",
-    "type/multisampled_texture.h",
-    "type/node.h",
-    "type/pointer.h",
-    "type/reference.h",
-    "type/sampled_texture.h",
-    "type/sampler.h",
-    "type/short_name.h",
-    "type/storage_texture.h",
-    "type/struct.h",
-    "type/texture.h",
-    "type/type.h",
-    "type/u32.h",
-    "type/unique_node.h",
-    "type/vector.h",
-    "type/void.h",
-    "utils/bitcast.h",
-    "utils/bitset.h",
-    "utils/block_allocator.h",
-    "utils/compiler_macros.h",
-    "utils/concat.h",
-    "utils/crc32.h",
-    "utils/debugger.cc",
-    "utils/debugger.h",
-    "utils/enum_set.h",
-    "utils/foreach_macro.h",
-    "utils/hash.h",
-    "utils/hashmap.h",
-    "utils/hashmap_base.h",
-    "utils/hashset.h",
-    "utils/map.h",
-    "utils/math.h",
-    "utils/scoped_assignment.h",
-    "utils/string.cc",
-    "utils/string.h",
-    "utils/unique_allocator.h",
-    "utils/unique_vector.h",
-    "utils/vector.h",
-    "writer/append_vector.cc",
-    "writer/append_vector.h",
-    "writer/array_length_from_uniform_options.cc",
-    "writer/array_length_from_uniform_options.h",
-    "writer/check_supported_extensions.cc",
-    "writer/check_supported_extensions.h",
-    "writer/flatten_bindings.cc",
-    "writer/flatten_bindings.h",
-    "writer/float_to_string.cc",
-    "writer/float_to_string.h",
-    "writer/generate_external_texture_bindings.cc",
-    "writer/generate_external_texture_bindings.h",
-    "writer/text.cc",
-    "writer/text.h",
-    "writer/text_generator.cc",
-    "writer/text_generator.h",
-    "writer/writer.cc",
-    "writer/writer.h",
   ]
-
-  if (is_linux || is_mac) {
-    sources += [ "diagnostic/printer_posix.cc" ]
-  } else if (is_win) {
-    sources += [ "diagnostic/printer_windows.cc" ]
-  } else {
-    sources += [ "diagnostic/printer_other.cc" ]
-  }
+  deps = [ ":libtint_core_all_src" ]
 }
 
 libtint_source_set("libtint_sem_src") {
@@ -700,7 +687,7 @@
     "sem/while_statement.h",
   ]
 
-  public_deps = [ ":libtint_core_all_src" ]
+  deps = [ ":libtint_core_all_src" ]
 }
 
 libtint_source_set("libtint_type_src") {
@@ -711,6 +698,10 @@
     "type/abstract_int.h",
     "type/abstract_numeric.cc",
     "type/abstract_numeric.h",
+    "type/access.cc",
+    "type/access.h",
+    "type/address_space.cc",
+    "type/address_space.h",
     "type/array.cc",
     "type/array.h",
     "type/array_count.cc",
@@ -754,8 +745,12 @@
     "type/storage_texture.h",
     "type/struct.cc",
     "type/struct.h",
+    "type/texel_format.cc",
+    "type/texel_format.h",
     "type/texture.cc",
     "type/texture.h",
+    "type/texture_dimension.cc",
+    "type/texture_dimension.h",
     "type/type.cc",
     "type/type.h",
     "type/u32.cc",
@@ -768,7 +763,7 @@
     "type/void.h",
   ]
 
-  public_deps = [ ":libtint_core_all_src" ]
+  deps = [ ":libtint_core_all_src" ]
 }
 
 libtint_source_set("libtint_constant_src") {
@@ -785,7 +780,7 @@
     "constant/value.cc",
     "constant/value.h",
   ]
-  public_deps = [ ":libtint_core_all_src" ]
+  deps = [ ":libtint_core_all_src" ]
 }
 
 libtint_source_set("libtint_core_src") {
@@ -793,10 +788,22 @@
     ":libtint_constant_src",
     ":libtint_core_all_src",
     ":libtint_sem_src",
+    ":libtint_transform_src",
     ":libtint_type_src",
+    ":libtint_writer_src",
   ]
 }
 
+libtint_source_set("libtint_reader_src") {
+  sources = [
+    "reader/reader.cc",
+    "reader/reader.h",
+  ]
+
+  deps = [ ":libtint_core_all_src" ]
+  public_deps = [ ":libtint_transform_src" ]
+}
+
 libtint_source_set("libtint_spv_reader_src") {
   sources = [
     "reader/spirv/construct.cc",
@@ -820,14 +827,43 @@
     "reader/spirv/usage.h",
   ]
 
-  public_deps = [
-    ":libtint_core_src",
+  deps = [
+    ":libtint_core_all_src",
+    ":libtint_reader_src",
     "${tint_spirv_tools_dir}/:spvtools_opt",
   ]
 
   public_configs = [ "${tint_spirv_tools_dir}/:spvtools_internal_config" ]
 }
 
+libtint_source_set("libtint_writer_src") {
+  sources = [
+    "writer/append_vector.cc",
+    "writer/append_vector.h",
+    "writer/array_length_from_uniform_options.cc",
+    "writer/array_length_from_uniform_options.h",
+    "writer/check_supported_extensions.cc",
+    "writer/check_supported_extensions.h",
+    "writer/flatten_bindings.cc",
+    "writer/flatten_bindings.h",
+    "writer/float_to_string.cc",
+    "writer/float_to_string.h",
+    "writer/generate_external_texture_bindings.cc",
+    "writer/generate_external_texture_bindings.h",
+    "writer/text.cc",
+    "writer/text.h",
+    "writer/text_generator.cc",
+    "writer/text_generator.h",
+    "writer/writer.cc",
+    "writer/writer.h",
+  ]
+
+  deps = [
+    ":libtint_core_all_src",
+    ":libtint_transform_src",
+  ]
+}
+
 libtint_source_set("libtint_spv_writer_src") {
   sources = [
     "writer/spirv/binary_writer.cc",
@@ -847,7 +883,11 @@
     "writer/spirv/scalar_constant.h",
   ]
 
-  public_deps = [ ":libtint_core_src" ]
+  deps = [
+    ":libtint_core_src",
+    ":libtint_transform_src",
+    ":libtint_writer_src",
+  ]
 }
 
 libtint_source_set("libtint_wgsl_reader_src") {
@@ -863,7 +903,10 @@
     "reader/wgsl/token.h",
   ]
 
-  public_deps = [ ":libtint_core_src" ]
+  deps = [
+    ":libtint_core_all_src",
+    ":libtint_reader_src",
+  ]
 }
 
 libtint_source_set("libtint_wgsl_writer_src") {
@@ -874,7 +917,10 @@
     "writer/wgsl/generator_impl.h",
   ]
 
-  public_deps = [ ":libtint_core_src" ]
+  deps = [
+    ":libtint_core_src",
+    ":libtint_writer_src",
+  ]
 }
 
 libtint_source_set("libtint_msl_writer_src") {
@@ -885,7 +931,11 @@
     "writer/msl/generator_impl.h",
   ]
 
-  public_deps = [ ":libtint_core_src" ]
+  deps = [
+    ":libtint_core_src",
+    ":libtint_transform_src",
+    ":libtint_writer_src",
+  ]
 }
 
 libtint_source_set("libtint_hlsl_writer_src") {
@@ -896,7 +946,11 @@
     "writer/hlsl/generator_impl.h",
   ]
 
-  public_deps = [ ":libtint_core_src" ]
+  deps = [
+    ":libtint_core_src",
+    ":libtint_transform_src",
+    ":libtint_writer_src",
+  ]
 }
 
 libtint_source_set("libtint_glsl_writer_src") {
@@ -907,7 +961,11 @@
     "writer/glsl/generator_impl.h",
   ]
 
-  public_deps = [ ":libtint_core_src" ]
+  deps = [
+    ":libtint_core_src",
+    ":libtint_transform_src",
+    ":libtint_writer_src",
+  ]
 }
 
 source_set("libtint") {
@@ -1083,8 +1141,6 @@
 
   tint_unittests_source_set("tint_unittests_ast_src") {
     sources = [
-      "ast/access_test.cc",
-      "ast/address_space_test.cc",
       "ast/alias_test.cc",
       "ast/array_test.cc",
       "ast/assignment_statement_test.cc",
@@ -1149,7 +1205,6 @@
       "ast/struct_test.cc",
       "ast/switch_statement_test.cc",
       "ast/test_helper.h",
-      "ast/texel_format_test.cc",
       "ast/texture_test.cc",
       "ast/traverse_expressions_test.cc",
       "ast/u32_test.cc",
@@ -1160,6 +1215,7 @@
       "ast/while_statement_test.cc",
       "ast/workgroup_attribute_test.cc",
     ]
+    deps = [ ":libtint_transform_src" ]
   }
 
   tint_unittests_source_set("tint_unittests_diagnostic_src") {
@@ -1242,7 +1298,10 @@
       "resolver/variable_test.cc",
       "resolver/variable_validation_test.cc",
     ]
-    deps = [ ":tint_unittests_ast_src" ]
+    deps = [
+      ":libtint_transform_src",
+      ":tint_unittests_ast_src",
+    ]
   }
 
   tint_unittests_source_set("tint_unittests_sem_src") {
@@ -1263,6 +1322,8 @@
 
   tint_unittests_source_set("tint_unittests_type_src") {
     sources = [
+      "type/access_test.cc",
+      "type/address_space_test.cc",
       "type/array_test.cc",
       "type/atomic_test.cc",
       "type/bool_test.cc",
@@ -1282,6 +1343,7 @@
       "type/short_name_test.cc",
       "type/storage_texture_test.cc",
       "type/struct_test.cc",
+      "type/texel_format_test.cc",
       "type/texture_test.cc",
       "type/type_test.cc",
       "type/u32_test.cc",
@@ -1350,6 +1412,8 @@
       "transform/while_to_loop_test.cc",
       "transform/zero_init_workgroup_memory_test.cc",
     ]
+
+    deps = [ ":libtint_transform_src" ]
   }
 
   tint_unittests_source_set("tint_unittests_utils_src") {
@@ -1386,6 +1450,7 @@
       "writer/generate_external_texture_bindings_test.cc",
       "writer/text_generator_test.cc",
     ]
+    deps = [ ":libtint_writer_src" ]
   }
 
   tint_unittests_source_set("tint_unittests_spv_reader_src") {
@@ -1425,7 +1490,10 @@
       "reader/spirv/usage_test.cc",
     ]
 
-    deps = [ ":libtint_spv_reader_src" ]
+    deps = [
+      ":libtint_spv_reader_src",
+      "${tint_spirv_tools_dir}/:spvtools_opt",
+    ]
   }
 
   tint_unittests_source_set("tint_unittests_spv_writer_src") {
@@ -1672,6 +1740,7 @@
 
     deps = [
       ":libtint_hlsl_writer_src",
+      ":libtint_transform_src",
       ":tint_unittests_ast_src",
     ]
   }
@@ -1714,6 +1783,7 @@
 
     deps = [
       ":libtint_glsl_writer_src",
+      ":libtint_transform_src",
       ":tint_unittests_ast_src",
       ":tint_unittests_transform_src",
     ]
diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt
index 2f7bda7..95f2c86 100644
--- a/src/tint/CMakeLists.txt
+++ b/src/tint/CMakeLists.txt
@@ -514,6 +514,8 @@
   type/struct.h
   type/texture.cc
   type/texture.h
+  type/texture_dimension.cc
+  type/texture_dimension.h
   type/type.cc
   type/type.h
   type/u32.cc
@@ -564,16 +566,16 @@
   writer/writer.h
 )
 
-tint_generated(ast/access BENCH TEST)
-tint_generated(ast/address_space BENCH TEST)
 tint_generated(ast/builtin_value BENCH TEST)
 tint_generated(ast/extension BENCH TEST)
 tint_generated(ast/interpolate_attribute BENCH TEST)
-tint_generated(ast/texel_format BENCH TEST)
 tint_generated(resolver/init_conv_intrinsic)
 tint_generated(sem/builtin_type)
 tint_generated(sem/parameter_usage)
+tint_generated(type/access BENCH TEST)
+tint_generated(type/address_space BENCH TEST)
 tint_generated(type/short_name BENCH TEST)
+tint_generated(type/texel_format BENCH TEST)
 
 if(UNIX)
   list(APPEND TINT_LIB_SRCS diagnostic/printer_posix.cc)
diff --git a/src/tint/ast/alias_test.cc b/src/tint/ast/alias_test.cc
index c734751..20a9c5d 100644
--- a/src/tint/ast/alias_test.cc
+++ b/src/tint/ast/alias_test.cc
@@ -13,7 +13,6 @@
 // limitations under the License.
 
 #include "src/tint/ast/alias.h"
-#include "src/tint/ast/access.h"
 #include "src/tint/ast/array.h"
 #include "src/tint/ast/bool.h"
 #include "src/tint/ast/f32.h"
@@ -26,6 +25,7 @@
 #include "src/tint/ast/texture.h"
 #include "src/tint/ast/u32.h"
 #include "src/tint/ast/vector.h"
+#include "src/tint/type/access.h"
 
 namespace tint::ast {
 namespace {
diff --git a/src/tint/ast/builtin_texture_helper_test.cc b/src/tint/ast/builtin_texture_helper_test.cc
index 0ea2ced..b8fefa6 100644
--- a/src/tint/ast/builtin_texture_helper_test.cc
+++ b/src/tint/ast/builtin_texture_helper_test.cc
@@ -17,6 +17,7 @@
 #include "src/tint/type/depth_texture.h"
 #include "src/tint/type/multisampled_texture.h"
 #include "src/tint/type/sampled_texture.h"
+#include "src/tint/type/texture_dimension.h"
 
 using namespace tint::number_suffixes;  // NOLINT
 
@@ -26,7 +27,7 @@
                                          const char* desc,
                                          TextureKind tk,
                                          ast::SamplerKind sk,
-                                         ast::TextureDimension dims,
+                                         type::TextureDimension dims,
                                          TextureDataType datatype,
                                          const char* f,
                                          std::function<Args(ProgramBuilder*)> a)
@@ -41,7 +42,7 @@
 TextureOverloadCase::TextureOverloadCase(ValidTextureOverload o,
                                          const char* desc,
                                          TextureKind tk,
-                                         ast::TextureDimension dims,
+                                         type::TextureDimension dims,
                                          TextureDataType datatype,
                                          const char* f,
                                          std::function<Args(ProgramBuilder*)> a)
@@ -54,9 +55,9 @@
       args(std::move(a)) {}
 TextureOverloadCase::TextureOverloadCase(ValidTextureOverload o,
                                          const char* d,
-                                         Access acc,
-                                         ast::TexelFormat fmt,
-                                         ast::TextureDimension dims,
+                                         type::Access acc,
+                                         type::TexelFormat fmt,
+                                         type::TextureDimension dims,
                                          TextureDataType datatype,
                                          const char* f,
                                          std::function<Args(ProgramBuilder*)> a)
@@ -186,7 +187,7 @@
             "textureDimensions(t : texture_1d<f32>) -> u32",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k1d,
+            type::TextureDimension::k1d,
             TextureDataType::kF32,
             "textureDimensions",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -196,7 +197,7 @@
             "textureDimensions(t : texture_2d<f32>) -> vec2<u32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureDimensions",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -207,7 +208,7 @@
             "                  level : i32) -> vec2<u32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureDimensions",
             [](ProgramBuilder* b) { return b->ExprList("texture", 1_i); },
@@ -217,7 +218,7 @@
             "textureDimensions(t : texture_2d_array<f32>) -> vec2<u32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureDimensions",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -228,7 +229,7 @@
             "                  level : i32) -> vec2<u32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureDimensions",
             [](ProgramBuilder* b) { return b->ExprList("texture", 1_i); },
@@ -238,7 +239,7 @@
             "textureDimensions(t : texture_3d<f32>) -> vec3<u32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k3d,
+            type::TextureDimension::k3d,
             TextureDataType::kF32,
             "textureDimensions",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -249,7 +250,7 @@
             "                  level : i32) -> vec3<u32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k3d,
+            type::TextureDimension::k3d,
             TextureDataType::kF32,
             "textureDimensions",
             [](ProgramBuilder* b) { return b->ExprList("texture", 1_i); },
@@ -259,7 +260,7 @@
             "textureDimensions(t : texture_cube<f32>) -> vec2<u32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCube,
+            type::TextureDimension::kCube,
             TextureDataType::kF32,
             "textureDimensions",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -270,7 +271,7 @@
             "                  level : i32) -> vec2<u32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCube,
+            type::TextureDimension::kCube,
             TextureDataType::kF32,
             "textureDimensions",
             [](ProgramBuilder* b) { return b->ExprList("texture", 1_i); },
@@ -280,7 +281,7 @@
             "textureDimensions(t : texture_cube_array<f32>) -> vec2<u32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCubeArray,
+            type::TextureDimension::kCubeArray,
             TextureDataType::kF32,
             "textureDimensions",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -291,7 +292,7 @@
             "                  level : i32) -> vec2<u32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCubeArray,
+            type::TextureDimension::kCubeArray,
             TextureDataType::kF32,
             "textureDimensions",
             [](ProgramBuilder* b) { return b->ExprList("texture", 1_i); },
@@ -301,7 +302,7 @@
             "textureDimensions(t : texture_multisampled_2d<f32>)-> vec2<u32>",
             TextureKind::kMultisampled,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureDimensions",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -311,7 +312,7 @@
             "textureDimensions(t : texture_depth_2d) -> vec2<u32>",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureDimensions",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -322,7 +323,7 @@
             "                  level : i32) -> vec2<u32>",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureDimensions",
             [](ProgramBuilder* b) { return b->ExprList("texture", 1_i); },
@@ -332,7 +333,7 @@
             "textureDimensions(t : texture_depth_2d_array) -> vec2<u32>",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureDimensions",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -343,7 +344,7 @@
             "                  level : i32) -> vec2<u32>",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureDimensions",
             [](ProgramBuilder* b) { return b->ExprList("texture", 1_i); },
@@ -353,7 +354,7 @@
             "textureDimensions(t : texture_depth_cube) -> vec2<u32>",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCube,
+            type::TextureDimension::kCube,
             TextureDataType::kF32,
             "textureDimensions",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -364,7 +365,7 @@
             "                  level : i32) -> vec2<u32>",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCube,
+            type::TextureDimension::kCube,
             TextureDataType::kF32,
             "textureDimensions",
             [](ProgramBuilder* b) { return b->ExprList("texture", 1_i); },
@@ -374,7 +375,7 @@
             "textureDimensions(t : texture_depth_cube_array) -> vec2<u32>",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCubeArray,
+            type::TextureDimension::kCubeArray,
             TextureDataType::kF32,
             "textureDimensions",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -385,7 +386,7 @@
             "                  level : i32) -> vec2<u32>",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCubeArray,
+            type::TextureDimension::kCubeArray,
             TextureDataType::kF32,
             "textureDimensions",
             [](ProgramBuilder* b) { return b->ExprList("texture", 1_i); },
@@ -395,7 +396,7 @@
             "textureDimensions(t : texture_depth_multisampled_2d) -> vec2<u32>",
             TextureKind::kDepthMultisampled,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureDimensions",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -403,9 +404,9 @@
         {
             ValidTextureOverload::kDimensionsStorageWO1d,
             "textureDimensions(t : texture_storage_1d<rgba32float>) -> u32",
-            ast::Access::kWrite,
-            ast::TexelFormat::kRgba32Float,
-            ast::TextureDimension::k1d,
+            type::Access::kWrite,
+            type::TexelFormat::kRgba32Float,
+            type::TextureDimension::k1d,
             TextureDataType::kF32,
             "textureDimensions",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -413,9 +414,9 @@
         {
             ValidTextureOverload::kDimensionsStorageWO2d,
             "textureDimensions(t : texture_storage_2d<rgba32float>) -> vec2<u32>",
-            ast::Access::kWrite,
-            ast::TexelFormat::kRgba32Float,
-            ast::TextureDimension::k2d,
+            type::Access::kWrite,
+            type::TexelFormat::kRgba32Float,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureDimensions",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -423,9 +424,9 @@
         {
             ValidTextureOverload::kDimensionsStorageWO2dArray,
             "textureDimensions(t : texture_storage_2d_array<rgba32float>) -> vec2<u32>",
-            ast::Access::kWrite,
-            ast::TexelFormat::kRgba32Float,
-            ast::TextureDimension::k2dArray,
+            type::Access::kWrite,
+            type::TexelFormat::kRgba32Float,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureDimensions",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -433,9 +434,9 @@
         {
             ValidTextureOverload::kDimensionsStorageWO3d,
             "textureDimensions(t : texture_storage_3d<rgba32float>) -> vec3<u32>",
-            ast::Access::kWrite,
-            ast::TexelFormat::kRgba32Float,
-            ast::TextureDimension::k3d,
+            type::Access::kWrite,
+            type::TexelFormat::kRgba32Float,
+            type::TextureDimension::k3d,
             TextureDataType::kF32,
             "textureDimensions",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -449,7 +450,7 @@
             "              coords    : vec2<f32>) -> vec4<T>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureGather",
             [](ProgramBuilder* b) {
@@ -468,7 +469,7 @@
             "              offset    : vec2<i32>) -> vec4<T>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureGather",
             [](ProgramBuilder* b) {
@@ -488,7 +489,7 @@
             "              array_index : i32) -> vec4<T>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureGather",
             [](ProgramBuilder* b) {
@@ -509,7 +510,7 @@
             "              offset      : vec2<i32>) -> vec4<T>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureGather",
             [](ProgramBuilder* b) {
@@ -529,7 +530,7 @@
             "              coords    : vec3<f32>) -> vec4<T>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCube,
+            type::TextureDimension::kCube,
             TextureDataType::kF32,
             "textureGather",
             [](ProgramBuilder* b) {
@@ -548,7 +549,7 @@
             "              array_index : u32) -> vec4<T>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCubeArray,
+            type::TextureDimension::kCubeArray,
             TextureDataType::kF32,
             "textureGather",
             [](ProgramBuilder* b) {
@@ -566,7 +567,7 @@
             "              coords : vec2<f32>) -> vec4<f32>",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureGather",
             [](ProgramBuilder* b) {
@@ -583,7 +584,7 @@
             "              offset : vec2<i32>) -> vec4<f32>",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureGather",
             [](ProgramBuilder* b) {
@@ -601,7 +602,7 @@
             "              array_index : u32) -> vec4<f32>",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureGather",
             [](ProgramBuilder* b) {
@@ -620,7 +621,7 @@
             "              offset      : vec2<i32>) -> vec4<f32>",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureGather",
             [](ProgramBuilder* b) {
@@ -638,7 +639,7 @@
             "              coords : vec3<f32>) -> vec4<f32>",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCube,
+            type::TextureDimension::kCube,
             TextureDataType::kF32,
             "textureGather",
             [](ProgramBuilder* b) {
@@ -655,7 +656,7 @@
             "              array_index : u32) -> vec4<f32>",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCubeArray,
+            type::TextureDimension::kCubeArray,
             TextureDataType::kF32,
             "textureGather",
             [](ProgramBuilder* b) {
@@ -673,7 +674,7 @@
             "                     depth_ref : f32) -> vec4<f32>",
             TextureKind::kDepth,
             ast::SamplerKind::kComparisonSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureGatherCompare",
             [](ProgramBuilder* b) {
@@ -692,7 +693,7 @@
             "                     offset    : vec2<i32>) -> vec4<f32>",
             TextureKind::kDepth,
             ast::SamplerKind::kComparisonSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureGatherCompare",
             [](ProgramBuilder* b) {
@@ -712,7 +713,7 @@
             "                     depth_ref   : f32) -> vec4<f32>",
             TextureKind::kDepth,
             ast::SamplerKind::kComparisonSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureGatherCompare",
             [](ProgramBuilder* b) {
@@ -733,7 +734,7 @@
             "                     offset      : vec2<i32>) -> vec4<f32>",
             TextureKind::kDepth,
             ast::SamplerKind::kComparisonSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureGatherCompare",
             [](ProgramBuilder* b) {
@@ -753,7 +754,7 @@
             "                     depth_ref : f32) -> vec4<f32>",
             TextureKind::kDepth,
             ast::SamplerKind::kComparisonSampler,
-            ast::TextureDimension::kCube,
+            type::TextureDimension::kCube,
             TextureDataType::kF32,
             "textureGatherCompare",
             [](ProgramBuilder* b) {
@@ -772,7 +773,7 @@
             "                     depth_ref   : f32) -> vec4<f32>",
             TextureKind::kDepth,
             ast::SamplerKind::kComparisonSampler,
-            ast::TextureDimension::kCubeArray,
+            type::TextureDimension::kCubeArray,
             TextureDataType::kF32,
             "textureGatherCompare",
             [](ProgramBuilder* b) {
@@ -788,7 +789,7 @@
             "textureNumLayers(t : texture_2d_array<f32>) -> u32",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureNumLayers",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -798,7 +799,7 @@
             "textureNumLayers(t : texture_cube_array<f32>) -> u32",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCubeArray,
+            type::TextureDimension::kCubeArray,
             TextureDataType::kF32,
             "textureNumLayers",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -808,7 +809,7 @@
             "textureNumLayers(t : texture_depth_2d_array) -> u32",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureNumLayers",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -818,7 +819,7 @@
             "textureNumLayers(t : texture_depth_cube_array) -> u32",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCubeArray,
+            type::TextureDimension::kCubeArray,
             TextureDataType::kF32,
             "textureNumLayers",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -826,9 +827,9 @@
         {
             ValidTextureOverload::kNumLayersStorageWO2dArray,
             "textureNumLayers(t : texture_storage_2d_array<rgba32float>) -> u32",
-            ast::Access::kWrite,
-            ast::TexelFormat::kRgba32Float,
-            ast::TextureDimension::k2dArray,
+            type::Access::kWrite,
+            type::TexelFormat::kRgba32Float,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureNumLayers",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -838,7 +839,7 @@
             "textureNumLevels(t : texture_2d<f32>) -> u32",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureNumLevels",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -848,7 +849,7 @@
             "textureNumLevels(t : texture_2d_array<f32>) -> u32",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureNumLevels",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -858,7 +859,7 @@
             "textureNumLevels(t : texture_3d<f32>) -> u32",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k3d,
+            type::TextureDimension::k3d,
             TextureDataType::kF32,
             "textureNumLevels",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -868,7 +869,7 @@
             "textureNumLevels(t : texture_cube<f32>) -> u32",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCube,
+            type::TextureDimension::kCube,
             TextureDataType::kF32,
             "textureNumLevels",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -878,7 +879,7 @@
             "textureNumLevels(t : texture_cube_array<f32>) -> u32",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCubeArray,
+            type::TextureDimension::kCubeArray,
             TextureDataType::kF32,
             "textureNumLevels",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -888,7 +889,7 @@
             "textureNumLevels(t : texture_depth_2d) -> u32",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureNumLevels",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -898,7 +899,7 @@
             "textureNumLevels(t : texture_depth_2d_array) -> u32",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureNumLevels",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -908,7 +909,7 @@
             "textureNumLevels(t : texture_depth_cube) -> u32",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCube,
+            type::TextureDimension::kCube,
             TextureDataType::kF32,
             "textureNumLevels",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -918,7 +919,7 @@
             "textureNumLevels(t : texture_depth_cube_array) -> u32",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCubeArray,
+            type::TextureDimension::kCubeArray,
             TextureDataType::kF32,
             "textureNumLevels",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -928,7 +929,7 @@
             "textureNumSamples(t : texture_multisampled_2d<f32>) -> u32",
             TextureKind::kMultisampled,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureNumSamples",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -938,7 +939,7 @@
             "textureNumSamples(t : texture_depth_multisampled_2d<f32>) -> u32",
             TextureKind::kMultisampled,
             ast::SamplerKind::kComparisonSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureNumSamples",
             [](ProgramBuilder* b) { return b->ExprList("texture"); },
@@ -950,7 +951,7 @@
             "              coords : f32) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k1d,
+            type::TextureDimension::k1d,
             TextureDataType::kF32,
             "textureSample",
             [](ProgramBuilder* b) {
@@ -966,7 +967,7 @@
             "              coords : vec2<f32>) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureSample",
             [](ProgramBuilder* b) {
@@ -983,7 +984,7 @@
             "              offset : vec2<i32>) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureSample",
             [](ProgramBuilder* b) {
@@ -1001,7 +1002,7 @@
             "              array_index : i32) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureSample",
             [](ProgramBuilder* b) {
@@ -1020,7 +1021,7 @@
             "              offset      : vec2<i32>) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureSample",
             [](ProgramBuilder* b) {
@@ -1038,7 +1039,7 @@
             "              coords : vec3<f32>) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k3d,
+            type::TextureDimension::k3d,
             TextureDataType::kF32,
             "textureSample",
             [](ProgramBuilder* b) {
@@ -1055,7 +1056,7 @@
             "              offset : vec3<i32>) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k3d,
+            type::TextureDimension::k3d,
             TextureDataType::kF32,
             "textureSample",
             [](ProgramBuilder* b) {
@@ -1072,7 +1073,7 @@
             "              coords : vec3<f32>) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCube,
+            type::TextureDimension::kCube,
             TextureDataType::kF32,
             "textureSample",
             [](ProgramBuilder* b) {
@@ -1089,7 +1090,7 @@
             "              array_index : i32) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCubeArray,
+            type::TextureDimension::kCubeArray,
             TextureDataType::kF32,
             "textureSample",
             [](ProgramBuilder* b) {
@@ -1106,7 +1107,7 @@
             "              coords : vec2<f32>) -> f32",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureSample",
             [](ProgramBuilder* b) {
@@ -1123,7 +1124,7 @@
             "              offset : vec2<i32>) -> f32",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureSample",
             [](ProgramBuilder* b) {
@@ -1141,7 +1142,7 @@
             "              array_index : i32) -> f32",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureSample",
             [](ProgramBuilder* b) {
@@ -1160,7 +1161,7 @@
             "              offset      : vec2<i32>) -> f32",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureSample",
             [](ProgramBuilder* b) {
@@ -1178,7 +1179,7 @@
             "              coords : vec3<f32>) -> f32",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCube,
+            type::TextureDimension::kCube,
             TextureDataType::kF32,
             "textureSample",
             [](ProgramBuilder* b) {
@@ -1195,7 +1196,7 @@
             "              array_index : u32) -> f32",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCubeArray,
+            type::TextureDimension::kCubeArray,
             TextureDataType::kF32,
             "textureSample",
             [](ProgramBuilder* b) {
@@ -1213,7 +1214,7 @@
             "                  bias   : f32) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureSampleBias",
             [](ProgramBuilder* b) {
@@ -1232,7 +1233,7 @@
             "                  offset : vec2<i32>) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureSampleBias",
             [](ProgramBuilder* b) {
@@ -1252,7 +1253,7 @@
             "                  bias        : f32) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureSampleBias",
             [](ProgramBuilder* b) {
@@ -1273,7 +1274,7 @@
             "                  offset      : vec2<i32>) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureSampleBias",
             [](ProgramBuilder* b) {
@@ -1293,7 +1294,7 @@
             "                  bias   : f32) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k3d,
+            type::TextureDimension::k3d,
             TextureDataType::kF32,
             "textureSampleBias",
             [](ProgramBuilder* b) {
@@ -1312,7 +1313,7 @@
             "                  offset : vec3<i32>) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k3d,
+            type::TextureDimension::k3d,
             TextureDataType::kF32,
             "textureSampleBias",
             [](ProgramBuilder* b) {
@@ -1331,7 +1332,7 @@
             "                  bias   : f32) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCube,
+            type::TextureDimension::kCube,
             TextureDataType::kF32,
             "textureSampleBias",
             [](ProgramBuilder* b) {
@@ -1350,7 +1351,7 @@
             "                  bias        : f32) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCubeArray,
+            type::TextureDimension::kCubeArray,
             TextureDataType::kF32,
             "textureSampleBias",
             [](ProgramBuilder* b) {
@@ -1369,7 +1370,7 @@
             "                   level  : f32) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureSampleLevel",
             [](ProgramBuilder* b) {
@@ -1388,7 +1389,7 @@
             "                   offset : vec2<i32>) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureSampleLevel",
             [](ProgramBuilder* b) {
@@ -1408,7 +1409,7 @@
             "                   level       : f32) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureSampleLevel",
             [](ProgramBuilder* b) {
@@ -1429,7 +1430,7 @@
             "                   offset      : vec2<i32>) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureSampleLevel",
             [](ProgramBuilder* b) {
@@ -1449,7 +1450,7 @@
             "                   level  : f32) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k3d,
+            type::TextureDimension::k3d,
             TextureDataType::kF32,
             "textureSampleLevel",
             [](ProgramBuilder* b) {
@@ -1468,7 +1469,7 @@
             "                   offset : vec3<i32>) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k3d,
+            type::TextureDimension::k3d,
             TextureDataType::kF32,
             "textureSampleLevel",
             [](ProgramBuilder* b) {
@@ -1487,7 +1488,7 @@
             "                   level  : f32) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCube,
+            type::TextureDimension::kCube,
             TextureDataType::kF32,
             "textureSampleLevel",
             [](ProgramBuilder* b) {
@@ -1506,7 +1507,7 @@
             "                   level       : f32) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCubeArray,
+            type::TextureDimension::kCubeArray,
             TextureDataType::kF32,
             "textureSampleLevel",
             [](ProgramBuilder* b) {
@@ -1525,7 +1526,7 @@
             "                   level  : u32) -> f32",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureSampleLevel",
             [](ProgramBuilder* b) {
@@ -1544,7 +1545,7 @@
             "                   offset : vec2<i32>) -> f32",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureSampleLevel",
             [](ProgramBuilder* b) {
@@ -1564,7 +1565,7 @@
             "                   level       : u32) -> f32",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureSampleLevel",
             [](ProgramBuilder* b) {
@@ -1585,7 +1586,7 @@
             "                   offset      : vec2<i32>) -> f32",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureSampleLevel",
             [](ProgramBuilder* b) {
@@ -1605,7 +1606,7 @@
             "                   level  : i32) -> f32",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCube,
+            type::TextureDimension::kCube,
             TextureDataType::kF32,
             "textureSampleLevel",
             [](ProgramBuilder* b) {
@@ -1624,7 +1625,7 @@
             "                   level       : i32) -> f32",
             TextureKind::kDepth,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCubeArray,
+            type::TextureDimension::kCubeArray,
             TextureDataType::kF32,
             "textureSampleLevel",
             [](ProgramBuilder* b) {
@@ -1644,7 +1645,7 @@
             "                  ddy    : vec2<f32>) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureSampleGrad",
             [](ProgramBuilder* b) {
@@ -1665,7 +1666,7 @@
             "                  offset : vec2<i32>) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureSampleGrad",
             [](ProgramBuilder* b) {
@@ -1687,7 +1688,7 @@
             "                  ddy         : vec2<f32>) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureSampleGrad",
             [](ProgramBuilder* b) {
@@ -1710,7 +1711,7 @@
             "                  offset      : vec2<i32>) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureSampleGrad",
             [](ProgramBuilder* b) {
@@ -1732,7 +1733,7 @@
             "                  ddy    : vec3<f32>) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k3d,
+            type::TextureDimension::k3d,
             TextureDataType::kF32,
             "textureSampleGrad",
             [](ProgramBuilder* b) {
@@ -1753,7 +1754,7 @@
             "                  offset : vec3<i32>) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::k3d,
+            type::TextureDimension::k3d,
             TextureDataType::kF32,
             "textureSampleGrad",
             [](ProgramBuilder* b) {
@@ -1774,7 +1775,7 @@
             "                  ddy    : vec3<f32>) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCube,
+            type::TextureDimension::kCube,
             TextureDataType::kF32,
             "textureSampleGrad",
             [](ProgramBuilder* b) {
@@ -1795,7 +1796,7 @@
             "                  ddy         : vec3<f32>) -> vec4<f32>",
             TextureKind::kRegular,
             ast::SamplerKind::kSampler,
-            ast::TextureDimension::kCubeArray,
+            type::TextureDimension::kCubeArray,
             TextureDataType::kF32,
             "textureSampleGrad",
             [](ProgramBuilder* b) {
@@ -1815,7 +1816,7 @@
             "                     depth_ref : f32) -> f32",
             TextureKind::kDepth,
             ast::SamplerKind::kComparisonSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureSampleCompare",
             [](ProgramBuilder* b) {
@@ -1834,7 +1835,7 @@
             "                     offset    : vec2<i32>) -> f32",
             TextureKind::kDepth,
             ast::SamplerKind::kComparisonSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureSampleCompare",
             [](ProgramBuilder* b) {
@@ -1854,7 +1855,7 @@
             "                     depth_ref   : f32) -> f32",
             TextureKind::kDepth,
             ast::SamplerKind::kComparisonSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureSampleCompare",
             [](ProgramBuilder* b) {
@@ -1875,7 +1876,7 @@
             "                     offset      : vec2<i32>) -> f32",
             TextureKind::kDepth,
             ast::SamplerKind::kComparisonSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureSampleCompare",
             [](ProgramBuilder* b) {
@@ -1895,7 +1896,7 @@
             "                     depth_ref : f32) -> f32",
             TextureKind::kDepth,
             ast::SamplerKind::kComparisonSampler,
-            ast::TextureDimension::kCube,
+            type::TextureDimension::kCube,
             TextureDataType::kF32,
             "textureSampleCompare",
             [](ProgramBuilder* b) {
@@ -1914,7 +1915,7 @@
             "                     depth_ref   : f32) -> f32",
             TextureKind::kDepth,
             ast::SamplerKind::kComparisonSampler,
-            ast::TextureDimension::kCubeArray,
+            type::TextureDimension::kCubeArray,
             TextureDataType::kF32,
             "textureSampleCompare",
             [](ProgramBuilder* b) {
@@ -1933,7 +1934,7 @@
             "                          depth_ref : f32) -> f32",
             TextureKind::kDepth,
             ast::SamplerKind::kComparisonSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureSampleCompareLevel",
             [](ProgramBuilder* b) {
@@ -1952,7 +1953,7 @@
             "                          offset    : vec2<i32>) -> f32",
             TextureKind::kDepth,
             ast::SamplerKind::kComparisonSampler,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureSampleCompareLevel",
             [](ProgramBuilder* b) {
@@ -1972,7 +1973,7 @@
             "                          depth_ref   : f32) -> f32",
             TextureKind::kDepth,
             ast::SamplerKind::kComparisonSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureSampleCompareLevel",
             [](ProgramBuilder* b) {
@@ -1993,7 +1994,7 @@
             "                          offset      : vec2<i32>) -> f32",
             TextureKind::kDepth,
             ast::SamplerKind::kComparisonSampler,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureSampleCompareLevel",
             [](ProgramBuilder* b) {
@@ -2013,7 +2014,7 @@
             "                          depth_ref   : f32) -> f32",
             TextureKind::kDepth,
             ast::SamplerKind::kComparisonSampler,
-            ast::TextureDimension::kCube,
+            type::TextureDimension::kCube,
             TextureDataType::kF32,
             "textureSampleCompareLevel",
             [](ProgramBuilder* b) {
@@ -2032,7 +2033,7 @@
             "                          depth_ref   : f32) -> f32",
             TextureKind::kDepth,
             ast::SamplerKind::kComparisonSampler,
-            ast::TextureDimension::kCubeArray,
+            type::TextureDimension::kCubeArray,
             TextureDataType::kF32,
             "textureSampleCompareLevel",
             [](ProgramBuilder* b) {
@@ -2049,7 +2050,7 @@
             "            coords : u32,\n"
             "            level  : u32) -> vec4<f32>",
             TextureKind::kRegular,
-            ast::TextureDimension::k1d,
+            type::TextureDimension::k1d,
             TextureDataType::kF32,
             "textureLoad",
             [](ProgramBuilder* b) {
@@ -2064,7 +2065,7 @@
             "            coords : i32,\n"
             "            level  : i32) -> vec4<u32>",
             TextureKind::kRegular,
-            ast::TextureDimension::k1d,
+            type::TextureDimension::k1d,
             TextureDataType::kU32,
             "textureLoad",
             [](ProgramBuilder* b) {
@@ -2079,7 +2080,7 @@
             "            coords : i32,\n"
             "            level  : i32) -> vec4<i32>",
             TextureKind::kRegular,
-            ast::TextureDimension::k1d,
+            type::TextureDimension::k1d,
             TextureDataType::kI32,
             "textureLoad",
             [](ProgramBuilder* b) {
@@ -2094,7 +2095,7 @@
             "            coords : vec2<u32>,\n"
             "            level  : u32) -> vec4<f32>",
             TextureKind::kRegular,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureLoad",
             [](ProgramBuilder* b) {
@@ -2109,7 +2110,7 @@
             "            coords : vec2<i32>,\n"
             "            level  : i32) -> vec4<u32>",
             TextureKind::kRegular,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kU32,
             "textureLoad",
             [](ProgramBuilder* b) {
@@ -2124,7 +2125,7 @@
             "            coords : vec2<u32>,\n"
             "            level  : u32) -> vec4<i32>",
             TextureKind::kRegular,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kI32,
             "textureLoad",
             [](ProgramBuilder* b) {
@@ -2140,7 +2141,7 @@
             "            array_index : i32,\n"
             "            level       : i32) -> vec4<f32>",
             TextureKind::kRegular,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureLoad",
             [](ProgramBuilder* b) {
@@ -2157,7 +2158,7 @@
             "            array_index : i32,\n"
             "            level       : i32) -> vec4<u32>",
             TextureKind::kRegular,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kU32,
             "textureLoad",
             [](ProgramBuilder* b) {
@@ -2174,7 +2175,7 @@
             "            array_index : u32,\n"
             "            level       : u32) -> vec4<i32>",
             TextureKind::kRegular,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kI32,
             "textureLoad",
             [](ProgramBuilder* b) {
@@ -2190,7 +2191,7 @@
             "            coords : vec3<i32>,\n"
             "            level  : i32) -> vec4<f32>",
             TextureKind::kRegular,
-            ast::TextureDimension::k3d,
+            type::TextureDimension::k3d,
             TextureDataType::kF32,
             "textureLoad",
             [](ProgramBuilder* b) {
@@ -2205,7 +2206,7 @@
             "            coords : vec3<i32>,\n"
             "            level  : i32) -> vec4<u32>",
             TextureKind::kRegular,
-            ast::TextureDimension::k3d,
+            type::TextureDimension::k3d,
             TextureDataType::kU32,
             "textureLoad",
             [](ProgramBuilder* b) {
@@ -2220,7 +2221,7 @@
             "            coords : vec3<u32>,\n"
             "            level  : u32) -> vec4<i32>",
             TextureKind::kRegular,
-            ast::TextureDimension::k3d,
+            type::TextureDimension::k3d,
             TextureDataType::kI32,
             "textureLoad",
             [](ProgramBuilder* b) {
@@ -2235,7 +2236,7 @@
             "            coords       : vec2<i32>,\n"
             "            sample_index : i32) -> vec4<f32>",
             TextureKind::kMultisampled,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureLoad",
             [](ProgramBuilder* b) {
@@ -2250,7 +2251,7 @@
             "            coords       : vec2<i32>,\n"
             "            sample_index : i32) -> vec4<u32>",
             TextureKind::kMultisampled,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kU32,
             "textureLoad",
             [](ProgramBuilder* b) {
@@ -2265,7 +2266,7 @@
             "            coords       : vec2<u32>,\n"
             "            sample_index : u32) -> vec4<i32>",
             TextureKind::kMultisampled,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kI32,
             "textureLoad",
             [](ProgramBuilder* b) {
@@ -2280,7 +2281,7 @@
             "            coords : vec2<i32>,\n"
             "            level  : i32) -> f32",
             TextureKind::kDepth,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureLoad",
             [](ProgramBuilder* b) {
@@ -2296,7 +2297,7 @@
             "            array_index : u32,\n"
             "            level       : u32) -> f32",
             TextureKind::kDepth,
-            ast::TextureDimension::k2dArray,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureLoad",
             [](ProgramBuilder* b) {
@@ -2312,7 +2313,7 @@
             "            coords       : vec2<u32>,\n"
             "            sample_index : u32) -> f32",
             TextureKind::kDepthMultisampled,
-            ast::TextureDimension::k2d,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureLoad",
             [](ProgramBuilder* b) {
@@ -2326,9 +2327,9 @@
             "textureStore(t      : texture_storage_1d<rgba32float>,\n"
             "             coords : i32,\n"
             "             value  : vec4<T>)",
-            ast::Access::kWrite,
-            ast::TexelFormat::kRgba32Float,
-            ast::TextureDimension::k1d,
+            type::Access::kWrite,
+            type::TexelFormat::kRgba32Float,
+            type::TextureDimension::k1d,
             TextureDataType::kF32,
             "textureStore",
             [](ProgramBuilder* b) {
@@ -2342,9 +2343,9 @@
             "textureStore(t      : texture_storage_2d<rgba32float>,\n"
             "             coords : vec2<i32>,\n"
             "             value  : vec4<T>)",
-            ast::Access::kWrite,
-            ast::TexelFormat::kRgba32Float,
-            ast::TextureDimension::k2d,
+            type::Access::kWrite,
+            type::TexelFormat::kRgba32Float,
+            type::TextureDimension::k2d,
             TextureDataType::kF32,
             "textureStore",
             [](ProgramBuilder* b) {
@@ -2359,9 +2360,9 @@
             "             coords      : vec2<u32>,\n"
             "             array_index : u32,\n"
             "             value       : vec4<T>)",
-            ast::Access::kWrite,
-            ast::TexelFormat::kRgba32Float,
-            ast::TextureDimension::k2dArray,
+            type::Access::kWrite,
+            type::TexelFormat::kRgba32Float,
+            type::TextureDimension::k2dArray,
             TextureDataType::kF32,
             "textureStore",
             [](ProgramBuilder* b) {
@@ -2376,9 +2377,9 @@
             "textureStore(t      : texture_storage_3d<rgba32float>,\n"
             "             coords : vec3<u32>,\n"
             "             value  : vec4<T>)",
-            ast::Access::kWrite,
-            ast::TexelFormat::kRgba32Float,
-            ast::TextureDimension::k3d,
+            type::Access::kWrite,
+            type::TexelFormat::kRgba32Float,
+            type::TextureDimension::k3d,
             TextureDataType::kF32,
             "textureStore",
             [](ProgramBuilder* b) {
diff --git a/src/tint/ast/builtin_texture_helper_test.h b/src/tint/ast/builtin_texture_helper_test.h
index 744796a..a17dd37 100644
--- a/src/tint/ast/builtin_texture_helper_test.h
+++ b/src/tint/ast/builtin_texture_helper_test.h
@@ -17,9 +17,10 @@
 
 #include <vector>
 
-#include "src/tint/ast/access.h"
 #include "src/tint/program_builder.h"
+#include "src/tint/type/access.h"
 #include "src/tint/type/storage_texture.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::ast::builtin::test {
 
@@ -185,7 +186,7 @@
                         const char*,
                         TextureKind,
                         ast::SamplerKind,
-                        ast::TextureDimension,
+                        type::TextureDimension,
                         TextureDataType,
                         const char*,
                         std::function<Args(ProgramBuilder*)>);
@@ -193,16 +194,16 @@
     TextureOverloadCase(ValidTextureOverload,
                         const char*,
                         TextureKind,
-                        ast::TextureDimension,
+                        type::TextureDimension,
                         TextureDataType,
                         const char*,
                         std::function<Args(ProgramBuilder*)>);
     /// Constructor for textureLoad() with storage textures
     TextureOverloadCase(ValidTextureOverload,
                         const char*,
-                        Access,
-                        ast::TexelFormat,
-                        ast::TextureDimension,
+                        type::Access,
+                        type::TexelFormat,
+                        type::TextureDimension,
                         TextureDataType,
                         const char*,
                         std::function<Args(ProgramBuilder*)>);
@@ -238,12 +239,12 @@
     ast::SamplerKind const sampler_kind = ast::SamplerKind::kSampler;
     /// The access control for the storage texture
     /// Used only when texture_kind is kStorage
-    Access const access = Access::kReadWrite;
+    type::Access const access = type::Access::kReadWrite;
     /// The image format for the storage texture
     /// Used only when texture_kind is kStorage
-    ast::TexelFormat const texel_format = ast::TexelFormat::kUndefined;
+    type::TexelFormat const texel_format = type::TexelFormat::kUndefined;
     /// The dimensions of the texture parameter
-    ast::TextureDimension const texture_dimension;
+    type::TextureDimension const texture_dimension;
     /// The data type of the texture parameter
     const TextureDataType texture_data_type;
     /// Name of the function. e.g. `textureSample`, `textureSampleGrad`, etc
diff --git a/src/tint/ast/depth_multisampled_texture.cc b/src/tint/ast/depth_multisampled_texture.cc
index 64998b5..2ab3e8a 100644
--- a/src/tint/ast/depth_multisampled_texture.cc
+++ b/src/tint/ast/depth_multisampled_texture.cc
@@ -21,8 +21,8 @@
 namespace tint::ast {
 namespace {
 
-bool IsValidDepthDimension(TextureDimension dim) {
-    return dim == TextureDimension::k2d;
+bool IsValidDepthDimension(type::TextureDimension dim) {
+    return dim == type::TextureDimension::k2d;
 }
 
 }  // namespace
@@ -30,7 +30,7 @@
 DepthMultisampledTexture::DepthMultisampledTexture(ProgramID pid,
                                                    NodeID nid,
                                                    const Source& src,
-                                                   TextureDimension d)
+                                                   type::TextureDimension d)
     : Base(pid, nid, src, d) {
     TINT_ASSERT(AST, IsValidDepthDimension(dim));
 }
diff --git a/src/tint/ast/depth_multisampled_texture.h b/src/tint/ast/depth_multisampled_texture.h
index 2cc8d78..8986d49 100644
--- a/src/tint/ast/depth_multisampled_texture.h
+++ b/src/tint/ast/depth_multisampled_texture.h
@@ -18,6 +18,7 @@
 #include <string>
 
 #include "src/tint/ast/texture.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::ast {
 
@@ -29,7 +30,10 @@
     /// @param nid the unique node identifier
     /// @param src the source of this node
     /// @param dim the dimensionality of the texture
-    DepthMultisampledTexture(ProgramID pid, NodeID nid, const Source& src, TextureDimension dim);
+    DepthMultisampledTexture(ProgramID pid,
+                             NodeID nid,
+                             const Source& src,
+                             type::TextureDimension dim);
     /// Move constructor
     DepthMultisampledTexture(DepthMultisampledTexture&&);
     ~DepthMultisampledTexture() override;
diff --git a/src/tint/ast/depth_multisampled_texture_test.cc b/src/tint/ast/depth_multisampled_texture_test.cc
index 1de335d..675e672 100644
--- a/src/tint/ast/depth_multisampled_texture_test.cc
+++ b/src/tint/ast/depth_multisampled_texture_test.cc
@@ -22,12 +22,12 @@
 using AstDepthMultisampledTextureTest = TestHelper;
 
 TEST_F(AstDepthMultisampledTextureTest, Dim) {
-    auto* d = create<DepthMultisampledTexture>(TextureDimension::k2d);
-    EXPECT_EQ(d->dim, TextureDimension::k2d);
+    auto* d = create<DepthMultisampledTexture>(type::TextureDimension::k2d);
+    EXPECT_EQ(d->dim, type::TextureDimension::k2d);
 }
 
 TEST_F(AstDepthMultisampledTextureTest, FriendlyName) {
-    auto* d = create<DepthMultisampledTexture>(TextureDimension::k2d);
+    auto* d = create<DepthMultisampledTexture>(type::TextureDimension::k2d);
     EXPECT_EQ(d->FriendlyName(Symbols()), "texture_depth_multisampled_2d");
 }
 
diff --git a/src/tint/ast/depth_texture.cc b/src/tint/ast/depth_texture.cc
index 4aae6f3..199c0da 100644
--- a/src/tint/ast/depth_texture.cc
+++ b/src/tint/ast/depth_texture.cc
@@ -21,14 +21,14 @@
 namespace tint::ast {
 namespace {
 
-bool IsValidDepthDimension(TextureDimension dim) {
-    return dim == TextureDimension::k2d || dim == TextureDimension::k2dArray ||
-           dim == TextureDimension::kCube || dim == TextureDimension::kCubeArray;
+bool IsValidDepthDimension(type::TextureDimension dim) {
+    return dim == type::TextureDimension::k2d || dim == type::TextureDimension::k2dArray ||
+           dim == type::TextureDimension::kCube || dim == type::TextureDimension::kCubeArray;
 }
 
 }  // namespace
 
-DepthTexture::DepthTexture(ProgramID pid, NodeID nid, const Source& src, TextureDimension d)
+DepthTexture::DepthTexture(ProgramID pid, NodeID nid, const Source& src, type::TextureDimension d)
     : Base(pid, nid, src, d) {
     TINT_ASSERT(AST, IsValidDepthDimension(dim));
 }
diff --git a/src/tint/ast/depth_texture.h b/src/tint/ast/depth_texture.h
index 7df34a2..e687612 100644
--- a/src/tint/ast/depth_texture.h
+++ b/src/tint/ast/depth_texture.h
@@ -18,6 +18,7 @@
 #include <string>
 
 #include "src/tint/ast/texture.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::ast {
 
@@ -29,7 +30,7 @@
     /// @param nid the unique node identifier
     /// @param src the source of this node
     /// @param dim the dimensionality of the texture
-    DepthTexture(ProgramID pid, NodeID nid, const Source& src, TextureDimension dim);
+    DepthTexture(ProgramID pid, NodeID nid, const Source& src, type::TextureDimension dim);
     /// Move constructor
     DepthTexture(DepthTexture&&);
     ~DepthTexture() override;
diff --git a/src/tint/ast/depth_texture_test.cc b/src/tint/ast/depth_texture_test.cc
index 15dc356..e2a7b0e 100644
--- a/src/tint/ast/depth_texture_test.cc
+++ b/src/tint/ast/depth_texture_test.cc
@@ -22,19 +22,19 @@
 using AstDepthTextureTest = TestHelper;
 
 TEST_F(AstDepthTextureTest, IsTexture) {
-    Texture* ty = create<DepthTexture>(TextureDimension::kCube);
+    Texture* ty = create<DepthTexture>(type::TextureDimension::kCube);
     EXPECT_TRUE(ty->Is<DepthTexture>());
     EXPECT_FALSE(ty->Is<SampledTexture>());
     EXPECT_FALSE(ty->Is<StorageTexture>());
 }
 
 TEST_F(AstDepthTextureTest, Dim) {
-    auto* d = create<DepthTexture>(TextureDimension::kCube);
-    EXPECT_EQ(d->dim, TextureDimension::kCube);
+    auto* d = create<DepthTexture>(type::TextureDimension::kCube);
+    EXPECT_EQ(d->dim, type::TextureDimension::kCube);
 }
 
 TEST_F(AstDepthTextureTest, FriendlyName) {
-    auto* d = create<DepthTexture>(TextureDimension::kCube);
+    auto* d = create<DepthTexture>(type::TextureDimension::kCube);
     EXPECT_EQ(d->FriendlyName(Symbols()), "texture_depth_cube");
 }
 
diff --git a/src/tint/ast/external_texture.cc b/src/tint/ast/external_texture.cc
index 4881913..95d9bc7 100644
--- a/src/tint/ast/external_texture.cc
+++ b/src/tint/ast/external_texture.cc
@@ -15,14 +15,15 @@
 #include "src/tint/ast/external_texture.h"
 
 #include "src/tint/program_builder.h"
+#include "src/tint/type/texture_dimension.h"
 
 TINT_INSTANTIATE_TYPEINFO(tint::ast::ExternalTexture);
 
 namespace tint::ast {
 
-// ExternalTexture::ExternalTexture() : Base(ast::TextureDimension::k2d) {}
+// ExternalTexture::ExternalTexture() : Base(type::TextureDimension::k2d) {}
 ExternalTexture::ExternalTexture(ProgramID pid, NodeID nid, const Source& src)
-    : Base(pid, nid, src, ast::TextureDimension::k2d) {}
+    : Base(pid, nid, src, type::TextureDimension::k2d) {}
 
 ExternalTexture::ExternalTexture(ExternalTexture&&) = default;
 
diff --git a/src/tint/ast/external_texture_test.cc b/src/tint/ast/external_texture_test.cc
index dfe097e..873dca8 100644
--- a/src/tint/ast/external_texture_test.cc
+++ b/src/tint/ast/external_texture_test.cc
@@ -15,6 +15,7 @@
 #include "src/tint/ast/external_texture.h"
 
 #include "src/tint/ast/test_helper.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::ast {
 namespace {
@@ -32,7 +33,7 @@
 
 TEST_F(AstExternalTextureTest, Dim) {
     auto* ty = create<ExternalTexture>();
-    EXPECT_EQ(ty->dim, ast::TextureDimension::k2d);
+    EXPECT_EQ(ty->dim, type::TextureDimension::k2d);
 }
 
 TEST_F(AstExternalTextureTest, FriendlyName) {
diff --git a/src/tint/ast/matrix_test.cc b/src/tint/ast/matrix_test.cc
index dbb88e3..ff47494 100644
--- a/src/tint/ast/matrix_test.cc
+++ b/src/tint/ast/matrix_test.cc
@@ -13,7 +13,6 @@
 // limitations under the License.
 
 #include "src/tint/ast/matrix.h"
-#include "src/tint/ast/access.h"
 #include "src/tint/ast/alias.h"
 #include "src/tint/ast/array.h"
 #include "src/tint/ast/bool.h"
@@ -26,6 +25,7 @@
 #include "src/tint/ast/texture.h"
 #include "src/tint/ast/u32.h"
 #include "src/tint/ast/vector.h"
+#include "src/tint/type/access.h"
 
 namespace tint::ast {
 namespace {
diff --git a/src/tint/ast/module_test.cc b/src/tint/ast/module_test.cc
index c34805e..c7b77c9 100644
--- a/src/tint/ast/module_test.cc
+++ b/src/tint/ast/module_test.cc
@@ -72,7 +72,7 @@
         {
             ProgramBuilder b1;
             ProgramBuilder b2;
-            b1.AST().AddGlobalVariable(b2.Var("var", b2.ty.i32(), ast::AddressSpace::kPrivate));
+            b1.AST().AddGlobalVariable(b2.Var("var", b2.ty.i32(), type::AddressSpace::kPrivate));
         },
         "internal compiler error");
 }
@@ -92,7 +92,7 @@
         ProgramBuilder b;
         b.Func("F", {}, b.ty.void_(), {});
         b.Alias("A", b.ty.u32());
-        b.GlobalVar("V", b.ty.i32(), ast::AddressSpace::kPrivate);
+        b.GlobalVar("V", b.ty.i32(), type::AddressSpace::kPrivate);
         return Program(std::move(b));
     }();
 
diff --git a/src/tint/ast/multisampled_texture.cc b/src/tint/ast/multisampled_texture.cc
index 0c44857..05aea9d 100644
--- a/src/tint/ast/multisampled_texture.cc
+++ b/src/tint/ast/multisampled_texture.cc
@@ -23,7 +23,7 @@
 MultisampledTexture::MultisampledTexture(ProgramID pid,
                                          NodeID nid,
                                          const Source& src,
-                                         TextureDimension d,
+                                         type::TextureDimension d,
                                          const Type* ty)
     : Base(pid, nid, src, d), type(ty) {
     TINT_ASSERT(AST, type);
diff --git a/src/tint/ast/multisampled_texture.h b/src/tint/ast/multisampled_texture.h
index 6887045..dfa192e 100644
--- a/src/tint/ast/multisampled_texture.h
+++ b/src/tint/ast/multisampled_texture.h
@@ -18,6 +18,7 @@
 #include <string>
 
 #include "src/tint/ast/texture.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::ast {
 
@@ -33,7 +34,7 @@
     MultisampledTexture(ProgramID pid,
                         NodeID nid,
                         const Source& src,
-                        TextureDimension dim,
+                        type::TextureDimension dim,
                         const Type* type);
     /// Move constructor
     MultisampledTexture(MultisampledTexture&&);
diff --git a/src/tint/ast/multisampled_texture_test.cc b/src/tint/ast/multisampled_texture_test.cc
index bc3b87f..8cb3b00 100644
--- a/src/tint/ast/multisampled_texture_test.cc
+++ b/src/tint/ast/multisampled_texture_test.cc
@@ -14,7 +14,6 @@
 
 #include "src/tint/ast/multisampled_texture.h"
 
-#include "src/tint/ast/access.h"
 #include "src/tint/ast/alias.h"
 #include "src/tint/ast/array.h"
 #include "src/tint/ast/bool.h"
@@ -31,6 +30,7 @@
 #include "src/tint/ast/texture.h"
 #include "src/tint/ast/u32.h"
 #include "src/tint/ast/vector.h"
+#include "src/tint/type/access.h"
 
 namespace tint::ast {
 namespace {
@@ -39,7 +39,7 @@
 
 TEST_F(AstMultisampledTextureTest, IsTexture) {
     auto* f32 = create<F32>();
-    Texture* ty = create<MultisampledTexture>(TextureDimension::kCube, f32);
+    Texture* ty = create<MultisampledTexture>(type::TextureDimension::kCube, f32);
     EXPECT_FALSE(ty->Is<DepthTexture>());
     EXPECT_TRUE(ty->Is<MultisampledTexture>());
     EXPECT_FALSE(ty->Is<SampledTexture>());
@@ -48,19 +48,19 @@
 
 TEST_F(AstMultisampledTextureTest, Dim) {
     auto* f32 = create<F32>();
-    auto* s = create<MultisampledTexture>(TextureDimension::k3d, f32);
-    EXPECT_EQ(s->dim, TextureDimension::k3d);
+    auto* s = create<MultisampledTexture>(type::TextureDimension::k3d, f32);
+    EXPECT_EQ(s->dim, type::TextureDimension::k3d);
 }
 
 TEST_F(AstMultisampledTextureTest, Type) {
     auto* f32 = create<F32>();
-    auto* s = create<MultisampledTexture>(TextureDimension::k3d, f32);
+    auto* s = create<MultisampledTexture>(type::TextureDimension::k3d, f32);
     EXPECT_EQ(s->type, f32);
 }
 
 TEST_F(AstMultisampledTextureTest, FriendlyName) {
     auto* f32 = create<F32>();
-    auto* s = create<MultisampledTexture>(TextureDimension::k3d, f32);
+    auto* s = create<MultisampledTexture>(type::TextureDimension::k3d, f32);
     EXPECT_EQ(s->FriendlyName(Symbols()), "texture_multisampled_3d<f32>");
 }
 
diff --git a/src/tint/ast/pointer.cc b/src/tint/ast/pointer.cc
index 71b7004..2216872 100644
--- a/src/tint/ast/pointer.cc
+++ b/src/tint/ast/pointer.cc
@@ -24,18 +24,18 @@
                  NodeID nid,
                  const Source& src,
                  const Type* const subtype,
-                 ast::AddressSpace addr_space,
-                 ast::Access ac)
+                 type::AddressSpace addr_space,
+                 type::Access ac)
     : Base(pid, nid, src), type(subtype), address_space(addr_space), access(ac) {}
 
 std::string Pointer::FriendlyName(const SymbolTable& symbols) const {
     std::ostringstream out;
     out << "ptr<";
-    if (address_space != ast::AddressSpace::kNone) {
+    if (address_space != type::AddressSpace::kNone) {
         out << address_space << ", ";
     }
     out << type->FriendlyName(symbols);
-    if (access != ast::Access::kUndefined) {
+    if (access != type::Access::kUndefined) {
         out << ", " << access;
     }
     out << ">";
diff --git a/src/tint/ast/pointer.h b/src/tint/ast/pointer.h
index 0e1e090..dda146a 100644
--- a/src/tint/ast/pointer.h
+++ b/src/tint/ast/pointer.h
@@ -17,9 +17,9 @@
 
 #include <string>
 
-#include "src/tint/ast/access.h"
-#include "src/tint/ast/address_space.h"
 #include "src/tint/ast/type.h"
+#include "src/tint/type/access.h"
+#include "src/tint/type/address_space.h"
 
 namespace tint::ast {
 
@@ -37,8 +37,8 @@
             NodeID nid,
             const Source& src,
             const Type* const subtype,
-            ast::AddressSpace address_space,
-            ast::Access access);
+            type::AddressSpace address_space,
+            type::Access access);
     /// Move constructor
     Pointer(Pointer&&);
     ~Pointer() override;
@@ -57,10 +57,10 @@
     const Type* const type;
 
     /// The address space of the pointer
-    ast::AddressSpace const address_space;
+    type::AddressSpace const address_space;
 
     /// The access control of the pointer
-    ast::Access const access;
+    type::Access const access;
 };
 
 }  // namespace tint::ast
diff --git a/src/tint/ast/pointer_test.cc b/src/tint/ast/pointer_test.cc
index aea260a..648d767 100644
--- a/src/tint/ast/pointer_test.cc
+++ b/src/tint/ast/pointer_test.cc
@@ -24,21 +24,21 @@
 
 TEST_F(AstPointerTest, Creation) {
     auto* i32 = create<I32>();
-    auto* p = create<Pointer>(i32, ast::AddressSpace::kStorage, Access::kRead);
+    auto* p = create<Pointer>(i32, type::AddressSpace::kStorage, type::Access::kRead);
     EXPECT_EQ(p->type, i32);
-    EXPECT_EQ(p->address_space, ast::AddressSpace::kStorage);
-    EXPECT_EQ(p->access, Access::kRead);
+    EXPECT_EQ(p->address_space, type::AddressSpace::kStorage);
+    EXPECT_EQ(p->access, type::Access::kRead);
 }
 
 TEST_F(AstPointerTest, FriendlyName) {
     auto* i32 = create<I32>();
-    auto* p = create<Pointer>(i32, ast::AddressSpace::kWorkgroup, Access::kUndefined);
+    auto* p = create<Pointer>(i32, type::AddressSpace::kWorkgroup, type::Access::kUndefined);
     EXPECT_EQ(p->FriendlyName(Symbols()), "ptr<workgroup, i32>");
 }
 
 TEST_F(AstPointerTest, FriendlyNameWithAccess) {
     auto* i32 = create<I32>();
-    auto* p = create<Pointer>(i32, ast::AddressSpace::kStorage, Access::kReadWrite);
+    auto* p = create<Pointer>(i32, type::AddressSpace::kStorage, type::Access::kReadWrite);
     EXPECT_EQ(p->FriendlyName(Symbols()), "ptr<storage, i32, read_write>");
 }
 
diff --git a/src/tint/ast/sampled_texture.cc b/src/tint/ast/sampled_texture.cc
index b8dfd61..cc33962 100644
--- a/src/tint/ast/sampled_texture.cc
+++ b/src/tint/ast/sampled_texture.cc
@@ -23,7 +23,7 @@
 SampledTexture::SampledTexture(ProgramID pid,
                                NodeID nid,
                                const Source& src,
-                               TextureDimension d,
+                               type::TextureDimension d,
                                const Type* ty)
     : Base(pid, nid, src, d), type(ty) {
     TINT_ASSERT(AST, type);
diff --git a/src/tint/ast/sampled_texture.h b/src/tint/ast/sampled_texture.h
index 1f33af3..4ad7aa7 100644
--- a/src/tint/ast/sampled_texture.h
+++ b/src/tint/ast/sampled_texture.h
@@ -18,6 +18,7 @@
 #include <string>
 
 #include "src/tint/ast/texture.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::ast {
 
@@ -33,7 +34,7 @@
     SampledTexture(ProgramID pid,
                    NodeID nid,
                    const Source& src,
-                   TextureDimension dim,
+                   type::TextureDimension dim,
                    const Type* type);
     /// Move constructor
     SampledTexture(SampledTexture&&);
diff --git a/src/tint/ast/sampled_texture_test.cc b/src/tint/ast/sampled_texture_test.cc
index f85d2df..4b42da7 100644
--- a/src/tint/ast/sampled_texture_test.cc
+++ b/src/tint/ast/sampled_texture_test.cc
@@ -24,7 +24,7 @@
 
 TEST_F(AstSampledTextureTest, IsTexture) {
     auto* f32 = create<F32>();
-    Texture* ty = create<SampledTexture>(TextureDimension::kCube, f32);
+    Texture* ty = create<SampledTexture>(type::TextureDimension::kCube, f32);
     EXPECT_FALSE(ty->Is<DepthTexture>());
     EXPECT_TRUE(ty->Is<SampledTexture>());
     EXPECT_FALSE(ty->Is<StorageTexture>());
@@ -32,19 +32,19 @@
 
 TEST_F(AstSampledTextureTest, Dim) {
     auto* f32 = create<F32>();
-    auto* s = create<SampledTexture>(TextureDimension::k3d, f32);
-    EXPECT_EQ(s->dim, TextureDimension::k3d);
+    auto* s = create<SampledTexture>(type::TextureDimension::k3d, f32);
+    EXPECT_EQ(s->dim, type::TextureDimension::k3d);
 }
 
 TEST_F(AstSampledTextureTest, Type) {
     auto* f32 = create<F32>();
-    auto* s = create<SampledTexture>(TextureDimension::k3d, f32);
+    auto* s = create<SampledTexture>(type::TextureDimension::k3d, f32);
     EXPECT_EQ(s->type, f32);
 }
 
 TEST_F(AstSampledTextureTest, FriendlyName) {
     auto* f32 = create<F32>();
-    auto* s = create<SampledTexture>(TextureDimension::k3d, f32);
+    auto* s = create<SampledTexture>(type::TextureDimension::k3d, f32);
     EXPECT_EQ(s->FriendlyName(Symbols()), "texture_3d<f32>");
 }
 
diff --git a/src/tint/ast/storage_texture.cc b/src/tint/ast/storage_texture.cc
index 0a48a5b..d107330 100644
--- a/src/tint/ast/storage_texture.cc
+++ b/src/tint/ast/storage_texture.cc
@@ -26,10 +26,10 @@
 StorageTexture::StorageTexture(ProgramID pid,
                                NodeID nid,
                                const Source& src,
-                               TextureDimension d,
-                               TexelFormat fmt,
+                               type::TextureDimension d,
+                               type::TexelFormat fmt,
                                const Type* subtype,
-                               Access ac)
+                               type::Access ac)
     : Base(pid, nid, src, d), format(fmt), type(subtype), access(ac) {}
 
 StorageTexture::StorageTexture(StorageTexture&&) = default;
@@ -49,35 +49,35 @@
     return ctx->dst->create<StorageTexture>(src, dim, format, ty, access);
 }
 
-Type* StorageTexture::SubtypeFor(TexelFormat format, ProgramBuilder& builder) {
+Type* StorageTexture::SubtypeFor(type::TexelFormat format, ProgramBuilder& builder) {
     switch (format) {
-        case TexelFormat::kR32Uint:
-        case TexelFormat::kRgba8Uint:
-        case TexelFormat::kRg32Uint:
-        case TexelFormat::kRgba16Uint:
-        case TexelFormat::kRgba32Uint: {
+        case type::TexelFormat::kR32Uint:
+        case type::TexelFormat::kRgba8Uint:
+        case type::TexelFormat::kRg32Uint:
+        case type::TexelFormat::kRgba16Uint:
+        case type::TexelFormat::kRgba32Uint: {
             return builder.create<U32>();
         }
 
-        case TexelFormat::kR32Sint:
-        case TexelFormat::kRgba8Sint:
-        case TexelFormat::kRg32Sint:
-        case TexelFormat::kRgba16Sint:
-        case TexelFormat::kRgba32Sint: {
+        case type::TexelFormat::kR32Sint:
+        case type::TexelFormat::kRgba8Sint:
+        case type::TexelFormat::kRg32Sint:
+        case type::TexelFormat::kRgba16Sint:
+        case type::TexelFormat::kRgba32Sint: {
             return builder.create<I32>();
         }
 
-        case TexelFormat::kBgra8Unorm:
-        case TexelFormat::kRgba8Unorm:
-        case TexelFormat::kRgba8Snorm:
-        case TexelFormat::kR32Float:
-        case TexelFormat::kRg32Float:
-        case TexelFormat::kRgba16Float:
-        case TexelFormat::kRgba32Float: {
+        case type::TexelFormat::kBgra8Unorm:
+        case type::TexelFormat::kRgba8Unorm:
+        case type::TexelFormat::kRgba8Snorm:
+        case type::TexelFormat::kR32Float:
+        case type::TexelFormat::kRg32Float:
+        case type::TexelFormat::kRgba16Float:
+        case type::TexelFormat::kRgba32Float: {
             return builder.create<F32>();
         }
 
-        case TexelFormat::kUndefined:
+        case type::TexelFormat::kUndefined:
             break;
     }
 
diff --git a/src/tint/ast/storage_texture.h b/src/tint/ast/storage_texture.h
index 9ae7b95..0f602a0 100644
--- a/src/tint/ast/storage_texture.h
+++ b/src/tint/ast/storage_texture.h
@@ -17,9 +17,10 @@
 
 #include <string>
 
-#include "src/tint/ast/access.h"
-#include "src/tint/ast/texel_format.h"
 #include "src/tint/ast/texture.h"
+#include "src/tint/type/access.h"
+#include "src/tint/type/texel_format.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::ast {
 
@@ -37,10 +38,10 @@
     StorageTexture(ProgramID pid,
                    NodeID nid,
                    const Source& src,
-                   TextureDimension dim,
-                   TexelFormat format,
+                   type::TextureDimension dim,
+                   type::TexelFormat format,
                    const Type* subtype,
-                   Access access_control);
+                   type::Access access_control);
 
     /// Move constructor
     StorageTexture(StorageTexture&&);
@@ -58,17 +59,17 @@
 
     /// @param format the storage texture image format
     /// @param builder the ProgramBuilder used to build the returned type
-    /// @returns the storage texture subtype for the given TexelFormat
-    static Type* SubtypeFor(TexelFormat format, ProgramBuilder& builder);
+    /// @returns the storage texture subtype for the given type::TexelFormat
+    static Type* SubtypeFor(type::TexelFormat format, ProgramBuilder& builder);
 
     /// The image format
-    const TexelFormat format;
+    const type::TexelFormat format;
 
     /// The storage subtype
     const Type* const type;
 
     /// The access control
-    const Access access;
+    const type::Access access;
 };
 
 }  // namespace tint::ast
diff --git a/src/tint/ast/storage_texture_test.cc b/src/tint/ast/storage_texture_test.cc
index 41f3d65..8bfd293 100644
--- a/src/tint/ast/storage_texture_test.cc
+++ b/src/tint/ast/storage_texture_test.cc
@@ -22,39 +22,40 @@
 using AstStorageTextureTest = TestHelper;
 
 TEST_F(AstStorageTextureTest, IsTexture) {
-    auto* subtype = StorageTexture::SubtypeFor(TexelFormat::kRgba32Float, *this);
-    Texture* ty = create<StorageTexture>(TextureDimension::k2dArray, TexelFormat::kRgba32Float,
-                                         subtype, Access::kRead);
+    auto* subtype = StorageTexture::SubtypeFor(type::TexelFormat::kRgba32Float, *this);
+    Texture* ty =
+        create<StorageTexture>(type::TextureDimension::k2dArray, type::TexelFormat::kRgba32Float,
+                               subtype, type::Access::kRead);
     EXPECT_FALSE(ty->Is<DepthTexture>());
     EXPECT_FALSE(ty->Is<SampledTexture>());
     EXPECT_TRUE(ty->Is<StorageTexture>());
 }
 
 TEST_F(AstStorageTextureTest, Dim) {
-    auto* subtype = StorageTexture::SubtypeFor(TexelFormat::kRgba32Float, *this);
-    auto* s = create<StorageTexture>(TextureDimension::k2dArray, TexelFormat::kRgba32Float, subtype,
-                                     Access::kRead);
-    EXPECT_EQ(s->dim, TextureDimension::k2dArray);
+    auto* subtype = StorageTexture::SubtypeFor(type::TexelFormat::kRgba32Float, *this);
+    auto* s = create<StorageTexture>(type::TextureDimension::k2dArray,
+                                     type::TexelFormat::kRgba32Float, subtype, type::Access::kRead);
+    EXPECT_EQ(s->dim, type::TextureDimension::k2dArray);
 }
 
 TEST_F(AstStorageTextureTest, Format) {
-    auto* subtype = StorageTexture::SubtypeFor(TexelFormat::kRgba32Float, *this);
-    auto* s = create<StorageTexture>(TextureDimension::k2dArray, TexelFormat::kRgba32Float, subtype,
-                                     Access::kRead);
-    EXPECT_EQ(s->format, TexelFormat::kRgba32Float);
+    auto* subtype = StorageTexture::SubtypeFor(type::TexelFormat::kRgba32Float, *this);
+    auto* s = create<StorageTexture>(type::TextureDimension::k2dArray,
+                                     type::TexelFormat::kRgba32Float, subtype, type::Access::kRead);
+    EXPECT_EQ(s->format, type::TexelFormat::kRgba32Float);
 }
 
 TEST_F(AstStorageTextureTest, FriendlyName) {
-    auto* subtype = StorageTexture::SubtypeFor(TexelFormat::kRgba32Float, *this);
-    auto* s = create<StorageTexture>(TextureDimension::k2dArray, TexelFormat::kRgba32Float, subtype,
-                                     Access::kRead);
+    auto* subtype = StorageTexture::SubtypeFor(type::TexelFormat::kRgba32Float, *this);
+    auto* s = create<StorageTexture>(type::TextureDimension::k2dArray,
+                                     type::TexelFormat::kRgba32Float, subtype, type::Access::kRead);
     EXPECT_EQ(s->FriendlyName(Symbols()), "texture_storage_2d_array<rgba32float, read>");
 }
 
 TEST_F(AstStorageTextureTest, F32) {
-    auto* subtype = StorageTexture::SubtypeFor(TexelFormat::kRgba32Float, *this);
-    Type* s = create<StorageTexture>(TextureDimension::k2dArray, TexelFormat::kRgba32Float, subtype,
-                                     Access::kRead);
+    auto* subtype = StorageTexture::SubtypeFor(type::TexelFormat::kRgba32Float, *this);
+    Type* s = create<StorageTexture>(type::TextureDimension::k2dArray,
+                                     type::TexelFormat::kRgba32Float, subtype, type::Access::kRead);
 
     ASSERT_TRUE(s->Is<Texture>());
     ASSERT_TRUE(s->Is<StorageTexture>());
@@ -62,9 +63,9 @@
 }
 
 TEST_F(AstStorageTextureTest, U32) {
-    auto* subtype = StorageTexture::SubtypeFor(TexelFormat::kRg32Uint, *this);
-    Type* s = create<StorageTexture>(TextureDimension::k2dArray, TexelFormat::kRg32Uint, subtype,
-                                     Access::kRead);
+    auto* subtype = StorageTexture::SubtypeFor(type::TexelFormat::kRg32Uint, *this);
+    Type* s = create<StorageTexture>(type::TextureDimension::k2dArray, type::TexelFormat::kRg32Uint,
+                                     subtype, type::Access::kRead);
 
     ASSERT_TRUE(s->Is<Texture>());
     ASSERT_TRUE(s->Is<StorageTexture>());
@@ -72,9 +73,9 @@
 }
 
 TEST_F(AstStorageTextureTest, I32) {
-    auto* subtype = StorageTexture::SubtypeFor(TexelFormat::kRgba32Sint, *this);
-    Type* s = create<StorageTexture>(TextureDimension::k2dArray, TexelFormat::kRgba32Sint, subtype,
-                                     Access::kRead);
+    auto* subtype = StorageTexture::SubtypeFor(type::TexelFormat::kRgba32Sint, *this);
+    Type* s = create<StorageTexture>(type::TextureDimension::k2dArray,
+                                     type::TexelFormat::kRgba32Sint, subtype, type::Access::kRead);
 
     ASSERT_TRUE(s->Is<Texture>());
     ASSERT_TRUE(s->Is<StorageTexture>());
diff --git a/src/tint/ast/texture.cc b/src/tint/ast/texture.cc
index f3c01df..bcfbcb5 100644
--- a/src/tint/ast/texture.cc
+++ b/src/tint/ast/texture.cc
@@ -18,66 +18,39 @@
 
 namespace tint::ast {
 
-std::ostream& operator<<(std::ostream& out, TextureDimension dim) {
+bool IsTextureArray(type::TextureDimension dim) {
     switch (dim) {
-        case TextureDimension::kNone:
-            out << "None";
-            break;
-        case TextureDimension::k1d:
-            out << "1d";
-            break;
-        case TextureDimension::k2d:
-            out << "2d";
-            break;
-        case TextureDimension::k2dArray:
-            out << "2d_array";
-            break;
-        case TextureDimension::k3d:
-            out << "3d";
-            break;
-        case TextureDimension::kCube:
-            out << "cube";
-            break;
-        case TextureDimension::kCubeArray:
-            out << "cube_array";
-            break;
-    }
-    return out;
-}
-
-bool IsTextureArray(TextureDimension dim) {
-    switch (dim) {
-        case TextureDimension::k2dArray:
-        case TextureDimension::kCubeArray:
+        case type::TextureDimension::k2dArray:
+        case type::TextureDimension::kCubeArray:
             return true;
-        case TextureDimension::k2d:
-        case TextureDimension::kNone:
-        case TextureDimension::k1d:
-        case TextureDimension::k3d:
-        case TextureDimension::kCube:
+        case type::TextureDimension::k2d:
+        case type::TextureDimension::kNone:
+        case type::TextureDimension::k1d:
+        case type::TextureDimension::k3d:
+        case type::TextureDimension::kCube:
             return false;
     }
     return false;
 }
 
-int NumCoordinateAxes(TextureDimension dim) {
+int NumCoordinateAxes(type::TextureDimension dim) {
     switch (dim) {
-        case TextureDimension::kNone:
+        case type::TextureDimension::kNone:
             return 0;
-        case TextureDimension::k1d:
+        case type::TextureDimension::k1d:
             return 1;
-        case TextureDimension::k2d:
-        case TextureDimension::k2dArray:
+        case type::TextureDimension::k2d:
+        case type::TextureDimension::k2dArray:
             return 2;
-        case TextureDimension::k3d:
-        case TextureDimension::kCube:
-        case TextureDimension::kCubeArray:
+        case type::TextureDimension::k3d:
+        case type::TextureDimension::kCube:
+        case type::TextureDimension::kCubeArray:
             return 3;
     }
     return 0;
 }
 
-Texture::Texture(ProgramID pid, NodeID nid, const Source& src, TextureDimension d)
+Texture::Texture(ProgramID pid, NodeID nid, const Source& src, type::TextureDimension d)
     : Base(pid, nid, src), dim(d) {}
 
 Texture::Texture(Texture&&) = default;
diff --git a/src/tint/ast/texture.h b/src/tint/ast/texture.h
index fcfa334..be78ba9 100644
--- a/src/tint/ast/texture.h
+++ b/src/tint/ast/texture.h
@@ -16,35 +16,13 @@
 #define SRC_TINT_AST_TEXTURE_H_
 
 #include "src/tint/ast/type.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::ast {
 
-/// The dimensionality of the texture
-enum class TextureDimension {
-    /// Invalid texture
-    kNone = -1,
-    /// 1 dimensional texture
-    k1d,
-    /// 2 dimensional texture
-    k2d,
-    /// 2 dimensional array texture
-    k2dArray,
-    /// 3 dimensional texture
-    k3d,
-    /// cube texture
-    kCube,
-    /// cube array texture
-    kCubeArray,
-};
-
-/// @param out the std::ostream to write to
-/// @param dim the TextureDimension
-/// @return the std::ostream so calls can be chained
-std::ostream& operator<<(std::ostream& out, TextureDimension dim);
-
-/// @param dim the TextureDimension to query
-/// @return true if the given TextureDimension is an array texture
-bool IsTextureArray(TextureDimension dim);
+/// @param dim the type::TextureDimension to query
+/// @return true if the given type::TextureDimension is an array texture
+bool IsTextureArray(type::TextureDimension dim);
 
 /// Returns the number of axes in the coordinate used for accessing
 /// the texture, where an access is one of: sampling, fetching, load,
@@ -56,9 +34,9 @@
 /// Note: To sample a cube texture, the coordinate has 3 dimensions,
 /// but textureDimensions on a cube or cube array returns a 2-element
 /// size, representing the (x,y) size of each cube face, in texels.
-/// @param dim the TextureDimension to query
+/// @param dim the type::TextureDimension to query
 /// @return number of dimensions in a coordinate for the dimensionality
-int NumCoordinateAxes(TextureDimension dim);
+int NumCoordinateAxes(type::TextureDimension dim);
 
 /// A texture type.
 class Texture : public Castable<Texture, Type> {
@@ -68,13 +46,13 @@
     /// @param nid the unique node identifier
     /// @param src the source of this node
     /// @param dim the dimensionality of the texture
-    Texture(ProgramID pid, NodeID nid, const Source& src, TextureDimension dim);
+    Texture(ProgramID pid, NodeID nid, const Source& src, type::TextureDimension dim);
     /// Move constructor
     Texture(Texture&&);
     ~Texture() override;
 
     /// The texture dimension
-    const TextureDimension dim;
+    const type::TextureDimension dim;
 };
 
 }  // namespace tint::ast
diff --git a/src/tint/ast/texture_test.cc b/src/tint/ast/texture_test.cc
index 7b7c0b0..cad2884 100644
--- a/src/tint/ast/texture_test.cc
+++ b/src/tint/ast/texture_test.cc
@@ -33,23 +33,23 @@
 using AstTextureTypeTest = TestHelper;
 
 TEST_F(AstTextureTypeTest, IsTextureArray) {
-    EXPECT_EQ(false, IsTextureArray(TextureDimension::kNone));
-    EXPECT_EQ(false, IsTextureArray(TextureDimension::k1d));
-    EXPECT_EQ(false, IsTextureArray(TextureDimension::k2d));
-    EXPECT_EQ(true, IsTextureArray(TextureDimension::k2dArray));
-    EXPECT_EQ(false, IsTextureArray(TextureDimension::k3d));
-    EXPECT_EQ(false, IsTextureArray(TextureDimension::kCube));
-    EXPECT_EQ(true, IsTextureArray(TextureDimension::kCubeArray));
+    EXPECT_EQ(false, IsTextureArray(type::TextureDimension::kNone));
+    EXPECT_EQ(false, IsTextureArray(type::TextureDimension::k1d));
+    EXPECT_EQ(false, IsTextureArray(type::TextureDimension::k2d));
+    EXPECT_EQ(true, IsTextureArray(type::TextureDimension::k2dArray));
+    EXPECT_EQ(false, IsTextureArray(type::TextureDimension::k3d));
+    EXPECT_EQ(false, IsTextureArray(type::TextureDimension::kCube));
+    EXPECT_EQ(true, IsTextureArray(type::TextureDimension::kCubeArray));
 }
 
 TEST_F(AstTextureTypeTest, NumCoordinateAxes) {
-    EXPECT_EQ(0, NumCoordinateAxes(TextureDimension::kNone));
-    EXPECT_EQ(1, NumCoordinateAxes(TextureDimension::k1d));
-    EXPECT_EQ(2, NumCoordinateAxes(TextureDimension::k2d));
-    EXPECT_EQ(2, NumCoordinateAxes(TextureDimension::k2dArray));
-    EXPECT_EQ(3, NumCoordinateAxes(TextureDimension::k3d));
-    EXPECT_EQ(3, NumCoordinateAxes(TextureDimension::kCube));
-    EXPECT_EQ(3, NumCoordinateAxes(TextureDimension::kCubeArray));
+    EXPECT_EQ(0, NumCoordinateAxes(type::TextureDimension::kNone));
+    EXPECT_EQ(1, NumCoordinateAxes(type::TextureDimension::k1d));
+    EXPECT_EQ(2, NumCoordinateAxes(type::TextureDimension::k2d));
+    EXPECT_EQ(2, NumCoordinateAxes(type::TextureDimension::k2dArray));
+    EXPECT_EQ(3, NumCoordinateAxes(type::TextureDimension::k3d));
+    EXPECT_EQ(3, NumCoordinateAxes(type::TextureDimension::kCube));
+    EXPECT_EQ(3, NumCoordinateAxes(type::TextureDimension::kCubeArray));
 }
 
 }  // namespace
diff --git a/src/tint/ast/var.cc b/src/tint/ast/var.cc
index 12f3f31..3ed6677 100644
--- a/src/tint/ast/var.cc
+++ b/src/tint/ast/var.cc
@@ -25,8 +25,8 @@
          const Source& src,
          const Symbol& sym,
          const ast::Type* ty,
-         AddressSpace address_space,
-         Access access,
+         type::AddressSpace address_space,
+         type::Access access,
          const Expression* init,
          utils::VectorRef<const Attribute*> attrs)
     : Base(pid, nid, src, sym, ty, init, std::move(attrs)),
diff --git a/src/tint/ast/var.h b/src/tint/ast/var.h
index 0141d9c..3fdd7db 100644
--- a/src/tint/ast/var.h
+++ b/src/tint/ast/var.h
@@ -56,8 +56,8 @@
         const Source& source,
         const Symbol& sym,
         const ast::Type* type,
-        AddressSpace declared_address_space,
-        Access declared_access,
+        type::AddressSpace declared_address_space,
+        type::Access declared_access,
         const Expression* initializer,
         utils::VectorRef<const Attribute*> attributes);
 
@@ -77,10 +77,10 @@
     const Var* Clone(CloneContext* ctx) const override;
 
     /// The declared address space
-    const AddressSpace declared_address_space;
+    const type::AddressSpace declared_address_space;
 
     /// The declared access control
-    const Access declared_access;
+    const type::Access declared_access;
 };
 
 /// A list of `var` declarations
diff --git a/src/tint/ast/variable.h b/src/tint/ast/variable.h
index 81096e9..7a75c3f 100644
--- a/src/tint/ast/variable.h
+++ b/src/tint/ast/variable.h
@@ -18,12 +18,12 @@
 #include <utility>
 #include <vector>
 
-#include "src/tint/ast/access.h"
-#include "src/tint/ast/address_space.h"
 #include "src/tint/ast/attribute.h"
 #include "src/tint/ast/binding_attribute.h"
 #include "src/tint/ast/expression.h"
 #include "src/tint/ast/group_attribute.h"
+#include "src/tint/type/access.h"
+#include "src/tint/type/address_space.h"
 
 // Forward declarations
 namespace tint::ast {
diff --git a/src/tint/ast/variable_test.cc b/src/tint/ast/variable_test.cc
index a0ee93d..e797b0d 100644
--- a/src/tint/ast/variable_test.cc
+++ b/src/tint/ast/variable_test.cc
@@ -25,10 +25,10 @@
 using VariableTest = TestHelper;
 
 TEST_F(VariableTest, Creation) {
-    auto* v = Var("my_var", ty.i32(), AddressSpace::kFunction);
+    auto* v = Var("my_var", ty.i32(), type::AddressSpace::kFunction);
 
     EXPECT_EQ(v->symbol, Symbol(1, ID()));
-    EXPECT_EQ(v->declared_address_space, AddressSpace::kFunction);
+    EXPECT_EQ(v->declared_address_space, type::AddressSpace::kFunction);
     EXPECT_TRUE(v->type->Is<ast::I32>());
     EXPECT_EQ(v->source.range.begin.line, 0u);
     EXPECT_EQ(v->source.range.begin.column, 0u);
@@ -38,10 +38,10 @@
 
 TEST_F(VariableTest, CreationWithSource) {
     auto* v = Var(Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 5}}}, "i",
-                  ty.f32(), AddressSpace::kPrivate, utils::Empty);
+                  ty.f32(), type::AddressSpace::kPrivate, utils::Empty);
 
     EXPECT_EQ(v->symbol, Symbol(1, ID()));
-    EXPECT_EQ(v->declared_address_space, AddressSpace::kPrivate);
+    EXPECT_EQ(v->declared_address_space, type::AddressSpace::kPrivate);
     EXPECT_TRUE(v->type->Is<ast::F32>());
     EXPECT_EQ(v->source.range.begin.line, 27u);
     EXPECT_EQ(v->source.range.begin.column, 4u);
@@ -51,10 +51,10 @@
 
 TEST_F(VariableTest, CreationEmpty) {
     auto* v = Var(Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 7}}}, "a_var",
-                  ty.i32(), AddressSpace::kWorkgroup, utils::Empty);
+                  ty.i32(), type::AddressSpace::kWorkgroup, utils::Empty);
 
     EXPECT_EQ(v->symbol, Symbol(1, ID()));
-    EXPECT_EQ(v->declared_address_space, AddressSpace::kWorkgroup);
+    EXPECT_EQ(v->declared_address_space, type::AddressSpace::kWorkgroup);
     EXPECT_TRUE(v->type->Is<ast::I32>());
     EXPECT_EQ(v->source.range.begin.line, 27u);
     EXPECT_EQ(v->source.range.begin.column, 4u);
@@ -92,7 +92,7 @@
 }
 
 TEST_F(VariableTest, WithAttributes) {
-    auto* var = Var("my_var", ty.i32(), AddressSpace::kFunction, Location(1_u),
+    auto* var = Var("my_var", ty.i32(), type::AddressSpace::kFunction, Location(1_u),
                     Builtin(BuiltinValue::kPosition), Id(1200_u));
 
     auto& attributes = var->attributes;
@@ -107,22 +107,22 @@
 }
 
 TEST_F(VariableTest, HasBindingPoint_BothProvided) {
-    auto* var = Var("my_var", ty.i32(), AddressSpace::kFunction, Binding(2_a), Group(1_a));
+    auto* var = Var("my_var", ty.i32(), type::AddressSpace::kFunction, Binding(2_a), Group(1_a));
     EXPECT_TRUE(var->HasBindingPoint());
 }
 
 TEST_F(VariableTest, HasBindingPoint_NeitherProvided) {
-    auto* var = Var("my_var", ty.i32(), AddressSpace::kFunction, utils::Empty);
+    auto* var = Var("my_var", ty.i32(), type::AddressSpace::kFunction, utils::Empty);
     EXPECT_FALSE(var->HasBindingPoint());
 }
 
 TEST_F(VariableTest, HasBindingPoint_MissingGroupAttribute) {
-    auto* var = Var("my_var", ty.i32(), AddressSpace::kFunction, Binding(2_a));
+    auto* var = Var("my_var", ty.i32(), type::AddressSpace::kFunction, Binding(2_a));
     EXPECT_FALSE(var->HasBindingPoint());
 }
 
 TEST_F(VariableTest, HasBindingPoint_MissingBindingAttribute) {
-    auto* var = Var("my_var", ty.i32(), AddressSpace::kFunction, Group(1_a));
+    auto* var = Var("my_var", ty.i32(), type::AddressSpace::kFunction, Group(1_a));
     EXPECT_FALSE(var->HasBindingPoint());
 }
 
diff --git a/src/tint/cmd/BUILD.gn b/src/tint/cmd/BUILD.gn
index c2f4322..3052d9e 100644
--- a/src/tint/cmd/BUILD.gn
+++ b/src/tint/cmd/BUILD.gn
@@ -19,6 +19,7 @@
   sources = [ "main.cc" ]
   deps = [
     "${tint_root_dir}/src/tint:libtint",
+    "${tint_root_dir}/src/tint:tint_utils_io",
     "${tint_root_dir}/src/tint:tint_val",
     "${tint_spirv_tools_dir}/:spvtools",
     "${tint_spirv_tools_dir}/:spvtools_opt",
diff --git a/src/tint/fuzzers/transform_builder.h b/src/tint/fuzzers/transform_builder.h
index 5867526..90d6af5 100644
--- a/src/tint/fuzzers/transform_builder.h
+++ b/src/tint/fuzzers/transform_builder.h
@@ -131,7 +131,7 @@
                 uint8_t old_binding;
                 uint8_t new_group;
                 uint8_t new_binding;
-                ast::Access new_access;
+                type::Access new_access;
             };
 
             std::vector<Config> configs = tb->builder()->vector<Config>();
diff --git a/src/tint/inspector/inspector.cc b/src/tint/inspector/inspector.cc
index e69c3b5..e57dce3 100644
--- a/src/tint/inspector/inspector.cc
+++ b/src/tint/inspector/inspector.cc
@@ -586,7 +586,7 @@
     uint32_t total_size = 0;
     auto* func_sem = program_->Sem().Get(func);
     for (const sem::Variable* var : func_sem->TransitivelyReferencedGlobals()) {
-        if (var->AddressSpace() == ast::AddressSpace::kWorkgroup) {
+        if (var->AddressSpace() == type::AddressSpace::kWorkgroup) {
             auto* ty = var->Type()->UnwrapRef();
             uint32_t align = ty->Align();
             uint32_t size = ty->Size();
@@ -718,7 +718,7 @@
         auto* var = rsv.first;
         auto binding_info = rsv.second;
 
-        if (read_only != (var->Access() == ast::Access::kRead)) {
+        if (read_only != (var->Access() == type::Access::kRead)) {
             continue;
         }
 
diff --git a/src/tint/inspector/inspector_test.cc b/src/tint/inspector/inspector_test.cc
index d6c635d..44b1744 100644
--- a/src/tint/inspector/inspector_test.cc
+++ b/src/tint/inspector/inspector_test.cc
@@ -27,6 +27,7 @@
 #include "src/tint/type/external_texture.h"
 #include "src/tint/type/multisampled_texture.h"
 #include "src/tint/type/sampled_texture.h"
+#include "src/tint/type/texture_dimension.h"
 #include "tint/tint.h"
 
 using namespace tint::number_suffixes;  // NOLINT
@@ -76,7 +77,7 @@
 class InspectorGetSampledArrayTextureResourceBindingsTest : public InspectorBuilder,
                                                             public testing::Test {};
 struct GetSampledTextureTestParams {
-    ast::TextureDimension type_dim;
+    type::TextureDimension type_dim;
     inspector::ResourceBinding::TextureDimension inspector_dim;
     inspector::ResourceBinding::SampledKind sampled_kind;
 };
@@ -100,7 +101,7 @@
 class InspectorGetStorageTextureResourceBindingsTest : public InspectorBuilder,
                                                        public testing::Test {};
 struct GetDepthTextureTestParams {
-    ast::TextureDimension type_dim;
+    type::TextureDimension type_dim;
     inspector::ResourceBinding::TextureDimension inspector_dim;
 };
 class InspectorGetDepthTextureResourceBindingsTestWithParam
@@ -110,8 +111,8 @@
 class InspectorGetDepthMultisampledTextureResourceBindingsTest : public InspectorBuilder,
                                                                  public testing::Test {};
 
-typedef std::tuple<ast::TextureDimension, ResourceBinding::TextureDimension> DimensionParams;
-typedef std::tuple<ast::TexelFormat, ResourceBinding::TexelFormat, ResourceBinding::SampledKind>
+typedef std::tuple<type::TextureDimension, ResourceBinding::TextureDimension> DimensionParams;
+typedef std::tuple<type::TexelFormat, ResourceBinding::TexelFormat, ResourceBinding::SampledKind>
     TexelFormatParams;
 typedef std::tuple<DimensionParams, TexelFormatParams> GetStorageTextureTestParams;
 class InspectorGetStorageTextureResourceBindingsTestWithParam
@@ -742,7 +743,7 @@
 
 TEST_F(InspectorGetEntryPointTest, OverrideReferencedIndirectly_ViaPrivateInitializer) {
     Override("foo", ty.f32());
-    GlobalVar("bar", ast::AddressSpace::kPrivate, ty.f32(), Mul(2_a, "foo"));
+    GlobalVar("bar", type::AddressSpace::kPrivate, ty.f32(), Mul(2_a, "foo"));
     MakePlainGlobalReferenceBodyFunction("ep_func", "bar", ty.f32(),
                                          utils::Vector{
                                              Stage(ast::PipelineStage::kCompute),
@@ -833,7 +834,7 @@
 
 TEST_F(InspectorGetEntryPointTest, OverrideReferencedByArraySize) {
     Override("size", ty.u32());
-    GlobalVar("v", ast::AddressSpace::kWorkgroup, ty.array(ty.f32(), "size"));
+    GlobalVar("v", type::AddressSpace::kWorkgroup, ty.array(ty.f32(), "size"));
     Func("ep", utils::Empty, ty.void_(),
          utils::Vector{
              Assign(Phony(), IndexAccessor("v", 0_a)),
@@ -856,7 +857,7 @@
 TEST_F(InspectorGetEntryPointTest, OverrideReferencedByArraySizeIndirectly) {
     Override("foo", ty.u32());
     Override("bar", ty.u32(), Mul(2_a, "foo"));
-    GlobalVar("v", ast::AddressSpace::kWorkgroup, ty.array(ty.f32(), Mul(2_a, Expr("bar"))));
+    GlobalVar("v", type::AddressSpace::kWorkgroup, ty.array(ty.f32(), Mul(2_a, Expr("bar"))));
     Func("ep", utils::Empty, ty.void_(),
          utils::Vector{
              Assign(Phony(), IndexAccessor("v", 0_a)),
@@ -884,7 +885,7 @@
     Alias("MyArray", ty.array(ty.f32(), Mul(2_a, Expr("bar"))));
     Override("zoo", ty.u32());
     Alias("MyArrayUnused", ty.array(ty.f32(), Mul(2_a, Expr("zoo"))));
-    GlobalVar("v", ast::AddressSpace::kWorkgroup, ty.type_name("MyArray"));
+    GlobalVar("v", type::AddressSpace::kWorkgroup, ty.type_name("MyArray"));
     Func("ep", utils::Empty, ty.void_(),
          utils::Vector{
              Assign(Phony(), IndexAccessor("v", 0_a)),
@@ -1650,8 +1651,8 @@
 
 TEST_F(InspectorGetStorageSizeTest, Simple_NonStruct) {
     AddUniformBuffer("ub_var", ty.i32(), 0, 0);
-    AddStorageBuffer("sb_var", ty.i32(), ast::Access::kReadWrite, 1, 0);
-    AddStorageBuffer("rosb_var", ty.i32(), ast::Access::kRead, 1, 1);
+    AddStorageBuffer("sb_var", ty.i32(), type::Access::kReadWrite, 1, 0);
+    AddStorageBuffer("rosb_var", ty.i32(), type::Access::kRead, 1, 1);
     Func("ep_func", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(Let("ub", Expr("ub_var"))),
@@ -1682,7 +1683,7 @@
     auto sb = MakeStorageBufferTypes("sb_type", utils::Vector{
                                                     ty.i32(),
                                                 });
-    AddStorageBuffer("sb_var", sb(), ast::Access::kReadWrite, 1, 0);
+    AddStorageBuffer("sb_var", sb(), type::Access::kReadWrite, 1, 0);
     MakeStructVariableReferenceBodyFunction("sb_func", "sb_var",
                                             utils::Vector{
                                                 MemberInfo{0, ty.i32()},
@@ -1691,7 +1692,7 @@
     auto ro_sb = MakeStorageBufferTypes("rosb_type", utils::Vector{
                                                          ty.i32(),
                                                      });
-    AddStorageBuffer("rosb_var", ro_sb(), ast::Access::kRead, 1, 1);
+    AddStorageBuffer("rosb_var", ro_sb(), type::Access::kRead, 1, 1);
     MakeStructVariableReferenceBodyFunction("rosb_func", "rosb_var",
                                             utils::Vector{
                                                 MemberInfo{0, ty.i32()},
@@ -1769,7 +1770,7 @@
     auto sb = MakeStorageBufferTypes("sb_type", utils::Vector{
                                                     ty.i32(),
                                                 });
-    AddStorageBuffer("sb_var", sb(), ast::Access::kReadWrite, 1, 0);
+    AddStorageBuffer("sb_var", sb(), type::Access::kReadWrite, 1, 0);
     MakeStructVariableReferenceBodyFunction("sb_func", "sb_var",
                                             utils::Vector{
                                                 MemberInfo{0, ty.i32()},
@@ -1778,20 +1779,20 @@
     auto ro_sb = MakeStorageBufferTypes("rosb_type", utils::Vector{
                                                          ty.i32(),
                                                      });
-    AddStorageBuffer("rosb_var", ro_sb(), ast::Access::kRead, 1, 1);
+    AddStorageBuffer("rosb_var", ro_sb(), type::Access::kRead, 1, 1);
     MakeStructVariableReferenceBodyFunction("rosb_func", "rosb_var",
                                             utils::Vector{
                                                 MemberInfo{0, ty.i32()},
                                             });
 
-    auto* s_texture_type = ty.sampled_texture(ast::TextureDimension::k1d, ty.f32());
+    auto* s_texture_type = ty.sampled_texture(type::TextureDimension::k1d, ty.f32());
     AddResource("s_texture", s_texture_type, 2, 0);
     AddSampler("s_var", 3, 0);
     AddGlobalVariable("s_coords", ty.f32());
     MakeSamplerReferenceBodyFunction("s_func", "s_texture", "s_var", "s_coords", ty.f32(),
                                      utils::Empty);
 
-    auto* cs_depth_texture_type = ty.depth_texture(ast::TextureDimension::k2d);
+    auto* cs_depth_texture_type = ty.depth_texture(type::TextureDimension::k2d);
     AddResource("cs_texture", cs_depth_texture_type, 3, 1);
     AddComparisonSampler("cs_var", 3, 2);
     AddGlobalVariable("cs_coords", ty.vec2<f32>());
@@ -1799,14 +1800,15 @@
     MakeComparisonSamplerReferenceBodyFunction("cs_func", "cs_texture", "cs_var", "cs_coords",
                                                "cs_depth", ty.f32(), utils::Empty);
 
-    auto* depth_ms_texture_type = ty.depth_multisampled_texture(ast::TextureDimension::k2d);
+    auto* depth_ms_texture_type = ty.depth_multisampled_texture(type::TextureDimension::k2d);
     AddResource("depth_ms_texture", depth_ms_texture_type, 3, 3);
     Func("depth_ms_func", utils::Empty, ty.void_(),
          utils::Vector{
              Ignore("depth_ms_texture"),
          });
 
-    auto* st_type = MakeStorageTextureTypes(ast::TextureDimension::k2d, ast::TexelFormat::kR32Uint);
+    auto* st_type =
+        MakeStorageTextureTypes(type::TextureDimension::k2d, type::TexelFormat::kR32Uint);
     AddStorageTexture("st_var", st_type, 4, 0);
     MakeStorageTextureBodyFunction("st_func", "st_var", ty.vec2<u32>(), utils::Empty);
 
@@ -2132,7 +2134,7 @@
 }
 
 TEST_F(InspectorGetStorageBufferResourceBindingsTest, Simple_NonStruct) {
-    AddStorageBuffer("foo_sb", ty.i32(), ast::Access::kReadWrite, 0, 0);
+    AddStorageBuffer("foo_sb", ty.i32(), type::Access::kReadWrite, 0, 0);
     MakePlainGlobalReferenceBodyFunction("sb_func", "foo_sb", ty.i32(), utils::Empty);
 
     MakeCallerBodyFunction("ep_func", utils::Vector{std::string("sb_func")},
@@ -2157,7 +2159,7 @@
     auto foo_struct_type = MakeStorageBufferTypes("foo_type", utils::Vector{
                                                                   ty.i32(),
                                                               });
-    AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kReadWrite, 0, 0);
+    AddStorageBuffer("foo_sb", foo_struct_type(), type::Access::kReadWrite, 0, 0);
 
     MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
                                             utils::Vector{
@@ -2188,7 +2190,7 @@
                                                                   ty.u32(),
                                                                   ty.f32(),
                                                               });
-    AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kReadWrite, 0, 0);
+    AddStorageBuffer("foo_sb", foo_struct_type(), type::Access::kReadWrite, 0, 0);
 
     MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
                                             utils::Vector{
@@ -2221,9 +2223,9 @@
                                                                 ty.u32(),
                                                                 ty.f32(),
                                                             });
-    AddStorageBuffer("sb_foo", sb_struct_type(), ast::Access::kReadWrite, 0, 0);
-    AddStorageBuffer("sb_bar", sb_struct_type(), ast::Access::kReadWrite, 0, 1);
-    AddStorageBuffer("sb_baz", sb_struct_type(), ast::Access::kReadWrite, 2, 0);
+    AddStorageBuffer("sb_foo", sb_struct_type(), type::Access::kReadWrite, 0, 0);
+    AddStorageBuffer("sb_bar", sb_struct_type(), type::Access::kReadWrite, 0, 1);
+    AddStorageBuffer("sb_baz", sb_struct_type(), type::Access::kReadWrite, 2, 0);
 
     auto AddReferenceFunc = [this](const std::string& func_name, const std::string& var_name) {
         MakeStructVariableReferenceBodyFunction(func_name, var_name,
@@ -2282,7 +2284,7 @@
                                                                   ty.i32(),
                                                                   ty.array<u32, 4>(),
                                                               });
-    AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kReadWrite, 0, 0);
+    AddStorageBuffer("foo_sb", foo_struct_type(), type::Access::kReadWrite, 0, 0);
 
     MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
                                             utils::Vector{
@@ -2312,7 +2314,7 @@
                                                                   ty.i32(),
                                                                   ty.array<u32>(),
                                                               });
-    AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kReadWrite, 0, 0);
+    AddStorageBuffer("foo_sb", foo_struct_type(), type::Access::kReadWrite, 0, 0);
 
     MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
                                             utils::Vector{
@@ -2341,7 +2343,7 @@
     auto foo_struct_type = MakeStorageBufferTypes("foo_type", utils::Vector{
                                                                   ty.vec3<f32>(),
                                                               });
-    AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kReadWrite, 0, 0);
+    AddStorageBuffer("foo_sb", foo_struct_type(), type::Access::kReadWrite, 0, 0);
 
     MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
                                             utils::Vector{
@@ -2367,7 +2369,7 @@
 }
 
 TEST_F(InspectorGetStorageBufferResourceBindingsTest, NonStructVec3) {
-    AddStorageBuffer("foo_ub", ty.vec3<f32>(), ast::Access::kReadWrite, 0, 0);
+    AddStorageBuffer("foo_ub", ty.vec3<f32>(), type::Access::kReadWrite, 0, 0);
     MakePlainGlobalReferenceBodyFunction("ub_func", "foo_ub", ty.vec3<f32>(), utils::Empty);
 
     MakeCallerBodyFunction("ep_func", utils::Vector{std::string("ub_func")},
@@ -2392,7 +2394,7 @@
     auto foo_struct_type = MakeStorageBufferTypes("foo_type", utils::Vector{
                                                                   ty.i32(),
                                                               });
-    AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kRead, 0, 0);
+    AddStorageBuffer("foo_sb", foo_struct_type(), type::Access::kRead, 0, 0);
 
     MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
                                             utils::Vector{
@@ -2415,7 +2417,7 @@
     auto foo_struct_type = MakeStorageBufferTypes("foo_type", utils::Vector{
                                                                   ty.i32(),
                                                               });
-    AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kRead, 0, 0);
+    AddStorageBuffer("foo_sb", foo_struct_type(), type::Access::kRead, 0, 0);
 
     MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
                                             utils::Vector{
@@ -2446,9 +2448,9 @@
                                                                 ty.u32(),
                                                                 ty.f32(),
                                                             });
-    AddStorageBuffer("sb_foo", sb_struct_type(), ast::Access::kRead, 0, 0);
-    AddStorageBuffer("sb_bar", sb_struct_type(), ast::Access::kRead, 0, 1);
-    AddStorageBuffer("sb_baz", sb_struct_type(), ast::Access::kRead, 2, 0);
+    AddStorageBuffer("sb_foo", sb_struct_type(), type::Access::kRead, 0, 0);
+    AddStorageBuffer("sb_bar", sb_struct_type(), type::Access::kRead, 0, 1);
+    AddStorageBuffer("sb_baz", sb_struct_type(), type::Access::kRead, 2, 0);
 
     auto AddReferenceFunc = [this](const std::string& func_name, const std::string& var_name) {
         MakeStructVariableReferenceBodyFunction(func_name, var_name,
@@ -2507,7 +2509,7 @@
                                                                   ty.i32(),
                                                                   ty.array<u32, 4>(),
                                                               });
-    AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kRead, 0, 0);
+    AddStorageBuffer("foo_sb", foo_struct_type(), type::Access::kRead, 0, 0);
 
     MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
                                             utils::Vector{
@@ -2537,7 +2539,7 @@
                                                                   ty.i32(),
                                                                   ty.array<u32>(),
                                                               });
-    AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kRead, 0, 0);
+    AddStorageBuffer("foo_sb", foo_struct_type(), type::Access::kRead, 0, 0);
 
     MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
                                             utils::Vector{
@@ -2566,7 +2568,7 @@
     auto foo_struct_type = MakeStorageBufferTypes("foo_type", utils::Vector{
                                                                   ty.i32(),
                                                               });
-    AddStorageBuffer("foo_sb", foo_struct_type(), ast::Access::kReadWrite, 0, 0);
+    AddStorageBuffer("foo_sb", foo_struct_type(), type::Access::kReadWrite, 0, 0);
 
     MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb",
                                             utils::Vector{
@@ -2586,7 +2588,7 @@
 }
 
 TEST_F(InspectorGetSamplerResourceBindingsTest, Simple) {
-    auto* sampled_texture_type = ty.sampled_texture(ast::TextureDimension::k1d, ty.f32());
+    auto* sampled_texture_type = ty.sampled_texture(type::TextureDimension::k1d, ty.f32());
     AddResource("foo_texture", sampled_texture_type, 0, 0);
     AddSampler("foo_sampler", 0, 1);
     AddGlobalVariable("foo_coords", ty.f32());
@@ -2621,7 +2623,7 @@
 }
 
 TEST_F(InspectorGetSamplerResourceBindingsTest, InFunction) {
-    auto* sampled_texture_type = ty.sampled_texture(ast::TextureDimension::k1d, ty.f32());
+    auto* sampled_texture_type = ty.sampled_texture(type::TextureDimension::k1d, ty.f32());
     AddResource("foo_texture", sampled_texture_type, 0, 0);
     AddSampler("foo_sampler", 0, 1);
     AddGlobalVariable("foo_coords", ty.f32());
@@ -2646,7 +2648,7 @@
 }
 
 TEST_F(InspectorGetSamplerResourceBindingsTest, UnknownEntryPoint) {
-    auto* sampled_texture_type = ty.sampled_texture(ast::TextureDimension::k1d, ty.f32());
+    auto* sampled_texture_type = ty.sampled_texture(type::TextureDimension::k1d, ty.f32());
     AddResource("foo_texture", sampled_texture_type, 0, 0);
     AddSampler("foo_sampler", 0, 1);
     AddGlobalVariable("foo_coords", ty.f32());
@@ -2663,7 +2665,7 @@
 }
 
 TEST_F(InspectorGetSamplerResourceBindingsTest, SkipsComparisonSamplers) {
-    auto* depth_texture_type = ty.depth_texture(ast::TextureDimension::k2d);
+    auto* depth_texture_type = ty.depth_texture(type::TextureDimension::k2d);
     AddResource("foo_texture", depth_texture_type, 0, 0);
     AddComparisonSampler("foo_sampler", 0, 1);
     AddGlobalVariable("foo_coords", ty.vec2<f32>());
@@ -2684,7 +2686,7 @@
 }
 
 TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, Simple) {
-    auto* depth_texture_type = ty.depth_texture(ast::TextureDimension::k2d);
+    auto* depth_texture_type = ty.depth_texture(type::TextureDimension::k2d);
     AddResource("foo_texture", depth_texture_type, 0, 0);
     AddComparisonSampler("foo_sampler", 0, 1);
     AddGlobalVariable("foo_coords", ty.vec2<f32>());
@@ -2721,7 +2723,7 @@
 }
 
 TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, InFunction) {
-    auto* depth_texture_type = ty.depth_texture(ast::TextureDimension::k2d);
+    auto* depth_texture_type = ty.depth_texture(type::TextureDimension::k2d);
     AddResource("foo_texture", depth_texture_type, 0, 0);
     AddComparisonSampler("foo_sampler", 0, 1);
     AddGlobalVariable("foo_coords", ty.vec2<f32>());
@@ -2747,7 +2749,7 @@
 }
 
 TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, UnknownEntryPoint) {
-    auto* depth_texture_type = ty.depth_texture(ast::TextureDimension::k2d);
+    auto* depth_texture_type = ty.depth_texture(type::TextureDimension::k2d);
     AddResource("foo_texture", depth_texture_type, 0, 0);
     AddComparisonSampler("foo_sampler", 0, 1);
     AddGlobalVariable("foo_coords", ty.vec2<f32>());
@@ -2766,7 +2768,7 @@
 }
 
 TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, SkipsSamplers) {
-    auto* sampled_texture_type = ty.sampled_texture(ast::TextureDimension::k1d, ty.f32());
+    auto* sampled_texture_type = ty.sampled_texture(type::TextureDimension::k1d, ty.f32());
     AddResource("foo_texture", sampled_texture_type, 0, 0);
     AddSampler("foo_sampler", 0, 1);
     AddGlobalVariable("foo_coords", ty.f32());
@@ -2833,16 +2835,16 @@
 INSTANTIATE_TEST_SUITE_P(
     InspectorGetSampledTextureResourceBindingsTest,
     InspectorGetSampledTextureResourceBindingsTestWithParam,
-    testing::Values(GetSampledTextureTestParams{ast::TextureDimension::k1d,
+    testing::Values(GetSampledTextureTestParams{type::TextureDimension::k1d,
                                                 inspector::ResourceBinding::TextureDimension::k1d,
                                                 inspector::ResourceBinding::SampledKind::kFloat},
-                    GetSampledTextureTestParams{ast::TextureDimension::k2d,
+                    GetSampledTextureTestParams{type::TextureDimension::k2d,
                                                 inspector::ResourceBinding::TextureDimension::k2d,
                                                 inspector::ResourceBinding::SampledKind::kFloat},
-                    GetSampledTextureTestParams{ast::TextureDimension::k3d,
+                    GetSampledTextureTestParams{type::TextureDimension::k3d,
                                                 inspector::ResourceBinding::TextureDimension::k3d,
                                                 inspector::ResourceBinding::SampledKind::kFloat},
-                    GetSampledTextureTestParams{ast::TextureDimension::kCube,
+                    GetSampledTextureTestParams{type::TextureDimension::kCube,
                                                 inspector::ResourceBinding::TextureDimension::kCube,
                                                 inspector::ResourceBinding::SampledKind::kFloat}));
 
@@ -2878,10 +2880,10 @@
     InspectorGetSampledArrayTextureResourceBindingsTest,
     InspectorGetSampledArrayTextureResourceBindingsTestWithParam,
     testing::Values(
-        GetSampledTextureTestParams{ast::TextureDimension::k2dArray,
+        GetSampledTextureTestParams{type::TextureDimension::k2dArray,
                                     inspector::ResourceBinding::TextureDimension::k2dArray,
                                     inspector::ResourceBinding::SampledKind::kFloat},
-        GetSampledTextureTestParams{ast::TextureDimension::kCubeArray,
+        GetSampledTextureTestParams{type::TextureDimension::kCubeArray,
                                     inspector::ResourceBinding::TextureDimension::kCubeArray,
                                     inspector::ResourceBinding::SampledKind::kFloat}));
 
@@ -2924,13 +2926,13 @@
     InspectorGetMultisampledTextureResourceBindingsTest,
     InspectorGetMultisampledTextureResourceBindingsTestWithParam,
     testing::Values(
-        GetMultisampledTextureTestParams{ast::TextureDimension::k2d,
+        GetMultisampledTextureTestParams{type::TextureDimension::k2d,
                                          inspector::ResourceBinding::TextureDimension::k2d,
                                          inspector::ResourceBinding::SampledKind::kFloat},
-        GetMultisampledTextureTestParams{ast::TextureDimension::k2d,
+        GetMultisampledTextureTestParams{type::TextureDimension::k2d,
                                          inspector::ResourceBinding::TextureDimension::k2d,
                                          inspector::ResourceBinding::SampledKind::kSInt},
-        GetMultisampledTextureTestParams{ast::TextureDimension::k2d,
+        GetMultisampledTextureTestParams{type::TextureDimension::k2d,
                                          inspector::ResourceBinding::TextureDimension::k2d,
                                          inspector::ResourceBinding::SampledKind::kUInt}));
 
@@ -2964,11 +2966,11 @@
     TexelFormatParams format_params;
     std::tie(dim_params, format_params) = GetParam();
 
-    ast::TextureDimension dim;
+    type::TextureDimension dim;
     ResourceBinding::TextureDimension expected_dim;
     std::tie(dim, expected_dim) = dim_params;
 
-    ast::TexelFormat format;
+    type::TexelFormat format;
     ResourceBinding::TexelFormat expected_format;
     ResourceBinding::SampledKind expected_kind;
     std::tie(format, expected_format, expected_kind) = format_params;
@@ -2978,14 +2980,14 @@
 
     const ast::Type* dim_type = nullptr;
     switch (dim) {
-        case ast::TextureDimension::k1d:
+        case type::TextureDimension::k1d:
             dim_type = ty.u32();
             break;
-        case ast::TextureDimension::k2d:
-        case ast::TextureDimension::k2dArray:
+        case type::TextureDimension::k2d:
+        case type::TextureDimension::k2dArray:
             dim_type = ty.vec2<u32>();
             break;
-        case ast::TextureDimension::k3d:
+        case type::TextureDimension::k3d:
             dim_type = ty.vec3<u32>();
             break;
         default:
@@ -3016,60 +3018,60 @@
 INSTANTIATE_TEST_SUITE_P(
     InspectorGetStorageTextureResourceBindingsTest,
     InspectorGetStorageTextureResourceBindingsTestWithParam,
-    testing::Combine(testing::Values(std::make_tuple(ast::TextureDimension::k1d,
+    testing::Combine(testing::Values(std::make_tuple(type::TextureDimension::k1d,
                                                      ResourceBinding::TextureDimension::k1d),
-                                     std::make_tuple(ast::TextureDimension::k2d,
+                                     std::make_tuple(type::TextureDimension::k2d,
                                                      ResourceBinding::TextureDimension::k2d),
-                                     std::make_tuple(ast::TextureDimension::k2dArray,
+                                     std::make_tuple(type::TextureDimension::k2dArray,
                                                      ResourceBinding::TextureDimension::k2dArray),
-                                     std::make_tuple(ast::TextureDimension::k3d,
+                                     std::make_tuple(type::TextureDimension::k3d,
                                                      ResourceBinding::TextureDimension::k3d)),
-                     testing::Values(std::make_tuple(ast::TexelFormat::kR32Float,
+                     testing::Values(std::make_tuple(type::TexelFormat::kR32Float,
                                                      ResourceBinding::TexelFormat::kR32Float,
                                                      ResourceBinding::SampledKind::kFloat),
-                                     std::make_tuple(ast::TexelFormat::kR32Sint,
+                                     std::make_tuple(type::TexelFormat::kR32Sint,
                                                      ResourceBinding::TexelFormat::kR32Sint,
                                                      ResourceBinding::SampledKind::kSInt),
-                                     std::make_tuple(ast::TexelFormat::kR32Uint,
+                                     std::make_tuple(type::TexelFormat::kR32Uint,
                                                      ResourceBinding::TexelFormat::kR32Uint,
                                                      ResourceBinding::SampledKind::kUInt),
-                                     std::make_tuple(ast::TexelFormat::kRg32Float,
+                                     std::make_tuple(type::TexelFormat::kRg32Float,
                                                      ResourceBinding::TexelFormat::kRg32Float,
                                                      ResourceBinding::SampledKind::kFloat),
-                                     std::make_tuple(ast::TexelFormat::kRg32Sint,
+                                     std::make_tuple(type::TexelFormat::kRg32Sint,
                                                      ResourceBinding::TexelFormat::kRg32Sint,
                                                      ResourceBinding::SampledKind::kSInt),
-                                     std::make_tuple(ast::TexelFormat::kRg32Uint,
+                                     std::make_tuple(type::TexelFormat::kRg32Uint,
                                                      ResourceBinding::TexelFormat::kRg32Uint,
                                                      ResourceBinding::SampledKind::kUInt),
-                                     std::make_tuple(ast::TexelFormat::kRgba16Float,
+                                     std::make_tuple(type::TexelFormat::kRgba16Float,
                                                      ResourceBinding::TexelFormat::kRgba16Float,
                                                      ResourceBinding::SampledKind::kFloat),
-                                     std::make_tuple(ast::TexelFormat::kRgba16Sint,
+                                     std::make_tuple(type::TexelFormat::kRgba16Sint,
                                                      ResourceBinding::TexelFormat::kRgba16Sint,
                                                      ResourceBinding::SampledKind::kSInt),
-                                     std::make_tuple(ast::TexelFormat::kRgba16Uint,
+                                     std::make_tuple(type::TexelFormat::kRgba16Uint,
                                                      ResourceBinding::TexelFormat::kRgba16Uint,
                                                      ResourceBinding::SampledKind::kUInt),
-                                     std::make_tuple(ast::TexelFormat::kRgba32Float,
+                                     std::make_tuple(type::TexelFormat::kRgba32Float,
                                                      ResourceBinding::TexelFormat::kRgba32Float,
                                                      ResourceBinding::SampledKind::kFloat),
-                                     std::make_tuple(ast::TexelFormat::kRgba32Sint,
+                                     std::make_tuple(type::TexelFormat::kRgba32Sint,
                                                      ResourceBinding::TexelFormat::kRgba32Sint,
                                                      ResourceBinding::SampledKind::kSInt),
-                                     std::make_tuple(ast::TexelFormat::kRgba32Uint,
+                                     std::make_tuple(type::TexelFormat::kRgba32Uint,
                                                      ResourceBinding::TexelFormat::kRgba32Uint,
                                                      ResourceBinding::SampledKind::kUInt),
-                                     std::make_tuple(ast::TexelFormat::kRgba8Sint,
+                                     std::make_tuple(type::TexelFormat::kRgba8Sint,
                                                      ResourceBinding::TexelFormat::kRgba8Sint,
                                                      ResourceBinding::SampledKind::kSInt),
-                                     std::make_tuple(ast::TexelFormat::kRgba8Snorm,
+                                     std::make_tuple(type::TexelFormat::kRgba8Snorm,
                                                      ResourceBinding::TexelFormat::kRgba8Snorm,
                                                      ResourceBinding::SampledKind::kFloat),
-                                     std::make_tuple(ast::TexelFormat::kRgba8Uint,
+                                     std::make_tuple(type::TexelFormat::kRgba8Uint,
                                                      ResourceBinding::TexelFormat::kRgba8Uint,
                                                      ResourceBinding::SampledKind::kUInt),
-                                     std::make_tuple(ast::TexelFormat::kRgba8Unorm,
+                                     std::make_tuple(type::TexelFormat::kRgba8Unorm,
                                                      ResourceBinding::TexelFormat::kRgba8Unorm,
                                                      ResourceBinding::SampledKind::kFloat))));
 
@@ -3101,17 +3103,17 @@
     InspectorGetDepthTextureResourceBindingsTest,
     InspectorGetDepthTextureResourceBindingsTestWithParam,
     testing::Values(
-        GetDepthTextureTestParams{ast::TextureDimension::k2d,
+        GetDepthTextureTestParams{type::TextureDimension::k2d,
                                   inspector::ResourceBinding::TextureDimension::k2d},
-        GetDepthTextureTestParams{ast::TextureDimension::k2dArray,
+        GetDepthTextureTestParams{type::TextureDimension::k2dArray,
                                   inspector::ResourceBinding::TextureDimension::k2dArray},
-        GetDepthTextureTestParams{ast::TextureDimension::kCube,
+        GetDepthTextureTestParams{type::TextureDimension::kCube,
                                   inspector::ResourceBinding::TextureDimension::kCube},
-        GetDepthTextureTestParams{ast::TextureDimension::kCubeArray,
+        GetDepthTextureTestParams{type::TextureDimension::kCubeArray,
                                   inspector::ResourceBinding::TextureDimension::kCubeArray}));
 
 TEST_F(InspectorGetDepthMultisampledTextureResourceBindingsTest, textureDimensions) {
-    auto* depth_ms_texture_type = ty.depth_multisampled_texture(ast::TextureDimension::k2d);
+    auto* depth_ms_texture_type = ty.depth_multisampled_texture(type::TextureDimension::k2d);
     AddResource("tex", depth_ms_texture_type, 0, 0);
 
     Func("ep", utils::Empty, ty.void_(),
diff --git a/src/tint/inspector/resource_binding.cc b/src/tint/inspector/resource_binding.cc
index 4dd26e0..91e5daf 100644
--- a/src/tint/inspector/resource_binding.cc
+++ b/src/tint/inspector/resource_binding.cc
@@ -18,6 +18,7 @@
 #include "src/tint/type/f32.h"
 #include "src/tint/type/i32.h"
 #include "src/tint/type/matrix.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/type/type.h"
 #include "src/tint/type/u32.h"
 #include "src/tint/type/vector.h"
@@ -25,21 +26,21 @@
 namespace tint::inspector {
 
 ResourceBinding::TextureDimension TypeTextureDimensionToResourceBindingTextureDimension(
-    const ast::TextureDimension& type_dim) {
+    const type::TextureDimension& type_dim) {
     switch (type_dim) {
-        case ast::TextureDimension::k1d:
+        case type::TextureDimension::k1d:
             return ResourceBinding::TextureDimension::k1d;
-        case ast::TextureDimension::k2d:
+        case type::TextureDimension::k2d:
             return ResourceBinding::TextureDimension::k2d;
-        case ast::TextureDimension::k2dArray:
+        case type::TextureDimension::k2dArray:
             return ResourceBinding::TextureDimension::k2dArray;
-        case ast::TextureDimension::k3d:
+        case type::TextureDimension::k3d:
             return ResourceBinding::TextureDimension::k3d;
-        case ast::TextureDimension::kCube:
+        case type::TextureDimension::kCube:
             return ResourceBinding::TextureDimension::kCube;
-        case ast::TextureDimension::kCubeArray:
+        case type::TextureDimension::kCubeArray:
             return ResourceBinding::TextureDimension::kCubeArray;
-        case ast::TextureDimension::kNone:
+        case type::TextureDimension::kNone:
             return ResourceBinding::TextureDimension::kNone;
     }
     return ResourceBinding::TextureDimension::kNone;
@@ -70,43 +71,43 @@
 }
 
 ResourceBinding::TexelFormat TypeTexelFormatToResourceBindingTexelFormat(
-    const ast::TexelFormat& image_format) {
+    const type::TexelFormat& image_format) {
     switch (image_format) {
-        case ast::TexelFormat::kBgra8Unorm:
+        case type::TexelFormat::kBgra8Unorm:
             return ResourceBinding::TexelFormat::kBgra8Unorm;
-        case ast::TexelFormat::kR32Uint:
+        case type::TexelFormat::kR32Uint:
             return ResourceBinding::TexelFormat::kR32Uint;
-        case ast::TexelFormat::kR32Sint:
+        case type::TexelFormat::kR32Sint:
             return ResourceBinding::TexelFormat::kR32Sint;
-        case ast::TexelFormat::kR32Float:
+        case type::TexelFormat::kR32Float:
             return ResourceBinding::TexelFormat::kR32Float;
-        case ast::TexelFormat::kRgba8Unorm:
+        case type::TexelFormat::kRgba8Unorm:
             return ResourceBinding::TexelFormat::kRgba8Unorm;
-        case ast::TexelFormat::kRgba8Snorm:
+        case type::TexelFormat::kRgba8Snorm:
             return ResourceBinding::TexelFormat::kRgba8Snorm;
-        case ast::TexelFormat::kRgba8Uint:
+        case type::TexelFormat::kRgba8Uint:
             return ResourceBinding::TexelFormat::kRgba8Uint;
-        case ast::TexelFormat::kRgba8Sint:
+        case type::TexelFormat::kRgba8Sint:
             return ResourceBinding::TexelFormat::kRgba8Sint;
-        case ast::TexelFormat::kRg32Uint:
+        case type::TexelFormat::kRg32Uint:
             return ResourceBinding::TexelFormat::kRg32Uint;
-        case ast::TexelFormat::kRg32Sint:
+        case type::TexelFormat::kRg32Sint:
             return ResourceBinding::TexelFormat::kRg32Sint;
-        case ast::TexelFormat::kRg32Float:
+        case type::TexelFormat::kRg32Float:
             return ResourceBinding::TexelFormat::kRg32Float;
-        case ast::TexelFormat::kRgba16Uint:
+        case type::TexelFormat::kRgba16Uint:
             return ResourceBinding::TexelFormat::kRgba16Uint;
-        case ast::TexelFormat::kRgba16Sint:
+        case type::TexelFormat::kRgba16Sint:
             return ResourceBinding::TexelFormat::kRgba16Sint;
-        case ast::TexelFormat::kRgba16Float:
+        case type::TexelFormat::kRgba16Float:
             return ResourceBinding::TexelFormat::kRgba16Float;
-        case ast::TexelFormat::kRgba32Uint:
+        case type::TexelFormat::kRgba32Uint:
             return ResourceBinding::TexelFormat::kRgba32Uint;
-        case ast::TexelFormat::kRgba32Sint:
+        case type::TexelFormat::kRgba32Sint:
             return ResourceBinding::TexelFormat::kRgba32Sint;
-        case ast::TexelFormat::kRgba32Float:
+        case type::TexelFormat::kRgba32Float:
             return ResourceBinding::TexelFormat::kRgba32Float;
-        case ast::TexelFormat::kUndefined:
+        case type::TexelFormat::kUndefined:
             return ResourceBinding::TexelFormat::kNone;
     }
     return ResourceBinding::TexelFormat::kNone;
diff --git a/src/tint/inspector/resource_binding.h b/src/tint/inspector/resource_binding.h
index ef22578..d968604 100644
--- a/src/tint/inspector/resource_binding.h
+++ b/src/tint/inspector/resource_binding.h
@@ -18,7 +18,7 @@
 #include <cstdint>
 
 #include "src/tint/ast/storage_texture.h"
-#include "src/tint/ast/texture.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/type/type.h"
 
 namespace tint::inspector {
@@ -104,24 +104,24 @@
     TexelFormat image_format;
 };
 
-/// Convert from internal ast::TextureDimension to public
+/// Convert from internal type::TextureDimension to public
 /// ResourceBinding::TextureDimension
 /// @param type_dim internal value to convert from
 /// @returns the publicly visible equivalent
 ResourceBinding::TextureDimension TypeTextureDimensionToResourceBindingTextureDimension(
-    const ast::TextureDimension& type_dim);
+    const type::TextureDimension& type_dim);
 
 /// Infer ResourceBinding::SampledKind for a given type::Type
 /// @param base_type internal type to infer from
 /// @returns the publicly visible equivalent
 ResourceBinding::SampledKind BaseTypeToSampledKind(const type::Type* base_type);
 
-/// Convert from internal ast::TexelFormat to public
+/// Convert from internal type::TexelFormat to public
 /// ResourceBinding::TexelFormat
 /// @param image_format internal value to convert from
 /// @returns the publicly visible equivalent
 ResourceBinding::TexelFormat TypeTexelFormatToResourceBindingTexelFormat(
-    const ast::TexelFormat& image_format);
+    const type::TexelFormat& image_format);
 
 }  // namespace tint::inspector
 
diff --git a/src/tint/inspector/test_inspector_builder.cc b/src/tint/inspector/test_inspector_builder.cc
index 97ae097..a24f18a 100644
--- a/src/tint/inspector/test_inspector_builder.cc
+++ b/src/tint/inspector/test_inspector_builder.cc
@@ -126,19 +126,19 @@
                                         const ast::Type* type,
                                         uint32_t group,
                                         uint32_t binding) {
-    GlobalVar(name, type, ast::AddressSpace::kUniform, Binding(AInt(binding)), Group(AInt(group)));
+    GlobalVar(name, type, type::AddressSpace::kUniform, Binding(AInt(binding)), Group(AInt(group)));
 }
 
 void InspectorBuilder::AddWorkgroupStorage(const std::string& name, const ast::Type* type) {
-    GlobalVar(name, type, ast::AddressSpace::kWorkgroup);
+    GlobalVar(name, type, type::AddressSpace::kWorkgroup);
 }
 
 void InspectorBuilder::AddStorageBuffer(const std::string& name,
                                         const ast::Type* type,
-                                        ast::Access access,
+                                        type::Access access,
                                         uint32_t group,
                                         uint32_t binding) {
-    GlobalVar(name, type, ast::AddressSpace::kStorage, access, Binding(AInt(binding)),
+    GlobalVar(name, type, type::AddressSpace::kStorage, access, Binding(AInt(binding)),
               Group(AInt(group)));
 }
 
@@ -188,7 +188,7 @@
 }
 
 void InspectorBuilder::AddGlobalVariable(const std::string& name, const ast::Type* type) {
-    GlobalVar(name, type, ast::AddressSpace::kPrivate);
+    GlobalVar(name, type, type::AddressSpace::kPrivate);
 }
 
 const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
@@ -259,17 +259,17 @@
     }
 }
 
-const ast::Type* InspectorBuilder::GetCoordsType(ast::TextureDimension dim,
+const ast::Type* InspectorBuilder::GetCoordsType(type::TextureDimension dim,
                                                  const ast::Type* scalar) {
     switch (dim) {
-        case ast::TextureDimension::k1d:
+        case type::TextureDimension::k1d:
             return scalar;
-        case ast::TextureDimension::k2d:
-        case ast::TextureDimension::k2dArray:
+        case type::TextureDimension::k2d:
+        case type::TextureDimension::k2dArray:
             return create<ast::Vector>(scalar, 2u);
-        case ast::TextureDimension::k3d:
-        case ast::TextureDimension::kCube:
-        case ast::TextureDimension::kCubeArray:
+        case type::TextureDimension::k3d:
+        case type::TextureDimension::kCube:
+        case type::TextureDimension::kCubeArray:
             return create<ast::Vector>(scalar, 3u);
         default:
             [=]() { FAIL() << "Unsupported texture dimension: " << dim; }();
@@ -277,9 +277,9 @@
     return nullptr;
 }
 
-const ast::Type* InspectorBuilder::MakeStorageTextureTypes(ast::TextureDimension dim,
-                                                           ast::TexelFormat format) {
-    return ty.storage_texture(dim, format, ast::Access::kWrite);
+const ast::Type* InspectorBuilder::MakeStorageTextureTypes(type::TextureDimension dim,
+                                                           type::TexelFormat format) {
+    return ty.storage_texture(dim, format, type::Access::kWrite);
 }
 
 void InspectorBuilder::AddStorageTexture(const std::string& name,
diff --git a/src/tint/inspector/test_inspector_builder.h b/src/tint/inspector/test_inspector_builder.h
index 8439bd6..cfba3ac 100644
--- a/src/tint/inspector/test_inspector_builder.h
+++ b/src/tint/inspector/test_inspector_builder.h
@@ -31,6 +31,7 @@
 #include "src/tint/type/external_texture.h"
 #include "src/tint/type/multisampled_texture.h"
 #include "src/tint/type/sampled_texture.h"
+#include "src/tint/type/texture_dimension.h"
 #include "tint/tint.h"
 
 namespace tint::inspector {
@@ -182,7 +183,7 @@
     /// @param binding the binding number to use for the storage buffer
     void AddStorageBuffer(const std::string& name,
                           const ast::Type* type,
-                          ast::Access access,
+                          type::Access access,
                           uint32_t group,
                           uint32_t binding);
 
@@ -287,13 +288,13 @@
     /// @param dim dimensionality of the texture being sampled
     /// @param scalar the scalar type
     /// @returns a pointer to a type appropriate for the coord param
-    const ast::Type* GetCoordsType(ast::TextureDimension dim, const ast::Type* scalar);
+    const ast::Type* GetCoordsType(type::TextureDimension dim, const ast::Type* scalar);
 
     /// Generates appropriate types for a Read-Only StorageTexture
     /// @param dim the texture dimension of the storage texture
     /// @param format the texel format of the storage texture
     /// @returns the storage texture type
-    const ast::Type* MakeStorageTextureTypes(ast::TextureDimension dim, ast::TexelFormat format);
+    const ast::Type* MakeStorageTextureTypes(type::TextureDimension dim, type::TexelFormat format);
 
     /// Adds a storage texture variable to the program
     /// @param name the name of the variable
diff --git a/src/tint/ir/builder_impl_test.cc b/src/tint/ir/builder_impl_test.cc
index 9dc908d..6424631 100644
--- a/src/tint/ir/builder_impl_test.cc
+++ b/src/tint/ir/builder_impl_test.cc
@@ -1468,7 +1468,7 @@
 
 TEST_F(IR_BuilderImplTest, EmitLiteral_Bool_True) {
     auto* expr = Expr(true);
-    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate, expr);
+    GlobalVar("a", ty.bool_(), type::AddressSpace::kPrivate, expr);
 
     auto& b = CreateBuilder();
     auto r = b.EmitLiteral(expr);
@@ -1482,7 +1482,7 @@
 
 TEST_F(IR_BuilderImplTest, EmitLiteral_Bool_False) {
     auto* expr = Expr(false);
-    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate, expr);
+    GlobalVar("a", ty.bool_(), type::AddressSpace::kPrivate, expr);
 
     auto& b = CreateBuilder();
     auto r = b.EmitLiteral(expr);
@@ -1496,7 +1496,7 @@
 
 TEST_F(IR_BuilderImplTest, EmitLiteral_F32) {
     auto* expr = Expr(1.2_f);
-    GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate, expr);
+    GlobalVar("a", ty.f32(), type::AddressSpace::kPrivate, expr);
 
     auto& b = CreateBuilder();
     auto r = b.EmitLiteral(expr);
@@ -1511,7 +1511,7 @@
 TEST_F(IR_BuilderImplTest, EmitLiteral_F16) {
     Enable(ast::Extension::kF16);
     auto* expr = Expr(1.2_h);
-    GlobalVar("a", ty.f16(), ast::AddressSpace::kPrivate, expr);
+    GlobalVar("a", ty.f16(), type::AddressSpace::kPrivate, expr);
 
     auto& b = CreateBuilder();
     auto r = b.EmitLiteral(expr);
@@ -1525,7 +1525,7 @@
 
 TEST_F(IR_BuilderImplTest, EmitLiteral_I32) {
     auto* expr = Expr(-2_i);
-    GlobalVar("a", ty.i32(), ast::AddressSpace::kPrivate, expr);
+    GlobalVar("a", ty.i32(), type::AddressSpace::kPrivate, expr);
 
     auto& b = CreateBuilder();
     auto r = b.EmitLiteral(expr);
@@ -1539,7 +1539,7 @@
 
 TEST_F(IR_BuilderImplTest, EmitLiteral_U32) {
     auto* expr = Expr(2_u);
-    GlobalVar("a", ty.u32(), ast::AddressSpace::kPrivate, expr);
+    GlobalVar("a", ty.u32(), type::AddressSpace::kPrivate, expr);
 
     auto& b = CreateBuilder();
     auto r = b.EmitLiteral(expr);
diff --git a/src/tint/program_builder.h b/src/tint/program_builder.h
index 9b688f0..5e8f669 100644
--- a/src/tint/program_builder.h
+++ b/src/tint/program_builder.h
@@ -107,6 +107,7 @@
 #include "src/tint/type/pointer.h"
 #include "src/tint/type/sampled_texture.h"
 #include "src/tint/type/storage_texture.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/type/u32.h"
 #include "src/tint/type/vector.h"
 #include "src/tint/type/void.h"
@@ -180,15 +181,15 @@
         ~VarOptions();
 
         const ast::Type* type = nullptr;
-        ast::AddressSpace address_space = ast::AddressSpace::kNone;
-        ast::Access access = ast::Access::kUndefined;
+        type::AddressSpace address_space = type::AddressSpace::kNone;
+        type::Access access = type::Access::kUndefined;
         const ast::Expression* initializer = nullptr;
         utils::Vector<const ast::Attribute*, 4> attributes;
 
       private:
         void Set(const ast::Type* t) { type = t; }
-        void Set(ast::AddressSpace addr_space) { address_space = addr_space; }
-        void Set(ast::Access ac) { access = ac; }
+        void Set(type::AddressSpace addr_space) { address_space = addr_space; }
+        void Set(type::Access ac) { access = ac; }
         void Set(const ast::Expression* c) { initializer = c; }
         void Set(utils::VectorRef<const ast::Attribute*> l) { attributes = std::move(l); }
         void Set(const ast::Attribute* a) { attributes.Push(a); }
@@ -939,10 +940,10 @@
         /// @param type the type of the pointer
         /// @param address_space the address space of the pointer
         /// @param access the optional access control of the pointer
-        /// @return the pointer to `type` with the given ast::AddressSpace
+        /// @return the pointer to `type` with the given type::AddressSpace
         const ast::Pointer* pointer(const ast::Type* type,
-                                    ast::AddressSpace address_space,
-                                    ast::Access access = ast::Access::kUndefined) const {
+                                    type::AddressSpace address_space,
+                                    type::Access access = type::Access::kUndefined) const {
             return builder->create<ast::Pointer>(type, address_space, access);
         }
 
@@ -950,31 +951,31 @@
         /// @param type the type of the pointer
         /// @param address_space the address space of the pointer
         /// @param access the optional access control of the pointer
-        /// @return the pointer to `type` with the given ast::AddressSpace
+        /// @return the pointer to `type` with the given type::AddressSpace
         const ast::Pointer* pointer(const Source& source,
                                     const ast::Type* type,
-                                    ast::AddressSpace address_space,
-                                    ast::Access access = ast::Access::kUndefined) const {
+                                    type::AddressSpace address_space,
+                                    type::Access access = type::Access::kUndefined) const {
             return builder->create<ast::Pointer>(source, type, address_space, access);
         }
 
         /// @param address_space the address space of the pointer
         /// @param access the optional access control of the pointer
-        /// @return the pointer to type `T` with the given ast::AddressSpace.
+        /// @return the pointer to type `T` with the given type::AddressSpace.
         template <typename T>
-        const ast::Pointer* pointer(ast::AddressSpace address_space,
-                                    ast::Access access = ast::Access::kUndefined) const {
+        const ast::Pointer* pointer(type::AddressSpace address_space,
+                                    type::Access access = type::Access::kUndefined) const {
             return pointer(Of<T>(), address_space, access);
         }
 
         /// @param source the Source of the node
         /// @param address_space the address space of the pointer
         /// @param access the optional access control of the pointer
-        /// @return the pointer to type `T` with the given ast::AddressSpace.
+        /// @return the pointer to type `T` with the given type::AddressSpace.
         template <typename T>
         const ast::Pointer* pointer(const Source& source,
-                                    ast::AddressSpace address_space,
-                                    ast::Access access = ast::Access::kUndefined) const {
+                                    type::AddressSpace address_space,
+                                    type::Access access = type::Access::kUndefined) const {
             return pointer(source, Of<T>(), address_space, access);
         }
 
@@ -1012,7 +1013,7 @@
 
         /// @param dims the dimensionality of the texture
         /// @returns the depth texture
-        const ast::DepthTexture* depth_texture(ast::TextureDimension dims) const {
+        const ast::DepthTexture* depth_texture(type::TextureDimension dims) const {
             return builder->create<ast::DepthTexture>(dims);
         }
 
@@ -1020,14 +1021,14 @@
         /// @param dims the dimensionality of the texture
         /// @returns the depth texture
         const ast::DepthTexture* depth_texture(const Source& source,
-                                               ast::TextureDimension dims) const {
+                                               type::TextureDimension dims) const {
             return builder->create<ast::DepthTexture>(source, dims);
         }
 
         /// @param dims the dimensionality of the texture
         /// @returns the multisampled depth texture
         const ast::DepthMultisampledTexture* depth_multisampled_texture(
-            ast::TextureDimension dims) const {
+            type::TextureDimension dims) const {
             return builder->create<ast::DepthMultisampledTexture>(dims);
         }
 
@@ -1036,14 +1037,14 @@
         /// @returns the multisampled depth texture
         const ast::DepthMultisampledTexture* depth_multisampled_texture(
             const Source& source,
-            ast::TextureDimension dims) const {
+            type::TextureDimension dims) const {
             return builder->create<ast::DepthMultisampledTexture>(source, dims);
         }
 
         /// @param dims the dimensionality of the texture
         /// @param subtype the texture subtype.
         /// @returns the sampled texture
-        const ast::SampledTexture* sampled_texture(ast::TextureDimension dims,
+        const ast::SampledTexture* sampled_texture(type::TextureDimension dims,
                                                    const ast::Type* subtype) const {
             return builder->create<ast::SampledTexture>(dims, subtype);
         }
@@ -1053,7 +1054,7 @@
         /// @param subtype the texture subtype.
         /// @returns the sampled texture
         const ast::SampledTexture* sampled_texture(const Source& source,
-                                                   ast::TextureDimension dims,
+                                                   type::TextureDimension dims,
                                                    const ast::Type* subtype) const {
             return builder->create<ast::SampledTexture>(source, dims, subtype);
         }
@@ -1061,7 +1062,7 @@
         /// @param dims the dimensionality of the texture
         /// @param subtype the texture subtype.
         /// @returns the multisampled texture
-        const ast::MultisampledTexture* multisampled_texture(ast::TextureDimension dims,
+        const ast::MultisampledTexture* multisampled_texture(type::TextureDimension dims,
                                                              const ast::Type* subtype) const {
             return builder->create<ast::MultisampledTexture>(dims, subtype);
         }
@@ -1071,7 +1072,7 @@
         /// @param subtype the texture subtype.
         /// @returns the multisampled texture
         const ast::MultisampledTexture* multisampled_texture(const Source& source,
-                                                             ast::TextureDimension dims,
+                                                             type::TextureDimension dims,
                                                              const ast::Type* subtype) const {
             return builder->create<ast::MultisampledTexture>(source, dims, subtype);
         }
@@ -1080,9 +1081,9 @@
         /// @param format the texel format of the texture
         /// @param access the access control of the texture
         /// @returns the storage texture
-        const ast::StorageTexture* storage_texture(ast::TextureDimension dims,
-                                                   ast::TexelFormat format,
-                                                   ast::Access access) const {
+        const ast::StorageTexture* storage_texture(type::TextureDimension dims,
+                                                   type::TexelFormat format,
+                                                   type::Access access) const {
             auto* subtype = ast::StorageTexture::SubtypeFor(format, *builder);
             return builder->create<ast::StorageTexture>(dims, format, subtype, access);
         }
@@ -1093,9 +1094,9 @@
         /// @param access the access control of the texture
         /// @returns the storage texture
         const ast::StorageTexture* storage_texture(const Source& source,
-                                                   ast::TextureDimension dims,
-                                                   ast::TexelFormat format,
-                                                   ast::Access access) const {
+                                                   type::TextureDimension dims,
+                                                   type::TexelFormat format,
+                                                   type::Access access) const {
             auto* subtype = ast::StorageTexture::SubtypeFor(format, *builder);
             return builder->create<ast::StorageTexture>(source, dims, format, subtype, access);
         }
@@ -1696,8 +1697,8 @@
     /// @param options the extra options passed to the ast::Var initializer
     /// Can be any of the following, in any order:
     ///   * ast::Type*          - specifies the variable type
-    ///   * ast::AddressSpace   - specifies the variable address space
-    ///   * ast::Access         - specifies the variable's access control
+    ///   * type::AddressSpace   - specifies the variable address space
+    ///   * type::Access         - specifies the variable's access control
     ///   * ast::Expression*    - specifies the variable's initializer expression
     ///   * ast::Attribute*     - specifies the variable's attributes (repeatable, or vector)
     /// Note that non-repeatable arguments of the same type will use the last argument's value.
@@ -1715,8 +1716,8 @@
     /// @param options the extra options passed to the ast::Var initializer
     /// Can be any of the following, in any order:
     ///   * ast::Type*          - specifies the variable type
-    ///   * ast::AddressSpace   - specifies the variable address space
-    ///   * ast::Access         - specifies the variable's access control
+    ///   * type::AddressSpace   - specifies the variable address space
+    ///   * type::Access         - specifies the variable's access control
     ///   * ast::Expression*    - specifies the variable's initializer expression
     ///   * ast::Attribute*     - specifies the variable's attributes (repeatable, or vector)
     /// Note that non-repeatable arguments of the same type will use the last argument's value.
@@ -1819,8 +1820,8 @@
     /// @param options the extra options passed to the ast::Var initializer
     /// Can be any of the following, in any order:
     ///   * ast::Type*          - specifies the variable type
-    ///   * ast::AddressSpace   - specifies the variable address space
-    ///   * ast::Access         - specifies the variable's access control
+    ///   * type::AddressSpace   - specifies the variable address space
+    ///   * type::Access         - specifies the variable's access control
     ///   * ast::Expression*    - specifies the variable's initializer expression
     ///   * ast::Attribute*     - specifies the variable's attributes (repeatable, or vector)
     /// Note that non-repeatable arguments of the same type will use the last argument's value.
@@ -1838,8 +1839,8 @@
     /// @param options the extra options passed to the ast::Var initializer
     /// Can be any of the following, in any order:
     ///   * ast::Type*          - specifies the variable type
-    ///   * ast::AddressSpace   - specifies the variable address space
-    ///   * ast::Access         - specifies the variable's access control
+    ///   * type::AddressSpace   - specifies the variable address space
+    ///   * type::Access         - specifies the variable's access control
     ///   * ast::Expression*    - specifies the variable's initializer expression
     ///   * ast::Attribute*    - specifies the variable's attributes (repeatable, or vector)
     /// Note that non-repeatable arguments of the same type will use the last argument's value.
diff --git a/src/tint/program_test.cc b/src/tint/program_test.cc
index d2f1673..f856504 100644
--- a/src/tint/program_test.cc
+++ b/src/tint/program_test.cc
@@ -46,7 +46,7 @@
 }
 
 TEST_F(ProgramTest, Assert_GlobalVariable) {
-    GlobalVar("var", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("var", ty.f32(), type::AddressSpace::kPrivate);
 
     Program program(std::move(*this));
     EXPECT_TRUE(program.IsValid());
diff --git a/src/tint/reader/spirv/enum_converter.cc b/src/tint/reader/spirv/enum_converter.cc
index 8c70156..901401f 100644
--- a/src/tint/reader/spirv/enum_converter.cc
+++ b/src/tint/reader/spirv/enum_converter.cc
@@ -14,6 +14,8 @@
 
 #include "src/tint/reader/spirv/enum_converter.h"
 
+#include "src/tint/type/texture_dimension.h"
+
 namespace tint::reader::spirv {
 
 EnumConverter::EnumConverter(const FailStream& fs) : fail_stream_(fs) {}
@@ -36,30 +38,30 @@
     return ast::PipelineStage::kNone;
 }
 
-ast::AddressSpace EnumConverter::ToAddressSpace(const spv::StorageClass sc) {
+type::AddressSpace EnumConverter::ToAddressSpace(const spv::StorageClass sc) {
     switch (sc) {
         case spv::StorageClass::Input:
-            return ast::AddressSpace::kIn;
+            return type::AddressSpace::kIn;
         case spv::StorageClass::Output:
-            return ast::AddressSpace::kOut;
+            return type::AddressSpace::kOut;
         case spv::StorageClass::Uniform:
-            return ast::AddressSpace::kUniform;
+            return type::AddressSpace::kUniform;
         case spv::StorageClass::Workgroup:
-            return ast::AddressSpace::kWorkgroup;
+            return type::AddressSpace::kWorkgroup;
         case spv::StorageClass::UniformConstant:
-            return ast::AddressSpace::kNone;
+            return type::AddressSpace::kNone;
         case spv::StorageClass::StorageBuffer:
-            return ast::AddressSpace::kStorage;
+            return type::AddressSpace::kStorage;
         case spv::StorageClass::Private:
-            return ast::AddressSpace::kPrivate;
+            return type::AddressSpace::kPrivate;
         case spv::StorageClass::Function:
-            return ast::AddressSpace::kFunction;
+            return type::AddressSpace::kFunction;
         default:
             break;
     }
 
     Fail() << "unknown SPIR-V storage class: " << uint32_t(sc);
-    return ast::AddressSpace::kUndefined;
+    return type::AddressSpace::kUndefined;
 }
 
 ast::BuiltinValue EnumConverter::ToBuiltin(spv::BuiltIn b) {
@@ -98,83 +100,83 @@
     return ast::BuiltinValue::kUndefined;
 }
 
-ast::TextureDimension EnumConverter::ToDim(spv::Dim dim, bool arrayed) {
+type::TextureDimension EnumConverter::ToDim(spv::Dim dim, bool arrayed) {
     if (arrayed) {
         switch (dim) {
             case spv::Dim::Dim2D:
-                return ast::TextureDimension::k2dArray;
+                return type::TextureDimension::k2dArray;
             case spv::Dim::Cube:
-                return ast::TextureDimension::kCubeArray;
+                return type::TextureDimension::kCubeArray;
             default:
                 break;
         }
         Fail() << "arrayed dimension must be 2D or Cube. Got " << int(dim);
-        return ast::TextureDimension::kNone;
+        return type::TextureDimension::kNone;
     }
     // Assume non-arrayed
     switch (dim) {
         case spv::Dim::Dim1D:
-            return ast::TextureDimension::k1d;
+            return type::TextureDimension::k1d;
         case spv::Dim::Dim2D:
-            return ast::TextureDimension::k2d;
+            return type::TextureDimension::k2d;
         case spv::Dim::Dim3D:
-            return ast::TextureDimension::k3d;
+            return type::TextureDimension::k3d;
         case spv::Dim::Cube:
-            return ast::TextureDimension::kCube;
+            return type::TextureDimension::kCube;
         default:
             break;
     }
     Fail() << "invalid dimension: " << int(dim);
-    return ast::TextureDimension::kNone;
+    return type::TextureDimension::kNone;
 }
 
-ast::TexelFormat EnumConverter::ToTexelFormat(spv::ImageFormat fmt) {
+type::TexelFormat EnumConverter::ToTexelFormat(spv::ImageFormat fmt) {
     switch (fmt) {
         case spv::ImageFormat::Unknown:
-            return ast::TexelFormat::kUndefined;
+            return type::TexelFormat::kUndefined;
 
         // 8 bit channels
         case spv::ImageFormat::Rgba8:
-            return ast::TexelFormat::kRgba8Unorm;
+            return type::TexelFormat::kRgba8Unorm;
         case spv::ImageFormat::Rgba8Snorm:
-            return ast::TexelFormat::kRgba8Snorm;
+            return type::TexelFormat::kRgba8Snorm;
         case spv::ImageFormat::Rgba8ui:
-            return ast::TexelFormat::kRgba8Uint;
+            return type::TexelFormat::kRgba8Uint;
         case spv::ImageFormat::Rgba8i:
-            return ast::TexelFormat::kRgba8Sint;
+            return type::TexelFormat::kRgba8Sint;
 
         // 16 bit channels
         case spv::ImageFormat::Rgba16ui:
-            return ast::TexelFormat::kRgba16Uint;
+            return type::TexelFormat::kRgba16Uint;
         case spv::ImageFormat::Rgba16i:
-            return ast::TexelFormat::kRgba16Sint;
+            return type::TexelFormat::kRgba16Sint;
         case spv::ImageFormat::Rgba16f:
-            return ast::TexelFormat::kRgba16Float;
+            return type::TexelFormat::kRgba16Float;
 
         // 32 bit channels
         case spv::ImageFormat::R32ui:
-            return ast::TexelFormat::kR32Uint;
+            return type::TexelFormat::kR32Uint;
         case spv::ImageFormat::R32i:
-            return ast::TexelFormat::kR32Sint;
+            return type::TexelFormat::kR32Sint;
         case spv::ImageFormat::R32f:
-            return ast::TexelFormat::kR32Float;
+            return type::TexelFormat::kR32Float;
         case spv::ImageFormat::Rg32ui:
-            return ast::TexelFormat::kRg32Uint;
+            return type::TexelFormat::kRg32Uint;
         case spv::ImageFormat::Rg32i:
-            return ast::TexelFormat::kRg32Sint;
+            return type::TexelFormat::kRg32Sint;
         case spv::ImageFormat::Rg32f:
-            return ast::TexelFormat::kRg32Float;
+            return type::TexelFormat::kRg32Float;
         case spv::ImageFormat::Rgba32ui:
-            return ast::TexelFormat::kRgba32Uint;
+            return type::TexelFormat::kRgba32Uint;
         case spv::ImageFormat::Rgba32i:
-            return ast::TexelFormat::kRgba32Sint;
+            return type::TexelFormat::kRgba32Sint;
         case spv::ImageFormat::Rgba32f:
-            return ast::TexelFormat::kRgba32Float;
+            return type::TexelFormat::kRgba32Float;
         default:
             break;
     }
     Fail() << "invalid image format: " << int(fmt);
-    return ast::TexelFormat::kUndefined;
+    return type::TexelFormat::kUndefined;
 }
 
 }  // namespace tint::reader::spirv
diff --git a/src/tint/reader/spirv/enum_converter.h b/src/tint/reader/spirv/enum_converter.h
index 6b7a889..f3cc037 100644
--- a/src/tint/reader/spirv/enum_converter.h
+++ b/src/tint/reader/spirv/enum_converter.h
@@ -17,11 +17,12 @@
 
 #include "spirv/unified1/spirv.h"
 #include "spirv/unified1/spirv.hpp11"
-#include "src/tint/ast/address_space.h"
 #include "src/tint/ast/builtin_value.h"
 #include "src/tint/ast/pipeline_stage.h"
 #include "src/tint/reader/spirv/fail_stream.h"
+#include "src/tint/type/address_space.h"
 #include "src/tint/type/storage_texture.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::reader::spirv {
 
@@ -44,7 +45,7 @@
     /// On failure, logs an error and returns kNone
     /// @param sc the SPIR-V storage class
     /// @returns a Tint AST address space
-    ast::AddressSpace ToAddressSpace(const spv::StorageClass sc);
+    type::AddressSpace ToAddressSpace(const spv::StorageClass sc);
 
     /// Converts a SPIR-V Builtin value a Tint Builtin.
     /// On failure, logs an error and returns kNone
@@ -57,14 +58,14 @@
     /// @param dim the SPIR-V Dim value
     /// @param arrayed true if the texture is arrayed
     /// @returns a Tint AST texture dimension
-    ast::TextureDimension ToDim(spv::Dim dim, bool arrayed);
+    type::TextureDimension ToDim(spv::Dim dim, bool arrayed);
 
     /// Converts a possibly arrayed SPIR-V Dim to a Tint texture dimension.
     /// On failure, logs an error and returns kNone
     /// @param dim the SPIR-V Dim value
     /// @param arrayed true if the texture is arrayed
     /// @returns a Tint AST texture dimension
-    ast::TextureDimension ToDim(SpvDim dim, bool arrayed) {
+    type::TextureDimension ToDim(SpvDim dim, bool arrayed) {
         return ToDim(static_cast<spv::Dim>(dim), arrayed);
     }
 
@@ -72,13 +73,13 @@
     /// On failure, logs an error and returns kNone
     /// @param fmt the SPIR-V format
     /// @returns a Tint AST format
-    ast::TexelFormat ToTexelFormat(spv::ImageFormat fmt);
+    type::TexelFormat ToTexelFormat(spv::ImageFormat fmt);
 
     /// Converts a SPIR-V Image Format to a TexelFormat
     /// On failure, logs an error and returns kNone
     /// @param fmt the SPIR-V format
     /// @returns a Tint AST format
-    ast::TexelFormat ToTexelFormat(SpvImageFormat fmt) {
+    type::TexelFormat ToTexelFormat(SpvImageFormat fmt) {
         return ToTexelFormat(static_cast<spv::ImageFormat>(fmt));
     }
 
diff --git a/src/tint/reader/spirv/enum_converter_test.cc b/src/tint/reader/spirv/enum_converter_test.cc
index bdb0247..e0982ac 100644
--- a/src/tint/reader/spirv/enum_converter_test.cc
+++ b/src/tint/reader/spirv/enum_converter_test.cc
@@ -17,6 +17,7 @@
 #include <string>
 
 #include "gmock/gmock.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::reader::spirv {
 namespace {
@@ -84,7 +85,7 @@
 struct StorageClassCase {
     spv::StorageClass sc;
     bool expect_success;
-    ast::AddressSpace expected;
+    type::AddressSpace expected;
 };
 inline std::ostream& operator<<(std::ostream& out, StorageClassCase scc) {
     out << "StorageClassCase{ spv::StorageClass:::" << int(scc.sc)
@@ -125,19 +126,19 @@
     EnumConverterGood,
     SpvStorageClassTest,
     testing::Values(
-        StorageClassCase{spv::StorageClass::Input, true, ast::AddressSpace::kIn},
-        StorageClassCase{spv::StorageClass::Output, true, ast::AddressSpace::kOut},
-        StorageClassCase{spv::StorageClass::Uniform, true, ast::AddressSpace::kUniform},
-        StorageClassCase{spv::StorageClass::Workgroup, true, ast::AddressSpace::kWorkgroup},
-        StorageClassCase{spv::StorageClass::UniformConstant, true, ast::AddressSpace::kNone},
-        StorageClassCase{spv::StorageClass::StorageBuffer, true, ast::AddressSpace::kStorage},
-        StorageClassCase{spv::StorageClass::Private, true, ast::AddressSpace::kPrivate},
-        StorageClassCase{spv::StorageClass::Function, true, ast::AddressSpace::kFunction}));
+        StorageClassCase{spv::StorageClass::Input, true, type::AddressSpace::kIn},
+        StorageClassCase{spv::StorageClass::Output, true, type::AddressSpace::kOut},
+        StorageClassCase{spv::StorageClass::Uniform, true, type::AddressSpace::kUniform},
+        StorageClassCase{spv::StorageClass::Workgroup, true, type::AddressSpace::kWorkgroup},
+        StorageClassCase{spv::StorageClass::UniformConstant, true, type::AddressSpace::kNone},
+        StorageClassCase{spv::StorageClass::StorageBuffer, true, type::AddressSpace::kStorage},
+        StorageClassCase{spv::StorageClass::Private, true, type::AddressSpace::kPrivate},
+        StorageClassCase{spv::StorageClass::Function, true, type::AddressSpace::kFunction}));
 
 INSTANTIATE_TEST_SUITE_P(EnumConverterBad,
                          SpvStorageClassTest,
                          testing::Values(StorageClassCase{static_cast<spv::StorageClass>(9999),
-                                                          false, ast::AddressSpace::kUndefined}));
+                                                          false, type::AddressSpace::kUndefined}));
 
 // Builtin
 
@@ -217,7 +218,7 @@
     spv::Dim dim;
     bool arrayed;
     bool expect_success;
-    ast::TextureDimension expected;
+    type::TextureDimension expected;
 };
 inline std::ostream& operator<<(std::ostream& out, DimCase dc) {
     out << "DimCase{ spv::Dim:::" << int(dc.dim) << " arrayed?:" << int(dc.arrayed)
@@ -256,38 +257,38 @@
                          SpvDimTest,
                          testing::Values(
                              // Non-arrayed
-                             DimCase{spv::Dim::Dim1D, false, true, ast::TextureDimension::k1d},
-                             DimCase{spv::Dim::Dim2D, false, true, ast::TextureDimension::k2d},
-                             DimCase{spv::Dim::Dim3D, false, true, ast::TextureDimension::k3d},
-                             DimCase{spv::Dim::Cube, false, true, ast::TextureDimension::kCube},
+                             DimCase{spv::Dim::Dim1D, false, true, type::TextureDimension::k1d},
+                             DimCase{spv::Dim::Dim2D, false, true, type::TextureDimension::k2d},
+                             DimCase{spv::Dim::Dim3D, false, true, type::TextureDimension::k3d},
+                             DimCase{spv::Dim::Cube, false, true, type::TextureDimension::kCube},
                              // Arrayed
-                             DimCase{spv::Dim::Dim2D, true, true, ast::TextureDimension::k2dArray},
+                             DimCase{spv::Dim::Dim2D, true, true, type::TextureDimension::k2dArray},
                              DimCase{spv::Dim::Cube, true, true,
-                                     ast::TextureDimension::kCubeArray}));
+                                     type::TextureDimension::kCubeArray}));
 
 INSTANTIATE_TEST_SUITE_P(
     EnumConverterBad,
     SpvDimTest,
     testing::Values(
         // Invalid SPIR-V dimensionality.
-        DimCase{spv::Dim::Max, false, false, ast::TextureDimension::kNone},
-        DimCase{spv::Dim::Max, true, false, ast::TextureDimension::kNone},
+        DimCase{spv::Dim::Max, false, false, type::TextureDimension::kNone},
+        DimCase{spv::Dim::Max, true, false, type::TextureDimension::kNone},
         // Vulkan non-arrayed dimensionalities not supported by WGSL.
-        DimCase{spv::Dim::Rect, false, false, ast::TextureDimension::kNone},
-        DimCase{spv::Dim::Buffer, false, false, ast::TextureDimension::kNone},
-        DimCase{spv::Dim::SubpassData, false, false, ast::TextureDimension::kNone},
+        DimCase{spv::Dim::Rect, false, false, type::TextureDimension::kNone},
+        DimCase{spv::Dim::Buffer, false, false, type::TextureDimension::kNone},
+        DimCase{spv::Dim::SubpassData, false, false, type::TextureDimension::kNone},
         // Arrayed dimensionalities not supported by WGSL
-        DimCase{spv::Dim::Dim3D, true, false, ast::TextureDimension::kNone},
-        DimCase{spv::Dim::Rect, true, false, ast::TextureDimension::kNone},
-        DimCase{spv::Dim::Buffer, true, false, ast::TextureDimension::kNone},
-        DimCase{spv::Dim::SubpassData, true, false, ast::TextureDimension::kNone}));
+        DimCase{spv::Dim::Dim3D, true, false, type::TextureDimension::kNone},
+        DimCase{spv::Dim::Rect, true, false, type::TextureDimension::kNone},
+        DimCase{spv::Dim::Buffer, true, false, type::TextureDimension::kNone},
+        DimCase{spv::Dim::SubpassData, true, false, type::TextureDimension::kNone}));
 
 // TexelFormat
 
 struct TexelFormatCase {
     spv::ImageFormat format;
     bool expect_success;
-    ast::TexelFormat expected;
+    type::TexelFormat expected;
 };
 inline std::ostream& operator<<(std::ostream& out, TexelFormatCase ifc) {
     out << "TexelFormatCase{ spv::ImageFormat:::" << int(ifc.format)
@@ -329,52 +330,52 @@
     SpvImageFormatTest,
     testing::Values(
         // Unknown.  This is used for sampled images.
-        TexelFormatCase{spv::ImageFormat::Unknown, true, ast::TexelFormat::kUndefined},
+        TexelFormatCase{spv::ImageFormat::Unknown, true, type::TexelFormat::kUndefined},
         // 8 bit channels
-        TexelFormatCase{spv::ImageFormat::Rgba8, true, ast::TexelFormat::kRgba8Unorm},
-        TexelFormatCase{spv::ImageFormat::Rgba8Snorm, true, ast::TexelFormat::kRgba8Snorm},
-        TexelFormatCase{spv::ImageFormat::Rgba8ui, true, ast::TexelFormat::kRgba8Uint},
-        TexelFormatCase{spv::ImageFormat::Rgba8i, true, ast::TexelFormat::kRgba8Sint},
+        TexelFormatCase{spv::ImageFormat::Rgba8, true, type::TexelFormat::kRgba8Unorm},
+        TexelFormatCase{spv::ImageFormat::Rgba8Snorm, true, type::TexelFormat::kRgba8Snorm},
+        TexelFormatCase{spv::ImageFormat::Rgba8ui, true, type::TexelFormat::kRgba8Uint},
+        TexelFormatCase{spv::ImageFormat::Rgba8i, true, type::TexelFormat::kRgba8Sint},
         // 16 bit channels
-        TexelFormatCase{spv::ImageFormat::Rgba16ui, true, ast::TexelFormat::kRgba16Uint},
-        TexelFormatCase{spv::ImageFormat::Rgba16i, true, ast::TexelFormat::kRgba16Sint},
-        TexelFormatCase{spv::ImageFormat::Rgba16f, true, ast::TexelFormat::kRgba16Float},
+        TexelFormatCase{spv::ImageFormat::Rgba16ui, true, type::TexelFormat::kRgba16Uint},
+        TexelFormatCase{spv::ImageFormat::Rgba16i, true, type::TexelFormat::kRgba16Sint},
+        TexelFormatCase{spv::ImageFormat::Rgba16f, true, type::TexelFormat::kRgba16Float},
         // 32 bit channels
         // ... 1 channel
-        TexelFormatCase{spv::ImageFormat::R32ui, true, ast::TexelFormat::kR32Uint},
-        TexelFormatCase{spv::ImageFormat::R32i, true, ast::TexelFormat::kR32Sint},
-        TexelFormatCase{spv::ImageFormat::R32f, true, ast::TexelFormat::kR32Float},
+        TexelFormatCase{spv::ImageFormat::R32ui, true, type::TexelFormat::kR32Uint},
+        TexelFormatCase{spv::ImageFormat::R32i, true, type::TexelFormat::kR32Sint},
+        TexelFormatCase{spv::ImageFormat::R32f, true, type::TexelFormat::kR32Float},
         // ... 2 channels
-        TexelFormatCase{spv::ImageFormat::Rg32ui, true, ast::TexelFormat::kRg32Uint},
-        TexelFormatCase{spv::ImageFormat::Rg32i, true, ast::TexelFormat::kRg32Sint},
-        TexelFormatCase{spv::ImageFormat::Rg32f, true, ast::TexelFormat::kRg32Float},
+        TexelFormatCase{spv::ImageFormat::Rg32ui, true, type::TexelFormat::kRg32Uint},
+        TexelFormatCase{spv::ImageFormat::Rg32i, true, type::TexelFormat::kRg32Sint},
+        TexelFormatCase{spv::ImageFormat::Rg32f, true, type::TexelFormat::kRg32Float},
         // ... 4 channels
-        TexelFormatCase{spv::ImageFormat::Rgba32ui, true, ast::TexelFormat::kRgba32Uint},
-        TexelFormatCase{spv::ImageFormat::Rgba32i, true, ast::TexelFormat::kRgba32Sint},
-        TexelFormatCase{spv::ImageFormat::Rgba32f, true, ast::TexelFormat::kRgba32Float}));
+        TexelFormatCase{spv::ImageFormat::Rgba32ui, true, type::TexelFormat::kRgba32Uint},
+        TexelFormatCase{spv::ImageFormat::Rgba32i, true, type::TexelFormat::kRgba32Sint},
+        TexelFormatCase{spv::ImageFormat::Rgba32f, true, type::TexelFormat::kRgba32Float}));
 
 INSTANTIATE_TEST_SUITE_P(
     EnumConverterBad,
     SpvImageFormatTest,
     testing::Values(
         // Scanning in order from the SPIR-V spec.
-        TexelFormatCase{spv::ImageFormat::Rg16f, false, ast::TexelFormat::kUndefined},
-        TexelFormatCase{spv::ImageFormat::R11fG11fB10f, false, ast::TexelFormat::kUndefined},
-        TexelFormatCase{spv::ImageFormat::R16f, false, ast::TexelFormat::kUndefined},
-        TexelFormatCase{spv::ImageFormat::Rgb10A2, false, ast::TexelFormat::kUndefined},
-        TexelFormatCase{spv::ImageFormat::Rg16, false, ast::TexelFormat::kUndefined},
-        TexelFormatCase{spv::ImageFormat::Rg8, false, ast::TexelFormat::kUndefined},
-        TexelFormatCase{spv::ImageFormat::R16, false, ast::TexelFormat::kUndefined},
-        TexelFormatCase{spv::ImageFormat::R8, false, ast::TexelFormat::kUndefined},
-        TexelFormatCase{spv::ImageFormat::Rgba16Snorm, false, ast::TexelFormat::kUndefined},
-        TexelFormatCase{spv::ImageFormat::Rg16Snorm, false, ast::TexelFormat::kUndefined},
-        TexelFormatCase{spv::ImageFormat::Rg8Snorm, false, ast::TexelFormat::kUndefined},
-        TexelFormatCase{spv::ImageFormat::Rg16i, false, ast::TexelFormat::kUndefined},
-        TexelFormatCase{spv::ImageFormat::Rg8i, false, ast::TexelFormat::kUndefined},
-        TexelFormatCase{spv::ImageFormat::R8i, false, ast::TexelFormat::kUndefined},
-        TexelFormatCase{spv::ImageFormat::Rgb10a2ui, false, ast::TexelFormat::kUndefined},
-        TexelFormatCase{spv::ImageFormat::Rg16ui, false, ast::TexelFormat::kUndefined},
-        TexelFormatCase{spv::ImageFormat::Rg8ui, false, ast::TexelFormat::kUndefined}));
+        TexelFormatCase{spv::ImageFormat::Rg16f, false, type::TexelFormat::kUndefined},
+        TexelFormatCase{spv::ImageFormat::R11fG11fB10f, false, type::TexelFormat::kUndefined},
+        TexelFormatCase{spv::ImageFormat::R16f, false, type::TexelFormat::kUndefined},
+        TexelFormatCase{spv::ImageFormat::Rgb10A2, false, type::TexelFormat::kUndefined},
+        TexelFormatCase{spv::ImageFormat::Rg16, false, type::TexelFormat::kUndefined},
+        TexelFormatCase{spv::ImageFormat::Rg8, false, type::TexelFormat::kUndefined},
+        TexelFormatCase{spv::ImageFormat::R16, false, type::TexelFormat::kUndefined},
+        TexelFormatCase{spv::ImageFormat::R8, false, type::TexelFormat::kUndefined},
+        TexelFormatCase{spv::ImageFormat::Rgba16Snorm, false, type::TexelFormat::kUndefined},
+        TexelFormatCase{spv::ImageFormat::Rg16Snorm, false, type::TexelFormat::kUndefined},
+        TexelFormatCase{spv::ImageFormat::Rg8Snorm, false, type::TexelFormat::kUndefined},
+        TexelFormatCase{spv::ImageFormat::Rg16i, false, type::TexelFormat::kUndefined},
+        TexelFormatCase{spv::ImageFormat::Rg8i, false, type::TexelFormat::kUndefined},
+        TexelFormatCase{spv::ImageFormat::R8i, false, type::TexelFormat::kUndefined},
+        TexelFormatCase{spv::ImageFormat::Rgb10a2ui, false, type::TexelFormat::kUndefined},
+        TexelFormatCase{spv::ImageFormat::Rg16ui, false, type::TexelFormat::kUndefined},
+        TexelFormatCase{spv::ImageFormat::Rg8ui, false, type::TexelFormat::kUndefined}));
 
 }  // namespace
 }  // namespace tint::reader::spirv
diff --git a/src/tint/reader/spirv/function.cc b/src/tint/reader/spirv/function.cc
index a0b257b..9ea9866 100644
--- a/src/tint/reader/spirv/function.cc
+++ b/src/tint/reader/spirv/function.cc
@@ -36,6 +36,7 @@
 #include "src/tint/transform/spirv_atomic.h"
 #include "src/tint/type/depth_texture.h"
 #include "src/tint/type/sampled_texture.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/utils/hashmap.h"
 #include "src/tint/utils/hashset.h"
 
@@ -2535,11 +2536,11 @@
                 return false;
             }
         }
-        auto* var = parser_impl_.MakeVar(inst.result_id(), ast::AddressSpace::kNone, var_store_type,
-                                         initializer, AttributeList{});
+        auto* var = parser_impl_.MakeVar(inst.result_id(), type::AddressSpace::kNone,
+                                         var_store_type, initializer, AttributeList{});
         auto* var_decl_stmt = create<ast::VariableDeclStatement>(Source{}, var);
         AddStatement(var_decl_stmt);
-        auto* var_type = ty_.Reference(var_store_type, ast::AddressSpace::kNone);
+        auto* var_type = ty_.Reference(var_store_type, type::AddressSpace::kNone);
         identifier_types_.emplace(inst.result_id(), var_type);
     }
     return success();
@@ -3389,9 +3390,9 @@
         // no need to remap pointer properties.
         auto* store_type = parser_impl_.ConvertType(def_inst->type_id());
         AddStatement(create<ast::VariableDeclStatement>(
-            Source{}, parser_impl_.MakeVar(id, ast::AddressSpace::kNone, store_type, nullptr,
+            Source{}, parser_impl_.MakeVar(id, type::AddressSpace::kNone, store_type, nullptr,
                                            AttributeList{})));
-        auto* type = ty_.Reference(store_type, ast::AddressSpace::kNone);
+        auto* type = ty_.Reference(store_type, type::AddressSpace::kNone);
         identifier_types_.emplace(id, type);
     }
 
@@ -4881,7 +4882,7 @@
                 }
                 // Local variables are always Function storage class, with default
                 // access mode.
-                return DefInfo::Pointer{ast::AddressSpace::kFunction, ast::Access::kUndefined};
+                return DefInfo::Pointer{type::AddressSpace::kFunction, type::Access::kUndefined};
             }
             case spv::Op::OpFunctionParameter: {
                 const auto* type = As<Pointer>(parser_impl_.ConvertType(inst.type_id()));
@@ -4894,7 +4895,7 @@
                 // parameters.  In that case we need to do a global analysis to
                 // determine what the formal argument parameter type should be,
                 // whether it has read_only or read_write access mode.
-                return DefInfo::Pointer{type->address_space, ast::Access::kUndefined};
+                return DefInfo::Pointer{type->address_space, type::Access::kUndefined};
             }
             default:
                 break;
@@ -5116,7 +5117,7 @@
             // Avoid moving combinatorial values across constructs.  This is a
             // simple heuristic to avoid changing the cost of an operation
             // by moving it into or out of a loop, for example.
-            if ((def_info->pointer.address_space == ast::AddressSpace::kUndefined) &&
+            if ((def_info->pointer.address_space == type::AddressSpace::kUndefined) &&
                 local_def.used_in_another_construct) {
                 should_hoist_to_let = true;
             }
@@ -5619,9 +5620,9 @@
                           << inst.PrettyPrint();
         }
         switch (texture_type->dims) {
-            case ast::TextureDimension::k2d:
-            case ast::TextureDimension::k2dArray:
-            case ast::TextureDimension::k3d:
+            case type::TextureDimension::k2d:
+            case type::TextureDimension::k2dArray:
+            case type::TextureDimension::k3d:
                 break;
             default:
                 return Fail() << "ConstOffset is only permitted for 2D, 2D Arrayed, "
@@ -5749,8 +5750,8 @@
             const ast::Expression* dims_call =
                 create<ast::CallExpression>(Source{}, dims_ident, dims_args);
             auto dims = texture_type->dims;
-            if ((dims == ast::TextureDimension::kCube) ||
-                (dims == ast::TextureDimension::kCubeArray)) {
+            if ((dims == type::TextureDimension::kCube) ||
+                (dims == type::TextureDimension::kCubeArray)) {
                 // textureDimension returns a 3-element vector but SPIR-V expects 2.
                 dims_call =
                     create<ast::MemberAccessorExpression>(Source{}, dims_call, PrefixSwizzle(2));
@@ -5952,7 +5953,7 @@
     if (!texture_type) {
         return {};
     }
-    ast::TextureDimension dim = texture_type->dims;
+    type::TextureDimension dim = texture_type->dims;
     // Number of regular coordinates.
     uint32_t num_axes = static_cast<uint32_t>(ast::NumCoordinateAxes(dim));
     bool is_arrayed = ast::IsTextureArray(dim);
@@ -6253,7 +6254,7 @@
         // API in parser_impl_.
         var_name = namer_.MakeDerivedName(original_value_name);
 
-        auto* temp_var = builder_.Var(var_name, type->Build(builder_), ast::AddressSpace::kNone,
+        auto* temp_var = builder_.Var(var_name, type->Build(builder_), type::AddressSpace::kNone,
                                       src_vector.expr);
 
         AddStatement(builder_.Decl({}, temp_var));
@@ -6323,7 +6324,7 @@
         // It doesn't correspond to a SPIR-V ID, so we don't use the ordinary
         // API in parser_impl_.
         var_name = namer_.MakeDerivedName(original_value_name);
-        auto* temp_var = builder_.Var(var_name, type->Build(builder_), ast::AddressSpace::kNone,
+        auto* temp_var = builder_.Var(var_name, type->Build(builder_), type::AddressSpace::kNone,
                                       src_composite.expr);
         AddStatement(builder_.Decl({}, temp_var));
     }
diff --git a/src/tint/reader/spirv/function.h b/src/tint/reader/spirv/function.h
index 65a1e3b..53afcdc 100644
--- a/src/tint/reader/spirv/function.h
+++ b/src/tint/reader/spirv/function.h
@@ -331,10 +331,10 @@
         /// buffer expressed in the old style (with Uniform address space)
         /// that needs to be remapped to StorageBuffer address space.
         /// This is kInvalid for non-pointers.
-        ast::AddressSpace address_space = ast::AddressSpace::kUndefined;
+        type::AddressSpace address_space = type::AddressSpace::kUndefined;
 
         /// The declared access mode.
-        ast::Access access = ast::Access::kUndefined;
+        type::Access access = type::Access::kUndefined;
     };
 
     /// The expression to use when sinking pointers into their use.
@@ -368,7 +368,7 @@
     }
     o << " requires_named_let_def: " << (di.requires_named_let_def ? "true" : "false")
       << " requires_hoisted_var_def: " << (di.requires_hoisted_var_def ? "true" : "false");
-    if (di.pointer.address_space != ast::AddressSpace::kNone) {
+    if (di.pointer.address_space != type::AddressSpace::kNone) {
         o << " sc:" << int(di.pointer.address_space);
     }
     switch (di.skip) {
diff --git a/src/tint/reader/spirv/parser_impl.cc b/src/tint/reader/spirv/parser_impl.cc
index 4fa4b2f..8d749a2 100644
--- a/src/tint/reader/spirv/parser_impl.cc
+++ b/src/tint/reader/spirv/parser_impl.cc
@@ -30,6 +30,7 @@
 #include "src/tint/type/depth_texture.h"
 #include "src/tint/type/multisampled_texture.h"
 #include "src/tint/type/sampled_texture.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/utils/unique_vector.h"
 
 namespace tint::reader::spirv {
@@ -1221,21 +1222,21 @@
     }
 
     auto ast_address_space = enum_converter_.ToAddressSpace(storage_class);
-    if (ast_address_space == ast::AddressSpace::kUndefined) {
+    if (ast_address_space == type::AddressSpace::kUndefined) {
         Fail() << "SPIR-V pointer type with ID " << type_id << " has invalid storage class "
                << static_cast<uint32_t>(storage_class);
         return nullptr;
     }
-    if (ast_address_space == ast::AddressSpace::kUniform &&
+    if (ast_address_space == type::AddressSpace::kUniform &&
         remap_buffer_block_type_.count(pointee_type_id)) {
-        ast_address_space = ast::AddressSpace::kStorage;
+        ast_address_space = type::AddressSpace::kStorage;
         remap_buffer_block_type_.insert(type_id);
     }
 
     // Pipeline input and output variables map to private variables.
-    if (ast_address_space == ast::AddressSpace::kIn ||
-        ast_address_space == ast::AddressSpace::kOut) {
-        ast_address_space = ast::AddressSpace::kPrivate;
+    if (ast_address_space == type::AddressSpace::kIn ||
+        ast_address_space == type::AddressSpace::kOut) {
+        ast_address_space = type::AddressSpace::kPrivate;
     }
     switch (ptr_as) {
         case PtrAs::Ref:
@@ -1459,14 +1460,14 @@
             continue;
         }
         switch (enum_converter_.ToAddressSpace(spirv_storage_class)) {
-            case ast::AddressSpace::kNone:
-            case ast::AddressSpace::kIn:
-            case ast::AddressSpace::kOut:
-            case ast::AddressSpace::kUniform:
-            case ast::AddressSpace::kHandle:
-            case ast::AddressSpace::kStorage:
-            case ast::AddressSpace::kWorkgroup:
-            case ast::AddressSpace::kPrivate:
+            case type::AddressSpace::kNone:
+            case type::AddressSpace::kIn:
+            case type::AddressSpace::kOut:
+            case type::AddressSpace::kUniform:
+            case type::AddressSpace::kHandle:
+            case type::AddressSpace::kStorage:
+            case type::AddressSpace::kWorkgroup:
+            case type::AddressSpace::kPrivate:
                 break;
             default:
                 return Fail() << "invalid SPIR-V storage class " << int(spirv_storage_class)
@@ -1476,7 +1477,7 @@
             return false;
         }
         const Type* ast_store_type = nullptr;
-        ast::AddressSpace ast_address_space = ast::AddressSpace::kNone;
+        type::AddressSpace ast_address_space = type::AddressSpace::kNone;
         if (spirv_storage_class == spv::StorageClass::UniformConstant) {
             // These are opaque handles: samplers or textures
             ast_store_type = GetHandleTypeForSpirvHandle(var);
@@ -1577,7 +1578,7 @@
 }
 
 ast::Var* ParserImpl::MakeVar(uint32_t id,
-                              ast::AddressSpace address_space,
+                              type::AddressSpace address_space,
                               const Type* storage_type,
                               const ast::Expression* initializer,
                               AttributeList decorations) {
@@ -1586,25 +1587,25 @@
         return nullptr;
     }
 
-    ast::Access access = ast::Access::kUndefined;
-    if (address_space == ast::AddressSpace::kStorage) {
+    type::Access access = type::Access::kUndefined;
+    if (address_space == type::AddressSpace::kStorage) {
         bool read_only = false;
         if (auto* tn = storage_type->As<Named>()) {
             read_only = read_only_struct_types_.count(tn->name) > 0;
         }
 
         // Apply the access(read) or access(read_write) modifier.
-        access = read_only ? ast::Access::kRead : ast::Access::kReadWrite;
+        access = read_only ? type::Access::kRead : type::Access::kReadWrite;
     }
 
     // Handle variables (textures and samplers) are always in the handle
     // address space, so we don't mention the address space.
-    if (address_space == ast::AddressSpace::kHandle) {
-        address_space = ast::AddressSpace::kNone;
+    if (address_space == type::AddressSpace::kHandle) {
+        address_space = type::AddressSpace::kNone;
     }
 
     if (!ConvertDecorationsForVariable(id, &storage_type, &decorations,
-                                       address_space != ast::AddressSpace::kPrivate)) {
+                                       address_space != type::AddressSpace::kPrivate)) {
         return nullptr;
     }
 
@@ -2481,9 +2482,9 @@
             }
         }
 
-        const ast::TextureDimension dim =
+        const type::TextureDimension dim =
             enum_converter_.ToDim(image_type->dim(), image_type->is_arrayed());
-        if (dim == ast::TextureDimension::kNone) {
+        if (dim == type::TextureDimension::kNone) {
             return nullptr;
         }
 
@@ -2506,7 +2507,7 @@
                     ast_handle_type = ty_.DepthTexture(dim);
                 }
             } else if (image_type->is_multisampled()) {
-                if (dim != ast::TextureDimension::k2d) {
+                if (dim != type::TextureDimension::k2d) {
                     Fail() << "WGSL multisampled textures must be 2d and non-arrayed: "
                               "invalid multisampled texture variable or function parameter "
                            << namer_.Name(obj.result_id()) << ": " << obj.PrettyPrint();
@@ -2517,9 +2518,9 @@
                 ast_handle_type = ty_.SampledTexture(dim, ast_sampled_component_type);
             }
         } else {
-            const auto access = ast::Access::kWrite;
+            const auto access = type::Access::kWrite;
             const auto format = enum_converter_.ToTexelFormat(image_type->format());
-            if (format == ast::TexelFormat::kUndefined) {
+            if (format == type::TexelFormat::kUndefined) {
                 return nullptr;
             }
             ast_handle_type = ty_.StorageTexture(dim, format, access);
@@ -2536,28 +2537,28 @@
     return ast_handle_type;
 }
 
-const Type* ParserImpl::GetComponentTypeForFormat(ast::TexelFormat format) {
+const Type* ParserImpl::GetComponentTypeForFormat(type::TexelFormat format) {
     switch (format) {
-        case ast::TexelFormat::kR32Uint:
-        case ast::TexelFormat::kRgba8Uint:
-        case ast::TexelFormat::kRg32Uint:
-        case ast::TexelFormat::kRgba16Uint:
-        case ast::TexelFormat::kRgba32Uint:
+        case type::TexelFormat::kR32Uint:
+        case type::TexelFormat::kRgba8Uint:
+        case type::TexelFormat::kRg32Uint:
+        case type::TexelFormat::kRgba16Uint:
+        case type::TexelFormat::kRgba32Uint:
             return ty_.U32();
 
-        case ast::TexelFormat::kR32Sint:
-        case ast::TexelFormat::kRgba8Sint:
-        case ast::TexelFormat::kRg32Sint:
-        case ast::TexelFormat::kRgba16Sint:
-        case ast::TexelFormat::kRgba32Sint:
+        case type::TexelFormat::kR32Sint:
+        case type::TexelFormat::kRgba8Sint:
+        case type::TexelFormat::kRg32Sint:
+        case type::TexelFormat::kRgba16Sint:
+        case type::TexelFormat::kRgba32Sint:
             return ty_.I32();
 
-        case ast::TexelFormat::kRgba8Unorm:
-        case ast::TexelFormat::kRgba8Snorm:
-        case ast::TexelFormat::kR32Float:
-        case ast::TexelFormat::kRg32Float:
-        case ast::TexelFormat::kRgba16Float:
-        case ast::TexelFormat::kRgba32Float:
+        case type::TexelFormat::kRgba8Unorm:
+        case type::TexelFormat::kRgba8Snorm:
+        case type::TexelFormat::kR32Float:
+        case type::TexelFormat::kRg32Float:
+        case type::TexelFormat::kRgba16Float:
+        case type::TexelFormat::kRgba32Float:
             return ty_.F32();
         default:
             break;
@@ -2566,30 +2567,30 @@
     return nullptr;
 }
 
-unsigned ParserImpl::GetChannelCountForFormat(ast::TexelFormat format) {
+unsigned ParserImpl::GetChannelCountForFormat(type::TexelFormat format) {
     switch (format) {
-        case ast::TexelFormat::kR32Float:
-        case ast::TexelFormat::kR32Sint:
-        case ast::TexelFormat::kR32Uint:
+        case type::TexelFormat::kR32Float:
+        case type::TexelFormat::kR32Sint:
+        case type::TexelFormat::kR32Uint:
             // One channel
             return 1;
 
-        case ast::TexelFormat::kRg32Float:
-        case ast::TexelFormat::kRg32Sint:
-        case ast::TexelFormat::kRg32Uint:
+        case type::TexelFormat::kRg32Float:
+        case type::TexelFormat::kRg32Sint:
+        case type::TexelFormat::kRg32Uint:
             // Two channels
             return 2;
 
-        case ast::TexelFormat::kRgba16Float:
-        case ast::TexelFormat::kRgba16Sint:
-        case ast::TexelFormat::kRgba16Uint:
-        case ast::TexelFormat::kRgba32Float:
-        case ast::TexelFormat::kRgba32Sint:
-        case ast::TexelFormat::kRgba32Uint:
-        case ast::TexelFormat::kRgba8Sint:
-        case ast::TexelFormat::kRgba8Snorm:
-        case ast::TexelFormat::kRgba8Uint:
-        case ast::TexelFormat::kRgba8Unorm:
+        case type::TexelFormat::kRgba16Float:
+        case type::TexelFormat::kRgba16Sint:
+        case type::TexelFormat::kRgba16Uint:
+        case type::TexelFormat::kRgba32Float:
+        case type::TexelFormat::kRgba32Sint:
+        case type::TexelFormat::kRgba32Uint:
+        case type::TexelFormat::kRgba8Sint:
+        case type::TexelFormat::kRgba8Snorm:
+        case type::TexelFormat::kRgba8Uint:
+        case type::TexelFormat::kRgba8Unorm:
             // Four channels
             return 4;
 
@@ -2600,7 +2601,7 @@
     return 0;
 }
 
-const Type* ParserImpl::GetTexelTypeForFormat(ast::TexelFormat format) {
+const Type* ParserImpl::GetTexelTypeForFormat(type::TexelFormat format) {
     const auto* component_type = GetComponentTypeForFormat(format);
     if (!component_type) {
         return nullptr;
diff --git a/src/tint/reader/spirv/parser_impl.h b/src/tint/reader/spirv/parser_impl.h
index 7713734..55e2250 100644
--- a/src/tint/reader/spirv/parser_impl.h
+++ b/src/tint/reader/spirv/parser_impl.h
@@ -423,14 +423,14 @@
     /// Creates an AST 'var' node for a SPIR-V ID, including any attached decorations, unless it's
     /// an ignorable builtin variable.
     /// @param id the SPIR-V result ID
-    /// @param address_space the address space, which cannot be ast::AddressSpace::kNone
+    /// @param address_space the address space, which cannot be type::AddressSpace::kNone
     /// @param storage_type the storage type of the variable
     /// @param initializer the variable initializer
     /// @param decorations the variable decorations
     /// @returns a new Variable node, or null in the ignorable variable case and
     /// in the error case
     ast::Var* MakeVar(uint32_t id,
-                      ast::AddressSpace address_space,
+                      type::AddressSpace address_space,
                       const Type* storage_type,
                       const ast::Expression* initializer,
                       AttributeList decorations);
@@ -672,19 +672,19 @@
     /// format.
     /// @param format image texel format
     /// @returns the component type, one of f32, i32, u32
-    const Type* GetComponentTypeForFormat(ast::TexelFormat format);
+    const Type* GetComponentTypeForFormat(type::TexelFormat format);
 
     /// Returns the number of channels in the given image format.
     /// @param format image texel format
     /// @returns the number of channels in the format
-    unsigned GetChannelCountForFormat(ast::TexelFormat format);
+    unsigned GetChannelCountForFormat(type::TexelFormat format);
 
     /// Returns the texel type corresponding to the given image format.
     /// This the WGSL type used for the texel parameter to textureStore.
     /// It's always a 4-element vector.
     /// @param format image texel format
     /// @returns the texel format
-    const Type* GetTexelTypeForFormat(ast::TexelFormat format);
+    const Type* GetTexelTypeForFormat(type::TexelFormat format);
 
     /// Returns the SPIR-V instruction with the given ID, or nullptr.
     /// @param id the SPIR-V result ID
diff --git a/src/tint/reader/spirv/parser_impl_convert_type_test.cc b/src/tint/reader/spirv/parser_impl_convert_type_test.cc
index 3b8fa62..a471632 100644
--- a/src/tint/reader/spirv/parser_impl_convert_type_test.cc
+++ b/src/tint/reader/spirv/parser_impl_convert_type_test.cc
@@ -731,7 +731,7 @@
     auto* ptr_ty = type->As<Pointer>();
     EXPECT_NE(ptr_ty, nullptr);
     EXPECT_TRUE(ptr_ty->type->Is<F32>());
-    EXPECT_EQ(ptr_ty->address_space, ast::AddressSpace::kPrivate);
+    EXPECT_EQ(ptr_ty->address_space, type::AddressSpace::kPrivate);
     EXPECT_TRUE(p->error().empty());
 }
 
@@ -747,7 +747,7 @@
     auto* ptr_ty = type->As<Pointer>();
     EXPECT_NE(ptr_ty, nullptr);
     EXPECT_TRUE(ptr_ty->type->Is<F32>());
-    EXPECT_EQ(ptr_ty->address_space, ast::AddressSpace::kPrivate);
+    EXPECT_EQ(ptr_ty->address_space, type::AddressSpace::kPrivate);
     EXPECT_TRUE(p->error().empty());
 }
 
@@ -763,7 +763,7 @@
     auto* ptr_ty = type->As<Pointer>();
     EXPECT_NE(ptr_ty, nullptr);
     EXPECT_TRUE(ptr_ty->type->Is<F32>());
-    EXPECT_EQ(ptr_ty->address_space, ast::AddressSpace::kUniform);
+    EXPECT_EQ(ptr_ty->address_space, type::AddressSpace::kUniform);
     EXPECT_TRUE(p->error().empty());
 }
 
@@ -779,7 +779,7 @@
     auto* ptr_ty = type->As<Pointer>();
     EXPECT_NE(ptr_ty, nullptr);
     EXPECT_TRUE(ptr_ty->type->Is<F32>());
-    EXPECT_EQ(ptr_ty->address_space, ast::AddressSpace::kWorkgroup);
+    EXPECT_EQ(ptr_ty->address_space, type::AddressSpace::kWorkgroup);
     EXPECT_TRUE(p->error().empty());
 }
 
@@ -795,7 +795,7 @@
     auto* ptr_ty = type->As<Pointer>();
     EXPECT_NE(ptr_ty, nullptr);
     EXPECT_TRUE(ptr_ty->type->Is<F32>());
-    EXPECT_EQ(ptr_ty->address_space, ast::AddressSpace::kNone);
+    EXPECT_EQ(ptr_ty->address_space, type::AddressSpace::kNone);
     EXPECT_TRUE(p->error().empty());
 }
 
@@ -811,7 +811,7 @@
     auto* ptr_ty = type->As<Pointer>();
     EXPECT_NE(ptr_ty, nullptr);
     EXPECT_TRUE(ptr_ty->type->Is<F32>());
-    EXPECT_EQ(ptr_ty->address_space, ast::AddressSpace::kStorage);
+    EXPECT_EQ(ptr_ty->address_space, type::AddressSpace::kStorage);
     EXPECT_TRUE(p->error().empty());
 }
 
@@ -827,7 +827,7 @@
     auto* ptr_ty = type->As<Pointer>();
     EXPECT_NE(ptr_ty, nullptr);
     EXPECT_TRUE(ptr_ty->type->Is<F32>());
-    EXPECT_EQ(ptr_ty->address_space, ast::AddressSpace::kPrivate);
+    EXPECT_EQ(ptr_ty->address_space, type::AddressSpace::kPrivate);
     EXPECT_TRUE(p->error().empty());
 }
 
@@ -843,7 +843,7 @@
     auto* ptr_ty = type->As<Pointer>();
     EXPECT_NE(ptr_ty, nullptr);
     EXPECT_TRUE(ptr_ty->type->Is<F32>());
-    EXPECT_EQ(ptr_ty->address_space, ast::AddressSpace::kFunction);
+    EXPECT_EQ(ptr_ty->address_space, type::AddressSpace::kFunction);
     EXPECT_TRUE(p->error().empty());
 }
 
@@ -862,12 +862,12 @@
 
     auto* ptr_ty = type->As<Pointer>();
     EXPECT_NE(ptr_ty, nullptr);
-    EXPECT_EQ(ptr_ty->address_space, ast::AddressSpace::kPrivate);
+    EXPECT_EQ(ptr_ty->address_space, type::AddressSpace::kPrivate);
     EXPECT_TRUE(ptr_ty->type->Is<Pointer>());
 
     auto* ptr_ptr_ty = ptr_ty->type->As<Pointer>();
     EXPECT_NE(ptr_ptr_ty, nullptr);
-    EXPECT_EQ(ptr_ptr_ty->address_space, ast::AddressSpace::kPrivate);
+    EXPECT_EQ(ptr_ptr_ty->address_space, type::AddressSpace::kPrivate);
     EXPECT_TRUE(ptr_ptr_ty->type->Is<F32>());
 
     EXPECT_TRUE(p->error().empty());
diff --git a/src/tint/reader/spirv/parser_type.cc b/src/tint/reader/spirv/parser_type.cc
index 04036f2..5751866 100644
--- a/src/tint/reader/spirv/parser_type.cc
+++ b/src/tint/reader/spirv/parser_type.cc
@@ -19,6 +19,7 @@
 #include <utility>
 
 #include "src/tint/program_builder.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/utils/hash.h"
 #include "src/tint/utils/map.h"
 #include "src/tint/utils/string.h"
@@ -174,7 +175,7 @@
 
 Texture::~Texture() = default;
 
-Pointer::Pointer(const Type* t, ast::AddressSpace s, ast::Access a)
+Pointer::Pointer(const Type* t, type::AddressSpace s, type::Access a)
     : type(t), address_space(s), access(a) {}
 Pointer::Pointer(const Pointer&) = default;
 
@@ -182,7 +183,7 @@
     return b.ty.pointer(type->Build(b), address_space, access);
 }
 
-Reference::Reference(const Type* t, ast::AddressSpace s, ast::Access a)
+Reference::Reference(const Type* t, type::AddressSpace s, type::Access a)
     : type(t), address_space(s), access(a) {}
 Reference::Reference(const Reference&) = default;
 
@@ -222,24 +223,24 @@
     return b.ty.sampler(kind);
 }
 
-Texture::Texture(ast::TextureDimension d) : dims(d) {}
+Texture::Texture(type::TextureDimension d) : dims(d) {}
 Texture::Texture(const Texture&) = default;
 
-DepthTexture::DepthTexture(ast::TextureDimension d) : Base(d) {}
+DepthTexture::DepthTexture(type::TextureDimension d) : Base(d) {}
 DepthTexture::DepthTexture(const DepthTexture&) = default;
 
 const ast::Type* DepthTexture::Build(ProgramBuilder& b) const {
     return b.ty.depth_texture(dims);
 }
 
-DepthMultisampledTexture::DepthMultisampledTexture(ast::TextureDimension d) : Base(d) {}
+DepthMultisampledTexture::DepthMultisampledTexture(type::TextureDimension d) : Base(d) {}
 DepthMultisampledTexture::DepthMultisampledTexture(const DepthMultisampledTexture&) = default;
 
 const ast::Type* DepthMultisampledTexture::Build(ProgramBuilder& b) const {
     return b.ty.depth_multisampled_texture(dims);
 }
 
-MultisampledTexture::MultisampledTexture(ast::TextureDimension d, const Type* t)
+MultisampledTexture::MultisampledTexture(type::TextureDimension d, const Type* t)
     : Base(d), type(t) {}
 MultisampledTexture::MultisampledTexture(const MultisampledTexture&) = default;
 
@@ -247,14 +248,14 @@
     return b.ty.multisampled_texture(dims, type->Build(b));
 }
 
-SampledTexture::SampledTexture(ast::TextureDimension d, const Type* t) : Base(d), type(t) {}
+SampledTexture::SampledTexture(type::TextureDimension d, const Type* t) : Base(d), type(t) {}
 SampledTexture::SampledTexture(const SampledTexture&) = default;
 
 const ast::Type* SampledTexture::Build(ProgramBuilder& b) const {
     return b.ty.sampled_texture(dims, type->Build(b));
 }
 
-StorageTexture::StorageTexture(ast::TextureDimension d, ast::TexelFormat f, ast::Access a)
+StorageTexture::StorageTexture(type::TextureDimension d, type::TexelFormat f, type::Access a)
     : Base(d), format(f), access(a) {}
 StorageTexture::StorageTexture(const StorageTexture&) = default;
 
@@ -459,14 +460,14 @@
 }
 
 const spirv::Pointer* TypeManager::Pointer(const Type* el,
-                                           ast::AddressSpace address_space,
-                                           ast::Access access) {
+                                           type::AddressSpace address_space,
+                                           type::Access access) {
     return state->pointers_.Get(el, address_space, access);
 }
 
 const spirv::Reference* TypeManager::Reference(const Type* el,
-                                               ast::AddressSpace address_space,
-                                               ast::Access access) {
+                                               type::AddressSpace address_space,
+                                               type::Access access) {
     return state->references_.Get(el, address_space, access);
 }
 
@@ -494,28 +495,28 @@
     return state->samplers_.Get(kind);
 }
 
-const spirv::DepthTexture* TypeManager::DepthTexture(ast::TextureDimension dims) {
+const spirv::DepthTexture* TypeManager::DepthTexture(type::TextureDimension dims) {
     return state->depth_textures_.Get(dims);
 }
 
 const spirv::DepthMultisampledTexture* TypeManager::DepthMultisampledTexture(
-    ast::TextureDimension dims) {
+    type::TextureDimension dims) {
     return state->depth_multisampled_textures_.Get(dims);
 }
 
-const spirv::MultisampledTexture* TypeManager::MultisampledTexture(ast::TextureDimension dims,
+const spirv::MultisampledTexture* TypeManager::MultisampledTexture(type::TextureDimension dims,
                                                                    const Type* ty) {
     return state->multisampled_textures_.Get(dims, ty);
 }
 
-const spirv::SampledTexture* TypeManager::SampledTexture(ast::TextureDimension dims,
+const spirv::SampledTexture* TypeManager::SampledTexture(type::TextureDimension dims,
                                                          const Type* ty) {
     return state->sampled_textures_.Get(dims, ty);
 }
 
-const spirv::StorageTexture* TypeManager::StorageTexture(ast::TextureDimension dims,
-                                                         ast::TexelFormat fmt,
-                                                         ast::Access access) {
+const spirv::StorageTexture* TypeManager::StorageTexture(type::TextureDimension dims,
+                                                         type::TexelFormat fmt,
+                                                         type::Access access) {
     return state->storage_textures_.Get(dims, fmt, access);
 }
 
diff --git a/src/tint/reader/spirv/parser_type.h b/src/tint/reader/spirv/parser_type.h
index 43c311c..0cdafeb 100644
--- a/src/tint/reader/spirv/parser_type.h
+++ b/src/tint/reader/spirv/parser_type.h
@@ -19,12 +19,12 @@
 #include <string>
 #include <vector>
 
-#include "src/tint/ast/access.h"
-#include "src/tint/ast/address_space.h"
 #include "src/tint/ast/sampler.h"
 #include "src/tint/ast/storage_texture.h"
-#include "src/tint/ast/texture.h"
 #include "src/tint/castable.h"
+#include "src/tint/type/access.h"
+#include "src/tint/type/address_space.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/utils/block_allocator.h"
 
 // Forward declarations
@@ -163,7 +163,7 @@
     /// @param ty the store type
     /// @param sc the pointer address space
     /// @param access the declared access mode
-    Pointer(const Type* ty, ast::AddressSpace sc, ast::Access access);
+    Pointer(const Type* ty, type::AddressSpace sc, type::Access access);
 
     /// Copy constructor
     /// @param other the other type to copy
@@ -181,9 +181,9 @@
     /// the store type
     Type const* const type;
     /// the pointer address space
-    ast::AddressSpace const address_space;
+    type::AddressSpace const address_space;
     /// the pointer declared access mode
-    ast::Access const access;
+    type::Access const access;
 };
 
 /// `ref<SC, T, AM>` type
@@ -194,7 +194,7 @@
     /// @param ty the referenced type
     /// @param sc the reference address space
     /// @param access the reference declared access mode
-    Reference(const Type* ty, ast::AddressSpace sc, ast::Access access);
+    Reference(const Type* ty, type::AddressSpace sc, type::Access access);
 
     /// Copy constructor
     /// @param other the other type to copy
@@ -212,9 +212,9 @@
     /// the store type
     Type const* const type;
     /// the pointer address space
-    ast::AddressSpace const address_space;
+    type::AddressSpace const address_space;
     /// the pointer declared access mode
-    ast::Access const access;
+    type::Access const access;
 };
 
 /// `vecN<T>` type
@@ -331,21 +331,21 @@
 
     /// Constructor
     /// @param d the texture dimensions
-    explicit Texture(ast::TextureDimension d);
+    explicit Texture(type::TextureDimension d);
 
     /// Copy constructor
     /// @param other the other type to copy
     Texture(const Texture& other);
 
     /// the texture dimensions
-    ast::TextureDimension const dims;
+    type::TextureDimension const dims;
 };
 
 /// `texture_depth_D` type
 struct DepthTexture final : public Castable<DepthTexture, Texture> {
     /// Constructor
     /// @param d the texture dimensions
-    explicit DepthTexture(ast::TextureDimension d);
+    explicit DepthTexture(type::TextureDimension d);
 
     /// Copy constructor
     /// @param other the other type to copy
@@ -365,7 +365,7 @@
 struct DepthMultisampledTexture final : public Castable<DepthMultisampledTexture, Texture> {
     /// Constructor
     /// @param d the texture dimensions
-    explicit DepthMultisampledTexture(ast::TextureDimension d);
+    explicit DepthMultisampledTexture(type::TextureDimension d);
 
     /// Copy constructor
     /// @param other the other type to copy
@@ -386,7 +386,7 @@
     /// Constructor
     /// @param d the texture dimensions
     /// @param t the multisampled texture type
-    MultisampledTexture(ast::TextureDimension d, const Type* t);
+    MultisampledTexture(type::TextureDimension d, const Type* t);
 
     /// Copy constructor
     /// @param other the other type to copy
@@ -410,7 +410,7 @@
     /// Constructor
     /// @param d the texture dimensions
     /// @param t the sampled texture type
-    SampledTexture(ast::TextureDimension d, const Type* t);
+    SampledTexture(type::TextureDimension d, const Type* t);
 
     /// Copy constructor
     /// @param other the other type to copy
@@ -435,7 +435,7 @@
     /// @param d the texture dimensions
     /// @param f the storage image format
     /// @param a the access control
-    StorageTexture(ast::TextureDimension d, ast::TexelFormat f, ast::Access a);
+    StorageTexture(type::TextureDimension d, type::TexelFormat f, type::Access a);
 
     /// Copy constructor
     /// @param other the other type to copy
@@ -451,10 +451,10 @@
 #endif  // NDEBUG
 
     /// the storage image format
-    ast::TexelFormat const format;
+    type::TexelFormat const format;
 
     /// the access control
-    ast::Access const access;
+    type::Access const access;
 };
 
 /// Base class for named types
@@ -550,16 +550,16 @@
     /// @return a Pointer type. Repeated calls with the same arguments will return
     /// the same pointer.
     const spirv::Pointer* Pointer(const Type* ty,
-                                  ast::AddressSpace address_space,
-                                  ast::Access access = ast::Access::kUndefined);
+                                  type::AddressSpace address_space,
+                                  type::Access access = type::Access::kUndefined);
     /// @param ty the referenced type
     /// @param address_space the reference address space
     /// @param access the declared access mode
     /// @return a Reference type. Repeated calls with the same arguments will
     /// return the same pointer.
     const spirv::Reference* Reference(const Type* ty,
-                                      ast::AddressSpace address_space,
-                                      ast::Access access = ast::Access::kUndefined);
+                                      type::AddressSpace address_space,
+                                      type::Access access = type::Access::kUndefined);
     /// @param ty the element type
     /// @param sz the number of elements in the vector
     /// @return a Vector type. Repeated calls with the same arguments will return
@@ -595,29 +595,29 @@
     /// @param d the texture dimensions
     /// @return a DepthTexture type. Repeated calls with the same arguments will
     /// return the same pointer.
-    const spirv::DepthTexture* DepthTexture(ast::TextureDimension d);
+    const spirv::DepthTexture* DepthTexture(type::TextureDimension d);
     /// @param d the texture dimensions
     /// @return a DepthMultisampledTexture type. Repeated calls with the same
     /// arguments will return the same pointer.
-    const spirv::DepthMultisampledTexture* DepthMultisampledTexture(ast::TextureDimension d);
+    const spirv::DepthMultisampledTexture* DepthMultisampledTexture(type::TextureDimension d);
     /// @param d the texture dimensions
     /// @param t the multisampled texture type
     /// @return a MultisampledTexture type. Repeated calls with the same arguments
     /// will return the same pointer.
-    const spirv::MultisampledTexture* MultisampledTexture(ast::TextureDimension d, const Type* t);
+    const spirv::MultisampledTexture* MultisampledTexture(type::TextureDimension d, const Type* t);
     /// @param d the texture dimensions
     /// @param t the sampled texture type
     /// @return a SampledTexture type. Repeated calls with the same arguments will
     /// return the same pointer.
-    const spirv::SampledTexture* SampledTexture(ast::TextureDimension d, const Type* t);
+    const spirv::SampledTexture* SampledTexture(type::TextureDimension d, const Type* t);
     /// @param d the texture dimensions
     /// @param f the storage image format
     /// @param a the access control
     /// @return a StorageTexture type. Repeated calls with the same arguments will
     /// return the same pointer.
-    const spirv::StorageTexture* StorageTexture(ast::TextureDimension d,
-                                                ast::TexelFormat f,
-                                                ast::Access a);
+    const spirv::StorageTexture* StorageTexture(type::TextureDimension d,
+                                                type::TexelFormat f,
+                                                type::Access a);
 
   private:
     struct State;
diff --git a/src/tint/reader/spirv/parser_type_test.cc b/src/tint/reader/spirv/parser_type_test.cc
index 90a8da2..183636f 100644
--- a/src/tint/reader/spirv/parser_type_test.cc
+++ b/src/tint/reader/spirv/parser_type_test.cc
@@ -15,6 +15,7 @@
 #include "gtest/gtest.h"
 
 #include "src/tint/reader/spirv/parser_type.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::reader::spirv {
 namespace {
@@ -28,24 +29,24 @@
     EXPECT_EQ(ty.U32(), ty.U32());
     EXPECT_EQ(ty.F32(), ty.F32());
     EXPECT_EQ(ty.I32(), ty.I32());
-    EXPECT_EQ(ty.Pointer(ty.I32(), ast::AddressSpace::kNone),
-              ty.Pointer(ty.I32(), ast::AddressSpace::kNone));
+    EXPECT_EQ(ty.Pointer(ty.I32(), type::AddressSpace::kNone),
+              ty.Pointer(ty.I32(), type::AddressSpace::kNone));
     EXPECT_EQ(ty.Vector(ty.I32(), 3), ty.Vector(ty.I32(), 3));
     EXPECT_EQ(ty.Matrix(ty.I32(), 3, 2), ty.Matrix(ty.I32(), 3, 2));
     EXPECT_EQ(ty.Array(ty.I32(), 3, 2), ty.Array(ty.I32(), 3, 2));
     EXPECT_EQ(ty.Alias(sym, ty.I32()), ty.Alias(sym, ty.I32()));
     EXPECT_EQ(ty.Struct(sym, {ty.I32()}), ty.Struct(sym, {ty.I32()}));
     EXPECT_EQ(ty.Sampler(ast::SamplerKind::kSampler), ty.Sampler(ast::SamplerKind::kSampler));
-    EXPECT_EQ(ty.DepthTexture(ast::TextureDimension::k2d),
-              ty.DepthTexture(ast::TextureDimension::k2d));
-    EXPECT_EQ(ty.MultisampledTexture(ast::TextureDimension::k2d, ty.I32()),
-              ty.MultisampledTexture(ast::TextureDimension::k2d, ty.I32()));
-    EXPECT_EQ(ty.SampledTexture(ast::TextureDimension::k2d, ty.I32()),
-              ty.SampledTexture(ast::TextureDimension::k2d, ty.I32()));
-    EXPECT_EQ(ty.StorageTexture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Uint,
-                                ast::Access::kRead),
-              ty.StorageTexture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Uint,
-                                ast::Access::kRead));
+    EXPECT_EQ(ty.DepthTexture(type::TextureDimension::k2d),
+              ty.DepthTexture(type::TextureDimension::k2d));
+    EXPECT_EQ(ty.MultisampledTexture(type::TextureDimension::k2d, ty.I32()),
+              ty.MultisampledTexture(type::TextureDimension::k2d, ty.I32()));
+    EXPECT_EQ(ty.SampledTexture(type::TextureDimension::k2d, ty.I32()),
+              ty.SampledTexture(type::TextureDimension::k2d, ty.I32()));
+    EXPECT_EQ(ty.StorageTexture(type::TextureDimension::k2d, type::TexelFormat::kR32Uint,
+                                type::Access::kRead),
+              ty.StorageTexture(type::TextureDimension::k2d, type::TexelFormat::kR32Uint,
+                                type::Access::kRead));
 }
 
 TEST(SpvParserTypeTest, DifferentArgumentsGivesDifferentPointer) {
@@ -53,10 +54,10 @@
     Symbol sym_b(Symbol(2, {}));
 
     TypeManager ty;
-    EXPECT_NE(ty.Pointer(ty.I32(), ast::AddressSpace::kNone),
-              ty.Pointer(ty.U32(), ast::AddressSpace::kNone));
-    EXPECT_NE(ty.Pointer(ty.I32(), ast::AddressSpace::kNone),
-              ty.Pointer(ty.I32(), ast::AddressSpace::kIn));
+    EXPECT_NE(ty.Pointer(ty.I32(), type::AddressSpace::kNone),
+              ty.Pointer(ty.U32(), type::AddressSpace::kNone));
+    EXPECT_NE(ty.Pointer(ty.I32(), type::AddressSpace::kNone),
+              ty.Pointer(ty.I32(), type::AddressSpace::kIn));
     EXPECT_NE(ty.Vector(ty.I32(), 3), ty.Vector(ty.U32(), 3));
     EXPECT_NE(ty.Vector(ty.I32(), 3), ty.Vector(ty.I32(), 2));
     EXPECT_NE(ty.Matrix(ty.I32(), 3, 2), ty.Matrix(ty.U32(), 3, 2));
@@ -69,28 +70,28 @@
     EXPECT_NE(ty.Struct(sym_a, {ty.I32()}), ty.Struct(sym_b, {ty.I32()}));
     EXPECT_NE(ty.Sampler(ast::SamplerKind::kSampler),
               ty.Sampler(ast::SamplerKind::kComparisonSampler));
-    EXPECT_NE(ty.DepthTexture(ast::TextureDimension::k2d),
-              ty.DepthTexture(ast::TextureDimension::k1d));
-    EXPECT_NE(ty.MultisampledTexture(ast::TextureDimension::k2d, ty.I32()),
-              ty.MultisampledTexture(ast::TextureDimension::k3d, ty.I32()));
-    EXPECT_NE(ty.MultisampledTexture(ast::TextureDimension::k2d, ty.I32()),
-              ty.MultisampledTexture(ast::TextureDimension::k2d, ty.U32()));
-    EXPECT_NE(ty.SampledTexture(ast::TextureDimension::k2d, ty.I32()),
-              ty.SampledTexture(ast::TextureDimension::k3d, ty.I32()));
-    EXPECT_NE(ty.SampledTexture(ast::TextureDimension::k2d, ty.I32()),
-              ty.SampledTexture(ast::TextureDimension::k2d, ty.U32()));
-    EXPECT_NE(ty.StorageTexture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Uint,
-                                ast::Access::kRead),
-              ty.StorageTexture(ast::TextureDimension::k3d, ast::TexelFormat::kR32Uint,
-                                ast::Access::kRead));
-    EXPECT_NE(ty.StorageTexture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Uint,
-                                ast::Access::kRead),
-              ty.StorageTexture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Sint,
-                                ast::Access::kRead));
-    EXPECT_NE(ty.StorageTexture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Uint,
-                                ast::Access::kRead),
-              ty.StorageTexture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Uint,
-                                ast::Access::kWrite));
+    EXPECT_NE(ty.DepthTexture(type::TextureDimension::k2d),
+              ty.DepthTexture(type::TextureDimension::k1d));
+    EXPECT_NE(ty.MultisampledTexture(type::TextureDimension::k2d, ty.I32()),
+              ty.MultisampledTexture(type::TextureDimension::k3d, ty.I32()));
+    EXPECT_NE(ty.MultisampledTexture(type::TextureDimension::k2d, ty.I32()),
+              ty.MultisampledTexture(type::TextureDimension::k2d, ty.U32()));
+    EXPECT_NE(ty.SampledTexture(type::TextureDimension::k2d, ty.I32()),
+              ty.SampledTexture(type::TextureDimension::k3d, ty.I32()));
+    EXPECT_NE(ty.SampledTexture(type::TextureDimension::k2d, ty.I32()),
+              ty.SampledTexture(type::TextureDimension::k2d, ty.U32()));
+    EXPECT_NE(ty.StorageTexture(type::TextureDimension::k2d, type::TexelFormat::kR32Uint,
+                                type::Access::kRead),
+              ty.StorageTexture(type::TextureDimension::k3d, type::TexelFormat::kR32Uint,
+                                type::Access::kRead));
+    EXPECT_NE(ty.StorageTexture(type::TextureDimension::k2d, type::TexelFormat::kR32Uint,
+                                type::Access::kRead),
+              ty.StorageTexture(type::TextureDimension::k2d, type::TexelFormat::kR32Sint,
+                                type::Access::kRead));
+    EXPECT_NE(ty.StorageTexture(type::TextureDimension::k2d, type::TexelFormat::kR32Uint,
+                                type::Access::kRead),
+              ty.StorageTexture(type::TextureDimension::k2d, type::TexelFormat::kR32Uint,
+                                type::Access::kWrite));
 }
 
 }  // namespace
diff --git a/src/tint/reader/wgsl/lexer.cc b/src/tint/reader/wgsl/lexer.cc
index 9ebe5d8..89804f2 100644
--- a/src/tint/reader/wgsl/lexer.cc
+++ b/src/tint/reader/wgsl/lexer.cc
@@ -1141,6 +1141,9 @@
     if (str == "continuing") {
         return {Token::Type::kContinuing, source, "continuing"};
     }
+    if (str == "diagnostic") {
+        return {Token::Type::kDiagnostic, source, "diagnostic"};
+    }
     if (str == "discard") {
         return {Token::Type::kDiscard, source, "discard"};
     }
diff --git a/src/tint/reader/wgsl/lexer_test.cc b/src/tint/reader/wgsl/lexer_test.cc
index a7c13e6..ffa85bd 100644
--- a/src/tint/reader/wgsl/lexer_test.cc
+++ b/src/tint/reader/wgsl/lexer_test.cc
@@ -1061,8 +1061,10 @@
                     TokenData{"continue", Token::Type::kContinue},
                     TokenData{"continuing", Token::Type::kContinuing},
                     TokenData{"default", Token::Type::kDefault},
+                    TokenData{"diagnostic", Token::Type::kDiagnostic},
                     TokenData{"discard", Token::Type::kDiscard},
                     TokenData{"else", Token::Type::kElse},
+                    TokenData{"enable", Token::Type::kEnable},
                     TokenData{"f32", Token::Type::kF32},
                     TokenData{"fallthrough", Token::Type::kFallthrough},
                     TokenData{"false", Token::Type::kFalse},
diff --git a/src/tint/reader/wgsl/parser_impl.cc b/src/tint/reader/wgsl/parser_impl.cc
index d35a87e..4ac0aa2 100644
--- a/src/tint/reader/wgsl/parser_impl.cc
+++ b/src/tint/reader/wgsl/parser_impl.cc
@@ -43,6 +43,7 @@
 #include "src/tint/type/external_texture.h"
 #include "src/tint/type/multisampled_texture.h"
 #include "src/tint/type/sampled_texture.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/utils/reverse.h"
 #include "src/tint/utils/string.h"
 
@@ -212,8 +213,8 @@
 
 ParserImpl::VarDeclInfo::VarDeclInfo(Source source_in,
                                      std::string name_in,
-                                     ast::AddressSpace address_space_in,
-                                     ast::Access access_in,
+                                     type::AddressSpace address_space_in,
+                                     type::Access access_in,
                                      const ast::Type* type_in)
     : source(std::move(source_in)),
       name(std::move(name_in)),
@@ -753,7 +754,7 @@
     auto storage = storage_texture_type();
     if (storage.matched) {
         const char* use = "storage texture type";
-        using StorageTextureInfo = std::pair<tint::ast::TexelFormat, tint::ast::Access>;
+        using StorageTextureInfo = std::pair<tint::type::TexelFormat, tint::type::Access>;
         auto params = expect_lt_gt_block(use, [&]() -> Expect<StorageTextureInfo> {
             auto format = expect_texel_format(use);
             if (format.errored) {
@@ -806,29 +807,29 @@
 //  | TEXTURE_SAMPLED_3D
 //  | TEXTURE_SAMPLED_CUBE
 //  | TEXTURE_SAMPLED_CUBE_ARRAY
-Maybe<const ast::TextureDimension> ParserImpl::sampled_texture_type() {
+Maybe<const type::TextureDimension> ParserImpl::sampled_texture_type() {
     if (match(Token::Type::kTextureSampled1d)) {
-        return ast::TextureDimension::k1d;
+        return type::TextureDimension::k1d;
     }
 
     if (match(Token::Type::kTextureSampled2d)) {
-        return ast::TextureDimension::k2d;
+        return type::TextureDimension::k2d;
     }
 
     if (match(Token::Type::kTextureSampled2dArray)) {
-        return ast::TextureDimension::k2dArray;
+        return type::TextureDimension::k2dArray;
     }
 
     if (match(Token::Type::kTextureSampled3d)) {
-        return ast::TextureDimension::k3d;
+        return type::TextureDimension::k3d;
     }
 
     if (match(Token::Type::kTextureSampledCube)) {
-        return ast::TextureDimension::kCube;
+        return type::TextureDimension::kCube;
     }
 
     if (match(Token::Type::kTextureSampledCubeArray)) {
-        return ast::TextureDimension::kCubeArray;
+        return type::TextureDimension::kCubeArray;
     }
 
     return Failure::kNoMatch;
@@ -847,9 +848,9 @@
 
 // multisampled_texture_type
 //  : TEXTURE_MULTISAMPLED_2D
-Maybe<const ast::TextureDimension> ParserImpl::multisampled_texture_type() {
+Maybe<const type::TextureDimension> ParserImpl::multisampled_texture_type() {
     if (match(Token::Type::kTextureMultisampled2d)) {
-        return ast::TextureDimension::k2d;
+        return type::TextureDimension::k2d;
     }
 
     return Failure::kNoMatch;
@@ -860,18 +861,18 @@
 //  | TEXTURE_STORAGE_2D
 //  | TEXTURE_STORAGE_2D_ARRAY
 //  | TEXTURE_STORAGE_3D
-Maybe<const ast::TextureDimension> ParserImpl::storage_texture_type() {
+Maybe<const type::TextureDimension> ParserImpl::storage_texture_type() {
     if (match(Token::Type::kTextureStorage1d)) {
-        return ast::TextureDimension::k1d;
+        return type::TextureDimension::k1d;
     }
     if (match(Token::Type::kTextureStorage2d)) {
-        return ast::TextureDimension::k2d;
+        return type::TextureDimension::k2d;
     }
     if (match(Token::Type::kTextureStorage2dArray)) {
-        return ast::TextureDimension::k2dArray;
+        return type::TextureDimension::k2dArray;
     }
     if (match(Token::Type::kTextureStorage3d)) {
-        return ast::TextureDimension::k3d;
+        return type::TextureDimension::k3d;
     }
 
     return Failure::kNoMatch;
@@ -886,19 +887,19 @@
 Maybe<const ast::Type*> ParserImpl::depth_texture_type() {
     Source source;
     if (match(Token::Type::kTextureDepth2d, &source)) {
-        return builder_.ty.depth_texture(source, ast::TextureDimension::k2d);
+        return builder_.ty.depth_texture(source, type::TextureDimension::k2d);
     }
     if (match(Token::Type::kTextureDepth2dArray, &source)) {
-        return builder_.ty.depth_texture(source, ast::TextureDimension::k2dArray);
+        return builder_.ty.depth_texture(source, type::TextureDimension::k2dArray);
     }
     if (match(Token::Type::kTextureDepthCube, &source)) {
-        return builder_.ty.depth_texture(source, ast::TextureDimension::kCube);
+        return builder_.ty.depth_texture(source, type::TextureDimension::kCube);
     }
     if (match(Token::Type::kTextureDepthCubeArray, &source)) {
-        return builder_.ty.depth_texture(source, ast::TextureDimension::kCubeArray);
+        return builder_.ty.depth_texture(source, type::TextureDimension::kCubeArray);
     }
     if (match(Token::Type::kTextureDepthMultisampled2d, &source)) {
-        return builder_.ty.depth_multisampled_texture(source, ast::TextureDimension::k2d);
+        return builder_.ty.depth_multisampled_texture(source, type::TextureDimension::k2d);
     }
     return Failure::kNoMatch;
 }
@@ -920,8 +921,8 @@
 //  | 'rgba32uint'
 //  | 'rgba32sint'
 //  | 'rgba32float'
-Expect<ast::TexelFormat> ParserImpl::expect_texel_format(std::string_view use) {
-    return expect_enum("texel format", ast::ParseTexelFormat, ast::kTexelFormatStrings, use);
+Expect<type::TexelFormat> ParserImpl::expect_texel_format(std::string_view use) {
+    return expect_enum("texel format", type::ParseTexelFormat, type::kTexelFormatStrings, use);
 }
 
 Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_ident_with_optional_type_specifier(
@@ -970,8 +971,8 @@
 //   : 'read'
 //   | 'write'
 //   | 'read_write'
-Expect<ast::Access> ParserImpl::expect_access_mode(std::string_view use) {
-    return expect_enum("access control", ast::ParseAccess, ast::kAccessStrings, use);
+Expect<type::Access> ParserImpl::expect_access_mode(std::string_view use) {
+    return expect_enum("access control", type::ParseAccess, type::kAccessStrings, use);
 }
 
 // variable_qualifier
@@ -995,7 +996,7 @@
             }
             return VariableQualifier{sc.value, ac.value};
         }
-        return Expect<VariableQualifier>{VariableQualifier{sc.value, ast::Access::kUndefined},
+        return Expect<VariableQualifier>{VariableQualifier{sc.value, type::Access::kUndefined},
                                          source};
     });
 
@@ -1250,8 +1251,8 @@
 Expect<const ast::Type*> ParserImpl::expect_type_specifier_pointer(const Source& s) {
     const char* use = "ptr declaration";
 
-    auto address_space = ast::AddressSpace::kNone;
-    auto access = ast::Access::kUndefined;
+    auto address_space = type::AddressSpace::kNone;
+    auto access = type::Access::kUndefined;
 
     auto subtype = expect_lt_gt_block(use, [&]() -> Expect<const ast::Type*> {
         auto sc = expect_address_space(use);
@@ -1371,8 +1372,8 @@
 //   | 'storage'
 //
 // Note, we also parse `push_constant` from the experimental extension
-Expect<ast::AddressSpace> ParserImpl::expect_address_space(std::string_view use) {
-    return expect_enum("address space", ast::ParseAddressSpace, ast::kAddressSpaceStrings, use);
+Expect<type::AddressSpace> ParserImpl::expect_address_space(std::string_view use) {
+    return expect_enum("address space", type::ParseAddressSpace, type::kAddressSpaceStrings, use);
 }
 
 // struct_decl
diff --git a/src/tint/reader/wgsl/parser_impl.h b/src/tint/reader/wgsl/parser_impl.h
index 5f64853..4ef19bb 100644
--- a/src/tint/reader/wgsl/parser_impl.h
+++ b/src/tint/reader/wgsl/parser_impl.h
@@ -22,11 +22,12 @@
 #include <utility>
 #include <vector>
 
-#include "src/tint/ast/access.h"
 #include "src/tint/program_builder.h"
 #include "src/tint/reader/wgsl/parser_impl_detail.h"
 #include "src/tint/reader/wgsl/token.h"
+#include "src/tint/type/access.h"
 #include "src/tint/type/storage_texture.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::ast {
 class BreakStatement;
@@ -283,8 +284,8 @@
         /// @param type_in variable type
         VarDeclInfo(Source source_in,
                     std::string name_in,
-                    ast::AddressSpace address_space_in,
-                    ast::Access access_in,
+                    type::AddressSpace address_space_in,
+                    type::Access access_in,
                     const ast::Type* type_in);
         /// Destructor
         ~VarDeclInfo();
@@ -294,9 +295,9 @@
         /// Variable name
         std::string name;
         /// Variable address space
-        ast::AddressSpace address_space = ast::AddressSpace::kNone;
+        type::AddressSpace address_space = type::AddressSpace::kNone;
         /// Variable access control
-        ast::Access access = ast::Access::kUndefined;
+        type::Access access = type::Access::kUndefined;
         /// Variable type
         const ast::Type* type = nullptr;
     };
@@ -304,9 +305,9 @@
     /// VariableQualifier contains the parsed information for a variable qualifier
     struct VariableQualifier {
         /// The variable's address space
-        ast::AddressSpace address_space = ast::AddressSpace::kNone;
+        type::AddressSpace address_space = type::AddressSpace::kNone;
         /// The variable's access control
-        ast::Access access = ast::Access::kUndefined;
+        type::Access access = type::Access::kUndefined;
     };
 
     /// MatrixDimensions contains the column and row information for a matrix
@@ -460,8 +461,8 @@
     Maybe<const ast::Type*> type_specifier();
     /// Parses an `address_space` grammar element, erroring on parse failure.
     /// @param use a description of what was being parsed if an error was raised.
-    /// @returns the address space or ast::AddressSpace::kNone if none matched
-    Expect<ast::AddressSpace> expect_address_space(std::string_view use);
+    /// @returns the address space or type::AddressSpace::kNone if none matched
+    Expect<type::AddressSpace> expect_address_space(std::string_view use);
     /// Parses a `struct_decl` grammar element.
     /// @returns the struct type or nullptr on error
     Maybe<const ast::Struct*> struct_decl();
@@ -486,14 +487,14 @@
     /// Parses a `multisampled_texture_type` grammar element
     /// @returns returns the multisample texture dimension or kNone if none
     /// matched.
-    Maybe<const ast::TextureDimension> multisampled_texture_type();
+    Maybe<const type::TextureDimension> multisampled_texture_type();
     /// Parses a `sampled_texture_type` grammar element
     /// @returns returns the sample texture dimension or kNone if none matched.
-    Maybe<const ast::TextureDimension> sampled_texture_type();
+    Maybe<const type::TextureDimension> sampled_texture_type();
     /// Parses a `storage_texture_type` grammar element
     /// @returns returns the storage texture dimension.
     /// Returns kNone if none matched.
-    Maybe<const ast::TextureDimension> storage_texture_type();
+    Maybe<const type::TextureDimension> storage_texture_type();
     /// Parses a `depth_texture_type` grammar element
     /// @returns the parsed Type or nullptr if none matched.
     Maybe<const ast::Type*> depth_texture_type();
@@ -503,7 +504,7 @@
     /// Parses a `texel_format` grammar element
     /// @param use a description of what was being parsed if an error was raised
     /// @returns returns the texel format or kNone if none matched.
-    Expect<ast::TexelFormat> expect_texel_format(std::string_view use);
+    Expect<type::TexelFormat> expect_texel_format(std::string_view use);
     /// Parses a `static_assert_statement` grammar element
     /// @returns returns the static assert, if it matched.
     Maybe<const ast::StaticAssert*> static_assert_statement();
@@ -524,7 +525,7 @@
     /// match a valid access control.
     /// @param use a description of what was being parsed if an error was raised
     /// @returns the parsed access control.
-    Expect<ast::Access> expect_access_mode(std::string_view use);
+    Expect<type::Access> expect_access_mode(std::string_view use);
     /// Parses an interpolation sample name identifier, erroring if the next token does not match a
     /// valid sample name.
     /// @returns the parsed sample name.
diff --git a/src/tint/reader/wgsl/parser_impl_address_space_test.cc b/src/tint/reader/wgsl/parser_impl_address_space_test.cc
index 251c1d0..32c3c47 100644
--- a/src/tint/reader/wgsl/parser_impl_address_space_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_address_space_test.cc
@@ -19,7 +19,7 @@
 
 struct AddressSpaceData {
     const char* input;
-    ast::AddressSpace result;
+    type::AddressSpace result;
 };
 inline std::ostream& operator<<(std::ostream& out, AddressSpaceData data) {
     out << std::string(data.input);
@@ -43,11 +43,11 @@
 INSTANTIATE_TEST_SUITE_P(
     ParserImplTest,
     ParserAddressSpaceTest,
-    testing::Values(AddressSpaceData{"uniform", ast::AddressSpace::kUniform},
-                    AddressSpaceData{"workgroup", ast::AddressSpace::kWorkgroup},
-                    AddressSpaceData{"storage", ast::AddressSpace::kStorage},
-                    AddressSpaceData{"private", ast::AddressSpace::kPrivate},
-                    AddressSpaceData{"function", ast::AddressSpace::kFunction}));
+    testing::Values(AddressSpaceData{"uniform", type::AddressSpace::kUniform},
+                    AddressSpaceData{"workgroup", type::AddressSpace::kWorkgroup},
+                    AddressSpaceData{"storage", type::AddressSpace::kStorage},
+                    AddressSpaceData{"private", type::AddressSpace::kPrivate},
+                    AddressSpaceData{"function", type::AddressSpace::kFunction}));
 
 TEST_F(ParserImplTest, AddressSpace_NoMatch) {
     auto p = parser("not-a-address-space");
diff --git a/src/tint/reader/wgsl/parser_impl_depth_texture_test.cc b/src/tint/reader/wgsl/parser_impl_depth_texture_test.cc
index fbd8ffb..dc8ddbf 100644
--- a/src/tint/reader/wgsl/parser_impl_depth_texture_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_depth_texture_test.cc
@@ -14,6 +14,7 @@
 
 #include "src/tint/reader/wgsl/parser_impl_test_helper.h"
 #include "src/tint/type/depth_texture.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::reader::wgsl {
 namespace {
@@ -34,7 +35,7 @@
     ASSERT_NE(t.value, nullptr);
     ASSERT_TRUE(t->Is<ast::Texture>());
     ASSERT_TRUE(t->Is<ast::DepthTexture>());
-    EXPECT_EQ(t->As<ast::Texture>()->dim, ast::TextureDimension::k2d);
+    EXPECT_EQ(t->As<ast::Texture>()->dim, type::TextureDimension::k2d);
     EXPECT_FALSE(p->has_error());
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 17u}}));
 }
@@ -47,7 +48,7 @@
     ASSERT_NE(t.value, nullptr);
     ASSERT_TRUE(t->Is<ast::Texture>());
     ASSERT_TRUE(t->Is<ast::DepthTexture>());
-    EXPECT_EQ(t->As<ast::Texture>()->dim, ast::TextureDimension::k2dArray);
+    EXPECT_EQ(t->As<ast::Texture>()->dim, type::TextureDimension::k2dArray);
     EXPECT_FALSE(p->has_error());
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 23u}}));
 }
@@ -60,7 +61,7 @@
     ASSERT_NE(t.value, nullptr);
     ASSERT_TRUE(t->Is<ast::Texture>());
     ASSERT_TRUE(t->Is<ast::DepthTexture>());
-    EXPECT_EQ(t->As<ast::Texture>()->dim, ast::TextureDimension::kCube);
+    EXPECT_EQ(t->As<ast::Texture>()->dim, type::TextureDimension::kCube);
     EXPECT_FALSE(p->has_error());
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 19u}}));
 }
@@ -73,7 +74,7 @@
     ASSERT_NE(t.value, nullptr);
     ASSERT_TRUE(t->Is<ast::Texture>());
     ASSERT_TRUE(t->Is<ast::DepthTexture>());
-    EXPECT_EQ(t->As<ast::Texture>()->dim, ast::TextureDimension::kCubeArray);
+    EXPECT_EQ(t->As<ast::Texture>()->dim, type::TextureDimension::kCubeArray);
     EXPECT_FALSE(p->has_error());
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 25u}}));
 }
@@ -86,7 +87,7 @@
     ASSERT_NE(t.value, nullptr);
     ASSERT_TRUE(t->Is<ast::Texture>());
     ASSERT_TRUE(t->Is<ast::DepthMultisampledTexture>());
-    EXPECT_EQ(t->As<ast::Texture>()->dim, ast::TextureDimension::k2d);
+    EXPECT_EQ(t->As<ast::Texture>()->dim, type::TextureDimension::k2d);
     EXPECT_FALSE(p->has_error());
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 30u}}));
 }
diff --git a/src/tint/reader/wgsl/parser_impl_global_variable_decl_test.cc b/src/tint/reader/wgsl/parser_impl_global_variable_decl_test.cc
index 695fc86..0dcde16 100644
--- a/src/tint/reader/wgsl/parser_impl_global_variable_decl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_global_variable_decl_test.cc
@@ -31,7 +31,7 @@
 
     EXPECT_EQ(var->symbol, p->builder().Symbols().Get("a"));
     EXPECT_TRUE(var->type->Is<ast::F32>());
-    EXPECT_EQ(var->declared_address_space, ast::AddressSpace::kPrivate);
+    EXPECT_EQ(var->declared_address_space, type::AddressSpace::kPrivate);
 
     EXPECT_EQ(var->source.range.begin.line, 1u);
     EXPECT_EQ(var->source.range.begin.column, 14u);
@@ -55,7 +55,7 @@
 
     EXPECT_EQ(var->symbol, p->builder().Symbols().Get("a"));
     EXPECT_TRUE(var->type->Is<ast::F32>());
-    EXPECT_EQ(var->declared_address_space, ast::AddressSpace::kPrivate);
+    EXPECT_EQ(var->declared_address_space, type::AddressSpace::kPrivate);
 
     EXPECT_EQ(var->source.range.begin.line, 1u);
     EXPECT_EQ(var->source.range.begin.column, 14u);
@@ -81,7 +81,7 @@
     EXPECT_EQ(var->symbol, p->builder().Symbols().Get("a"));
     ASSERT_NE(var->type, nullptr);
     EXPECT_TRUE(var->type->Is<ast::F32>());
-    EXPECT_EQ(var->declared_address_space, ast::AddressSpace::kUniform);
+    EXPECT_EQ(var->declared_address_space, type::AddressSpace::kUniform);
 
     EXPECT_EQ(var->source.range.begin.line, 1u);
     EXPECT_EQ(var->source.range.begin.column, 36u);
@@ -112,7 +112,7 @@
     EXPECT_EQ(var->symbol, p->builder().Symbols().Get("a"));
     ASSERT_NE(var->type, nullptr);
     EXPECT_TRUE(var->type->Is<ast::F32>());
-    EXPECT_EQ(var->declared_address_space, ast::AddressSpace::kUniform);
+    EXPECT_EQ(var->declared_address_space, type::AddressSpace::kUniform);
 
     EXPECT_EQ(var->source.range.begin.line, 1u);
     EXPECT_EQ(var->source.range.begin.column, 36u);
diff --git a/src/tint/reader/wgsl/parser_impl_sampled_texture_test.cc b/src/tint/reader/wgsl/parser_impl_sampled_texture_test.cc
index 6aa1aab..5a2d38a 100644
--- a/src/tint/reader/wgsl/parser_impl_sampled_texture_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_sampled_texture_test.cc
@@ -13,6 +13,7 @@
 // limitations under the License.
 
 #include "src/tint/reader/wgsl/parser_impl_test_helper.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::reader::wgsl {
 namespace {
@@ -30,7 +31,7 @@
     auto t = p->sampled_texture_type();
     EXPECT_TRUE(t.matched);
     EXPECT_FALSE(t.errored);
-    EXPECT_EQ(t.value, ast::TextureDimension::k1d);
+    EXPECT_EQ(t.value, type::TextureDimension::k1d);
     EXPECT_FALSE(p->has_error());
 }
 
@@ -39,7 +40,7 @@
     auto t = p->sampled_texture_type();
     EXPECT_TRUE(t.matched);
     EXPECT_FALSE(t.errored);
-    EXPECT_EQ(t.value, ast::TextureDimension::k2d);
+    EXPECT_EQ(t.value, type::TextureDimension::k2d);
     EXPECT_FALSE(p->has_error());
 }
 
@@ -48,7 +49,7 @@
     auto t = p->sampled_texture_type();
     EXPECT_TRUE(t.matched);
     EXPECT_FALSE(t.errored);
-    EXPECT_EQ(t.value, ast::TextureDimension::k2dArray);
+    EXPECT_EQ(t.value, type::TextureDimension::k2dArray);
     EXPECT_FALSE(p->has_error());
 }
 
@@ -57,7 +58,7 @@
     auto t = p->sampled_texture_type();
     EXPECT_TRUE(t.matched);
     EXPECT_FALSE(t.errored);
-    EXPECT_EQ(t.value, ast::TextureDimension::k3d);
+    EXPECT_EQ(t.value, type::TextureDimension::k3d);
     EXPECT_FALSE(p->has_error());
 }
 
@@ -66,7 +67,7 @@
     auto t = p->sampled_texture_type();
     EXPECT_TRUE(t.matched);
     EXPECT_FALSE(t.errored);
-    EXPECT_EQ(t.value, ast::TextureDimension::kCube);
+    EXPECT_EQ(t.value, type::TextureDimension::kCube);
     EXPECT_FALSE(p->has_error());
 }
 
@@ -75,7 +76,7 @@
     auto t = p->sampled_texture_type();
     EXPECT_TRUE(t.matched);
     EXPECT_FALSE(t.errored);
-    EXPECT_EQ(t.value, ast::TextureDimension::kCubeArray);
+    EXPECT_EQ(t.value, type::TextureDimension::kCubeArray);
     EXPECT_FALSE(p->has_error());
 }
 
diff --git a/src/tint/reader/wgsl/parser_impl_storage_texture_test.cc b/src/tint/reader/wgsl/parser_impl_storage_texture_test.cc
index 528f3a4..e1c25b6 100644
--- a/src/tint/reader/wgsl/parser_impl_storage_texture_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_storage_texture_test.cc
@@ -13,6 +13,7 @@
 // limitations under the License.
 
 #include "src/tint/reader/wgsl/parser_impl_test_helper.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::reader::wgsl {
 namespace {
@@ -30,7 +31,7 @@
     auto t = p->storage_texture_type();
     EXPECT_TRUE(t.matched);
     EXPECT_FALSE(t.errored);
-    EXPECT_EQ(t.value, ast::TextureDimension::k1d);
+    EXPECT_EQ(t.value, type::TextureDimension::k1d);
     EXPECT_FALSE(p->has_error());
 }
 
@@ -39,7 +40,7 @@
     auto t = p->storage_texture_type();
     EXPECT_TRUE(t.matched);
     EXPECT_FALSE(t.errored);
-    EXPECT_EQ(t.value, ast::TextureDimension::k2d);
+    EXPECT_EQ(t.value, type::TextureDimension::k2d);
     EXPECT_FALSE(p->has_error());
 }
 
@@ -48,7 +49,7 @@
     auto t = p->storage_texture_type();
     EXPECT_TRUE(t.matched);
     EXPECT_FALSE(t.errored);
-    EXPECT_EQ(t.value, ast::TextureDimension::k2dArray);
+    EXPECT_EQ(t.value, type::TextureDimension::k2dArray);
     EXPECT_FALSE(p->has_error());
 }
 
@@ -57,7 +58,7 @@
     auto t = p->storage_texture_type();
     EXPECT_TRUE(t.matched);
     EXPECT_FALSE(t.errored);
-    EXPECT_EQ(t.value, ast::TextureDimension::k3d);
+    EXPECT_EQ(t.value, type::TextureDimension::k3d);
     EXPECT_FALSE(p->has_error());
 }
 
diff --git a/src/tint/reader/wgsl/parser_impl_texel_format_test.cc b/src/tint/reader/wgsl/parser_impl_texel_format_test.cc
index 8551032..046feef 100644
--- a/src/tint/reader/wgsl/parser_impl_texel_format_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_texel_format_test.cc
@@ -30,7 +30,7 @@
     auto p = parser("r32uint");
     auto t = p->expect_texel_format("test");
     EXPECT_FALSE(t.errored);
-    EXPECT_EQ(t.value, ast::TexelFormat::kR32Uint);
+    EXPECT_EQ(t.value, type::TexelFormat::kR32Uint);
     EXPECT_FALSE(p->has_error());
 }
 
@@ -38,7 +38,7 @@
     auto p = parser("r32sint");
     auto t = p->expect_texel_format("test");
     EXPECT_FALSE(t.errored);
-    EXPECT_EQ(t.value, ast::TexelFormat::kR32Sint);
+    EXPECT_EQ(t.value, type::TexelFormat::kR32Sint);
     EXPECT_FALSE(p->has_error());
 }
 
@@ -46,7 +46,7 @@
     auto p = parser("r32float");
     auto t = p->expect_texel_format("test");
     EXPECT_FALSE(t.errored);
-    EXPECT_EQ(t.value, ast::TexelFormat::kR32Float);
+    EXPECT_EQ(t.value, type::TexelFormat::kR32Float);
     EXPECT_FALSE(p->has_error());
 }
 
@@ -54,7 +54,7 @@
     auto p = parser("rgba8unorm");
     auto t = p->expect_texel_format("test");
     EXPECT_FALSE(t.errored);
-    EXPECT_EQ(t.value, ast::TexelFormat::kRgba8Unorm);
+    EXPECT_EQ(t.value, type::TexelFormat::kRgba8Unorm);
     EXPECT_FALSE(p->has_error());
 }
 
@@ -62,7 +62,7 @@
     auto p = parser("rgba8snorm");
     auto t = p->expect_texel_format("test");
     EXPECT_FALSE(t.errored);
-    EXPECT_EQ(t.value, ast::TexelFormat::kRgba8Snorm);
+    EXPECT_EQ(t.value, type::TexelFormat::kRgba8Snorm);
     EXPECT_FALSE(p->has_error());
 }
 
@@ -70,7 +70,7 @@
     auto p = parser("rgba8uint");
     auto t = p->expect_texel_format("test");
     EXPECT_FALSE(t.errored);
-    EXPECT_EQ(t.value, ast::TexelFormat::kRgba8Uint);
+    EXPECT_EQ(t.value, type::TexelFormat::kRgba8Uint);
     EXPECT_FALSE(p->has_error());
 }
 
@@ -78,7 +78,7 @@
     auto p = parser("rgba8sint");
     auto t = p->expect_texel_format("test");
     EXPECT_FALSE(t.errored);
-    EXPECT_EQ(t.value, ast::TexelFormat::kRgba8Sint);
+    EXPECT_EQ(t.value, type::TexelFormat::kRgba8Sint);
     EXPECT_FALSE(p->has_error());
 }
 
@@ -86,7 +86,7 @@
     auto p = parser("rg32uint");
     auto t = p->expect_texel_format("test");
     EXPECT_FALSE(t.errored);
-    EXPECT_EQ(t.value, ast::TexelFormat::kRg32Uint);
+    EXPECT_EQ(t.value, type::TexelFormat::kRg32Uint);
     EXPECT_FALSE(p->has_error());
 }
 
@@ -94,7 +94,7 @@
     auto p = parser("rg32sint");
     auto t = p->expect_texel_format("test");
     EXPECT_FALSE(t.errored);
-    EXPECT_EQ(t.value, ast::TexelFormat::kRg32Sint);
+    EXPECT_EQ(t.value, type::TexelFormat::kRg32Sint);
     EXPECT_FALSE(p->has_error());
 }
 
@@ -102,7 +102,7 @@
     auto p = parser("rg32float");
     auto t = p->expect_texel_format("test");
     EXPECT_FALSE(t.errored);
-    EXPECT_EQ(t.value, ast::TexelFormat::kRg32Float);
+    EXPECT_EQ(t.value, type::TexelFormat::kRg32Float);
     EXPECT_FALSE(p->has_error());
 }
 
@@ -110,7 +110,7 @@
     auto p = parser("rgba16uint");
     auto t = p->expect_texel_format("test");
     EXPECT_FALSE(t.errored);
-    EXPECT_EQ(t.value, ast::TexelFormat::kRgba16Uint);
+    EXPECT_EQ(t.value, type::TexelFormat::kRgba16Uint);
     EXPECT_FALSE(p->has_error());
 }
 
@@ -118,7 +118,7 @@
     auto p = parser("rgba16sint");
     auto t = p->expect_texel_format("test");
     EXPECT_FALSE(t.errored);
-    EXPECT_EQ(t.value, ast::TexelFormat::kRgba16Sint);
+    EXPECT_EQ(t.value, type::TexelFormat::kRgba16Sint);
     EXPECT_FALSE(p->has_error());
 }
 
@@ -126,7 +126,7 @@
     auto p = parser("rgba16float");
     auto t = p->expect_texel_format("test");
     EXPECT_FALSE(t.errored);
-    EXPECT_EQ(t.value, ast::TexelFormat::kRgba16Float);
+    EXPECT_EQ(t.value, type::TexelFormat::kRgba16Float);
     EXPECT_FALSE(p->has_error());
 }
 
@@ -134,7 +134,7 @@
     auto p = parser("rgba32uint");
     auto t = p->expect_texel_format("test");
     EXPECT_FALSE(t.errored);
-    EXPECT_EQ(t.value, ast::TexelFormat::kRgba32Uint);
+    EXPECT_EQ(t.value, type::TexelFormat::kRgba32Uint);
     EXPECT_FALSE(p->has_error());
 }
 
@@ -142,7 +142,7 @@
     auto p = parser("rgba32sint");
     auto t = p->expect_texel_format("test");
     EXPECT_FALSE(t.errored);
-    EXPECT_EQ(t.value, ast::TexelFormat::kRgba32Sint);
+    EXPECT_EQ(t.value, type::TexelFormat::kRgba32Sint);
     EXPECT_FALSE(p->has_error());
 }
 
@@ -150,7 +150,7 @@
     auto p = parser("rgba32float");
     auto t = p->expect_texel_format("test");
     EXPECT_FALSE(t.errored);
-    EXPECT_EQ(t.value, ast::TexelFormat::kRgba32Float);
+    EXPECT_EQ(t.value, type::TexelFormat::kRgba32Float);
     EXPECT_FALSE(p->has_error());
 }
 
diff --git a/src/tint/reader/wgsl/parser_impl_texture_sampler_test.cc b/src/tint/reader/wgsl/parser_impl_texture_sampler_test.cc
index 01a4241..43d4ada 100644
--- a/src/tint/reader/wgsl/parser_impl_texture_sampler_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_texture_sampler_test.cc
@@ -16,6 +16,7 @@
 #include "src/tint/type/depth_texture.h"
 #include "src/tint/type/multisampled_texture.h"
 #include "src/tint/type/sampled_texture.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::reader::wgsl {
 namespace {
@@ -62,7 +63,7 @@
     ASSERT_NE(t.value, nullptr);
     ASSERT_TRUE(t->Is<ast::Texture>());
     ASSERT_TRUE(t->Is<ast::DepthTexture>());
-    EXPECT_EQ(t->As<ast::Texture>()->dim, ast::TextureDimension::k2d);
+    EXPECT_EQ(t->As<ast::Texture>()->dim, type::TextureDimension::k2d);
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 17u}}));
 }
 
@@ -76,7 +77,7 @@
     ASSERT_TRUE(t->Is<ast::Texture>());
     ASSERT_TRUE(t->Is<ast::SampledTexture>());
     ASSERT_TRUE(t->As<ast::SampledTexture>()->type->Is<ast::F32>());
-    EXPECT_EQ(t->As<ast::Texture>()->dim, ast::TextureDimension::k1d);
+    EXPECT_EQ(t->As<ast::Texture>()->dim, type::TextureDimension::k1d);
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 16u}}));
 }
 
@@ -90,7 +91,7 @@
     ASSERT_TRUE(t->Is<ast::Texture>());
     ASSERT_TRUE(t->Is<ast::SampledTexture>());
     ASSERT_TRUE(t->As<ast::SampledTexture>()->type->Is<ast::I32>());
-    EXPECT_EQ(t->As<ast::Texture>()->dim, ast::TextureDimension::k2d);
+    EXPECT_EQ(t->As<ast::Texture>()->dim, type::TextureDimension::k2d);
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 16u}}));
 }
 
@@ -104,7 +105,7 @@
     ASSERT_TRUE(t->Is<ast::Texture>());
     ASSERT_TRUE(t->Is<ast::SampledTexture>());
     ASSERT_TRUE(t->As<ast::SampledTexture>()->type->Is<ast::U32>());
-    EXPECT_EQ(t->As<ast::Texture>()->dim, ast::TextureDimension::k3d);
+    EXPECT_EQ(t->As<ast::Texture>()->dim, type::TextureDimension::k3d);
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 16u}}));
 }
 
@@ -148,7 +149,7 @@
     ASSERT_TRUE(t->Is<ast::Texture>());
     ASSERT_TRUE(t->Is<ast::MultisampledTexture>());
     ASSERT_TRUE(t->As<ast::MultisampledTexture>()->type->Is<ast::I32>());
-    EXPECT_EQ(t->As<ast::Texture>()->dim, ast::TextureDimension::k2d);
+    EXPECT_EQ(t->As<ast::Texture>()->dim, type::TextureDimension::k2d);
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 29u}}));
 }
 
@@ -190,9 +191,9 @@
 
     ASSERT_TRUE(t->Is<ast::Texture>());
     ASSERT_TRUE(t->Is<ast::StorageTexture>());
-    EXPECT_EQ(t->As<ast::StorageTexture>()->format, ast::TexelFormat::kRg32Float);
-    EXPECT_EQ(t->As<ast::StorageTexture>()->access, ast::Access::kRead);
-    EXPECT_EQ(t->As<ast::Texture>()->dim, ast::TextureDimension::k1d);
+    EXPECT_EQ(t->As<ast::StorageTexture>()->format, type::TexelFormat::kRg32Float);
+    EXPECT_EQ(t->As<ast::StorageTexture>()->access, type::Access::kRead);
+    EXPECT_EQ(t->As<ast::Texture>()->dim, type::TextureDimension::k1d);
     EXPECT_EQ(t->source.range, (Source::Range{{1u, 1u}, {1u, 36u}}));
 }
 
@@ -206,9 +207,9 @@
 
     ASSERT_TRUE(t->Is<ast::Texture>());
     ASSERT_TRUE(t->Is<ast::StorageTexture>());
-    EXPECT_EQ(t->As<ast::StorageTexture>()->format, ast::TexelFormat::kR32Uint);
-    EXPECT_EQ(t->As<ast::StorageTexture>()->access, ast::Access::kWrite);
-    EXPECT_EQ(t->As<ast::Texture>()->dim, ast::TextureDimension::k2d);
+    EXPECT_EQ(t->As<ast::StorageTexture>()->format, type::TexelFormat::kR32Uint);
+    EXPECT_EQ(t->As<ast::StorageTexture>()->access, type::Access::kWrite);
+    EXPECT_EQ(t->As<ast::Texture>()->dim, type::TextureDimension::k2d);
     EXPECT_EQ(t->source.range, (Source::Range{{1u, 1u}, {1u, 35u}}));
 }
 
diff --git a/src/tint/reader/wgsl/parser_impl_type_decl_test.cc b/src/tint/reader/wgsl/parser_impl_type_decl_test.cc
index c40c298..1d54255 100644
--- a/src/tint/reader/wgsl/parser_impl_type_decl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_type_decl_test.cc
@@ -176,7 +176,7 @@
 
     auto* ptr = t.value->As<ast::Pointer>();
     ASSERT_TRUE(ptr->type->Is<ast::F32>());
-    ASSERT_EQ(ptr->address_space, ast::AddressSpace::kFunction);
+    ASSERT_EQ(ptr->address_space, type::AddressSpace::kFunction);
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 19u}}));
 }
 
@@ -191,8 +191,8 @@
 
     auto* ptr = t.value->As<ast::Pointer>();
     ASSERT_TRUE(ptr->type->Is<ast::F32>());
-    ASSERT_EQ(ptr->address_space, ast::AddressSpace::kFunction);
-    ASSERT_EQ(ptr->access, ast::Access::kRead);
+    ASSERT_EQ(ptr->address_space, type::AddressSpace::kFunction);
+    ASSERT_EQ(ptr->access, type::Access::kRead);
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 25u}}));
 }
 
@@ -207,7 +207,7 @@
 
     auto* ptr = t.value->As<ast::Pointer>();
     ASSERT_TRUE(ptr->type->Is<ast::Vector>());
-    ASSERT_EQ(ptr->address_space, ast::AddressSpace::kFunction);
+    ASSERT_EQ(ptr->address_space, type::AddressSpace::kFunction);
 
     auto* vec = ptr->type->As<ast::Vector>();
     ASSERT_EQ(vec->width, 2u);
diff --git a/src/tint/reader/wgsl/parser_impl_type_decl_without_ident_test.cc b/src/tint/reader/wgsl/parser_impl_type_decl_without_ident_test.cc
index bd96659..f2ab172 100644
--- a/src/tint/reader/wgsl/parser_impl_type_decl_without_ident_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_type_decl_without_ident_test.cc
@@ -167,7 +167,7 @@
 
     auto* ptr = t.value->As<ast::Pointer>();
     ASSERT_TRUE(ptr->type->Is<ast::F32>());
-    ASSERT_EQ(ptr->address_space, ast::AddressSpace::kFunction);
+    ASSERT_EQ(ptr->address_space, type::AddressSpace::kFunction);
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 19u}}));
 }
 
@@ -182,8 +182,8 @@
 
     auto* ptr = t.value->As<ast::Pointer>();
     ASSERT_TRUE(ptr->type->Is<ast::F32>());
-    ASSERT_EQ(ptr->address_space, ast::AddressSpace::kFunction);
-    ASSERT_EQ(ptr->access, ast::Access::kRead);
+    ASSERT_EQ(ptr->address_space, type::AddressSpace::kFunction);
+    ASSERT_EQ(ptr->access, type::Access::kRead);
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 25u}}));
 }
 
@@ -198,7 +198,7 @@
 
     auto* ptr = t.value->As<ast::Pointer>();
     ASSERT_TRUE(ptr->type->Is<ast::Vector>());
-    ASSERT_EQ(ptr->address_space, ast::AddressSpace::kFunction);
+    ASSERT_EQ(ptr->address_space, type::AddressSpace::kFunction);
 
     auto* vec = ptr->type->As<ast::Vector>();
     ASSERT_EQ(vec->width, 2u);
diff --git a/src/tint/reader/wgsl/parser_impl_variable_decl_test.cc b/src/tint/reader/wgsl/parser_impl_variable_decl_test.cc
index 5cf038b..ba4a872 100644
--- a/src/tint/reader/wgsl/parser_impl_variable_decl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_variable_decl_test.cc
@@ -80,7 +80,7 @@
     EXPECT_FALSE(p->has_error());
     EXPECT_EQ(v->name, "my_var");
     EXPECT_TRUE(v->type->Is<ast::F32>());
-    EXPECT_EQ(v->address_space, ast::AddressSpace::kPrivate);
+    EXPECT_EQ(v->address_space, type::AddressSpace::kPrivate);
 
     EXPECT_EQ(v->source.range.begin.line, 1u);
     EXPECT_EQ(v->source.range.begin.column, 14u);
@@ -96,7 +96,7 @@
     EXPECT_FALSE(p->has_error());
     EXPECT_EQ(v->name, "my_var");
     EXPECT_TRUE(v->type->Is<ast::F32>());
-    EXPECT_EQ(v->address_space, ast::AddressSpace::kPushConstant);
+    EXPECT_EQ(v->address_space, type::AddressSpace::kPushConstant);
 }
 
 TEST_F(ParserImplTest, VariableDecl_InvalidAddressSpace) {
diff --git a/src/tint/reader/wgsl/parser_impl_variable_qualifier_test.cc b/src/tint/reader/wgsl/parser_impl_variable_qualifier_test.cc
index 5c0cd5e..111f207 100644
--- a/src/tint/reader/wgsl/parser_impl_variable_qualifier_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_variable_qualifier_test.cc
@@ -19,8 +19,8 @@
 
 struct VariableStorageData {
     const char* input;
-    ast::AddressSpace address_space;
-    ast::Access access;
+    type::AddressSpace address_space;
+    type::Access access;
 };
 inline std::ostream& operator<<(std::ostream& out, VariableStorageData data) {
     out << std::string(data.input);
@@ -47,15 +47,15 @@
     ParserImplTest,
     VariableQualifierTest,
     testing::Values(
-        VariableStorageData{"uniform", ast::AddressSpace::kUniform, ast::Access::kUndefined},
-        VariableStorageData{"workgroup", ast::AddressSpace::kWorkgroup, ast::Access::kUndefined},
-        VariableStorageData{"storage", ast::AddressSpace::kStorage, ast::Access::kUndefined},
-        VariableStorageData{"private", ast::AddressSpace::kPrivate, ast::Access::kUndefined},
-        VariableStorageData{"function", ast::AddressSpace::kFunction, ast::Access::kUndefined},
-        VariableStorageData{"storage, read", ast::AddressSpace::kStorage, ast::Access::kRead},
-        VariableStorageData{"storage, write", ast::AddressSpace::kStorage, ast::Access::kWrite},
-        VariableStorageData{"storage, read_write", ast::AddressSpace::kStorage,
-                            ast::Access::kReadWrite}));
+        VariableStorageData{"uniform", type::AddressSpace::kUniform, type::Access::kUndefined},
+        VariableStorageData{"workgroup", type::AddressSpace::kWorkgroup, type::Access::kUndefined},
+        VariableStorageData{"storage", type::AddressSpace::kStorage, type::Access::kUndefined},
+        VariableStorageData{"private", type::AddressSpace::kPrivate, type::Access::kUndefined},
+        VariableStorageData{"function", type::AddressSpace::kFunction, type::Access::kUndefined},
+        VariableStorageData{"storage, read", type::AddressSpace::kStorage, type::Access::kRead},
+        VariableStorageData{"storage, write", type::AddressSpace::kStorage, type::Access::kWrite},
+        VariableStorageData{"storage, read_write", type::AddressSpace::kStorage,
+                            type::Access::kReadWrite}));
 
 TEST_F(ParserImplTest, VariableQualifier_NoMatch) {
     auto p = parser("<not-a-storage-class>");
diff --git a/src/tint/reader/wgsl/token.cc b/src/tint/reader/wgsl/token.cc
index ac5eb08..8e3fbdb 100644
--- a/src/tint/reader/wgsl/token.cc
+++ b/src/tint/reader/wgsl/token.cc
@@ -153,6 +153,8 @@
             return "continue";
         case Token::Type::kContinuing:
             return "continuing";
+        case Token::Type::kDiagnostic:
+            return "diagnostic";
         case Token::Type::kDiscard:
             return "discard";
         case Token::Type::kDefault:
diff --git a/src/tint/reader/wgsl/token.h b/src/tint/reader/wgsl/token.h
index 3f92f48..2aeffa9 100644
--- a/src/tint/reader/wgsl/token.h
+++ b/src/tint/reader/wgsl/token.h
@@ -163,6 +163,8 @@
         kContinue,
         /// A 'continuing'
         kContinuing,
+        /// A 'diagnostic'
+        kDiagnostic,
         /// A 'discard'
         kDiscard,
         /// A 'default'
diff --git a/src/tint/resolver/address_space_layout_validation_test.cc b/src/tint/resolver/address_space_layout_validation_test.cc
index 638df21..4055842 100644
--- a/src/tint/resolver/address_space_layout_validation_test.cc
+++ b/src/tint/resolver/address_space_layout_validation_test.cc
@@ -39,7 +39,7 @@
                   Member(Source{{34, 56}}, "b", ty.f32(), utils::Vector{MemberAlign(1_i)}),
               });
 
-    GlobalVar(Source{{78, 90}}, "a", ty.type_name("S"), ast::AddressSpace::kStorage, Group(0_a),
+    GlobalVar(Source{{78, 90}}, "a", ty.type_name("S"), type::AddressSpace::kStorage, Group(0_a),
               Binding(0_a));
 
     ASSERT_FALSE(r()->Resolve());
@@ -69,7 +69,7 @@
                   Member(Source{{34, 56}}, "b", ty.f32(), utils::Vector{MemberAlign(4_i)}),
               });
 
-    GlobalVar(Source{{78, 90}}, "a", ty.type_name("S"), ast::AddressSpace::kStorage, Group(0_a),
+    GlobalVar(Source{{78, 90}}, "a", ty.type_name("S"), type::AddressSpace::kStorage, Group(0_a),
               Binding(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -100,8 +100,8 @@
                   Member(Source{{56, 78}}, "inner", ty.type_name("Inner")),
               });
 
-    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::AddressSpace::kUniform, Group(0_a),
-              Binding(0_a));
+    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), type::AddressSpace::kUniform,
+              Group(0_a), Binding(0_a));
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -145,8 +145,8 @@
                          utils::Vector{MemberAlign(16_i)}),
               });
 
-    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::AddressSpace::kUniform, Group(0_a),
-              Binding(0_a));
+    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), type::AddressSpace::kUniform,
+              Group(0_a), Binding(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -170,8 +170,8 @@
                   Member(Source{{56, 78}}, "inner", ty.type_name("Inner")),
               });
 
-    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::AddressSpace::kUniform, Group(0_a),
-              Binding(0_a));
+    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), type::AddressSpace::kUniform,
+              Group(0_a), Binding(0_a));
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -204,8 +204,8 @@
                          utils::Vector{MemberAlign(16_i)}),
               });
 
-    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::AddressSpace::kUniform, Group(0_a),
-              Binding(0_a));
+    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), type::AddressSpace::kUniform,
+              Group(0_a), Binding(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -236,8 +236,8 @@
                   Member(Source{{78, 90}}, "scalar", ty.i32()),
               });
 
-    GlobalVar(Source{{22, 24}}, "a", ty.type_name("Outer"), ast::AddressSpace::kUniform, Group(0_a),
-              Binding(0_a));
+    GlobalVar(Source{{22, 24}}, "a", ty.type_name("Outer"), type::AddressSpace::kUniform,
+              Group(0_a), Binding(0_a));
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -288,8 +288,8 @@
                   Member(Source{{78, 90}}, "scalar", ty.i32()),
               });
 
-    GlobalVar(Source{{22, 24}}, "a", ty.type_name("Outer"), ast::AddressSpace::kUniform, Group(0_a),
-              Binding(0_a));
+    GlobalVar(Source{{22, 24}}, "a", ty.type_name("Outer"), type::AddressSpace::kUniform,
+              Group(0_a), Binding(0_a));
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -336,8 +336,8 @@
                   Member(Source{{78, 90}}, "scalar", ty.i32(), utils::Vector{MemberAlign(16_i)}),
               });
 
-    GlobalVar(Source{{22, 34}}, "a", ty.type_name("Outer"), ast::AddressSpace::kUniform, Group(0_a),
-              Binding(0_a));
+    GlobalVar(Source{{22, 34}}, "a", ty.type_name("Outer"), type::AddressSpace::kUniform,
+              Group(0_a), Binding(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -358,7 +358,7 @@
                                          });
 
     GlobalVar(Source{{78, 90}}, "a", ty.type_name("ScalarPackedAtEndOfVec3"),
-              ast::AddressSpace::kUniform, Group(0_a), Binding(0_a));
+              type::AddressSpace::kUniform, Group(0_a), Binding(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -381,7 +381,7 @@
                                          });
 
     GlobalVar(Source{{78, 90}}, "a", ty.type_name("ScalarPackedAtEndOfVec3"),
-              ast::AddressSpace::kUniform, Group(0_a), Binding(0_a));
+              type::AddressSpace::kUniform, Group(0_a), Binding(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -406,8 +406,8 @@
                   Member("scalar", ty.i32()),
               });
 
-    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::AddressSpace::kUniform, Group(0_a),
-              Binding(0_a));
+    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), type::AddressSpace::kUniform,
+              Group(0_a), Binding(0_a));
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -440,8 +440,8 @@
                   Member("scalar", ty.i32()),
               });
 
-    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::AddressSpace::kUniform, Group(0_a),
-              Binding(0_a));
+    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), type::AddressSpace::kUniform,
+              Group(0_a), Binding(0_a));
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -483,8 +483,8 @@
                   Member("scalar", ty.i32()),
               });
 
-    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::AddressSpace::kUniform, Group(0_a),
-              Binding(0_a));
+    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), type::AddressSpace::kUniform,
+              Group(0_a), Binding(0_a));
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -502,7 +502,7 @@
     // @group(0) @binding(0)
     // var<uniform> a : array<f32, 4u>;
     GlobalVar(Source{{78, 90}}, "a", ty.array(Source{{34, 56}}, ty.f32(), 4_u),
-              ast::AddressSpace::kUniform, Group(0_a), Binding(0_a));
+              type::AddressSpace::kUniform, Group(0_a), Binding(0_a));
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -523,8 +523,8 @@
                   Member("inner", ty.array(Source{{34, 56}}, ty.array(ty.f32(), 4_u), 4_u)),
               });
 
-    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::AddressSpace::kUniform, Group(0_a),
-              Binding(0_a));
+    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), type::AddressSpace::kUniform,
+              Group(0_a), Binding(0_a));
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -556,8 +556,8 @@
                   Member("scalar", ty.i32()),
               });
 
-    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::AddressSpace::kUniform, Group(0_a),
-              Binding(0_a));
+    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), type::AddressSpace::kUniform,
+              Group(0_a), Binding(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -575,7 +575,7 @@
         Source{{12, 34}}, "S",
         utils::Vector{Member("a", ty.f32(), utils::Vector{MemberSize(5_a)}),
                       Member(Source{{34, 56}}, "b", ty.f32(), utils::Vector{MemberAlign(1_i)})});
-    GlobalVar(Source{{78, 90}}, "a", ty.type_name("S"), ast::AddressSpace::kPushConstant);
+    GlobalVar(Source{{78, 90}}, "a", ty.type_name("S"), type::AddressSpace::kPushConstant);
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -600,7 +600,7 @@
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
     Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{MemberSize(5_a)}),
                                  Member("b", ty.f32(), utils::Vector{MemberAlign(4_i)})});
-    GlobalVar("a", ty.type_name("S"), ast::AddressSpace::kPushConstant);
+    GlobalVar("a", ty.type_name("S"), type::AddressSpace::kPushConstant);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
diff --git a/src/tint/resolver/address_space_validation_test.cc b/src/tint/resolver/address_space_validation_test.cc
index bc6c4a4..b85feeb 100644
--- a/src/tint/resolver/address_space_validation_test.cc
+++ b/src/tint/resolver/address_space_validation_test.cc
@@ -38,7 +38,7 @@
 
 TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_NoAddressSpace_Fail) {
     // type g = ptr<f32>;
-    Alias("g", ty.pointer(Source{{12, 34}}, ty.f32(), ast::AddressSpace::kUndefined));
+    Alias("g", ty.pointer(Source{{12, 34}}, ty.f32(), type::AddressSpace::kUndefined));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: ptr missing address space");
@@ -46,7 +46,7 @@
 
 TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_FunctionAddressSpace_Fail) {
     // var<private> g : f32;
-    GlobalVar(Source{{12, 34}}, "g", ty.f32(), ast::AddressSpace::kFunction);
+    GlobalVar(Source{{12, 34}}, "g", ty.f32(), type::AddressSpace::kFunction);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -56,7 +56,7 @@
 TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Private_RuntimeArray) {
     // var<private> v : array<i32>;
     GlobalVar(Source{{56, 78}}, "v", ty.array(Source{{12, 34}}, ty.i32()),
-              ast::AddressSpace::kPrivate);
+              type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -67,7 +67,7 @@
 TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Private_RuntimeArray) {
     // type t : ptr<private, array<i32>>;
     Alias("t", ty.pointer(Source{{56, 78}}, ty.array(Source{{12, 34}}, ty.i32()),
-                          ast::AddressSpace::kPrivate));
+                          type::AddressSpace::kPrivate));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -79,7 +79,7 @@
     // struct S { m : array<i32> };
     // var<private> v : S;
     Structure("S", utils::Vector{Member(Source{{12, 34}}, "m", ty.array(ty.i32()))});
-    GlobalVar(Source{{56, 78}}, "v", ty.type_name("S"), ast::AddressSpace::kPrivate);
+    GlobalVar(Source{{56, 78}}, "v", ty.type_name("S"), type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -92,7 +92,7 @@
     // struct S { m : array<i32> };
     // type t = ptr<private, S>;
     Structure("S", utils::Vector{Member(Source{{12, 34}}, "m", ty.array(ty.i32()))});
-    Alias("t", ty.pointer(ty.type_name("S"), ast::AddressSpace::kPrivate));
+    Alias("t", ty.pointer(ty.type_name("S"), type::AddressSpace::kPrivate));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -104,7 +104,7 @@
 TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Workgroup_RuntimeArray) {
     // var<workgroup> v : array<i32>;
     GlobalVar(Source{{56, 78}}, "v", ty.array(Source{{12, 34}}, ty.i32()),
-              ast::AddressSpace::kWorkgroup);
+              type::AddressSpace::kWorkgroup);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -114,7 +114,7 @@
 
 TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Workgroup_RuntimeArray) {
     // type t = ptr<workgroup, array<i32>>;
-    Alias("t", ty.pointer(ty.array(Source{{12, 34}}, ty.i32()), ast::AddressSpace::kWorkgroup));
+    Alias("t", ty.pointer(ty.array(Source{{12, 34}}, ty.i32()), type::AddressSpace::kWorkgroup));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -126,7 +126,7 @@
     // struct S { m : array<i32> };
     // var<workgroup> v : S;
     Structure("S", utils::Vector{Member(Source{{12, 34}}, "m", ty.array(ty.i32()))});
-    GlobalVar(Source{{56, 78}}, "v", ty.type_name("S"), ast::AddressSpace::kWorkgroup);
+    GlobalVar(Source{{56, 78}}, "v", ty.type_name("S"), type::AddressSpace::kWorkgroup);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -139,7 +139,7 @@
     // struct S { m : array<i32> };
     // type t = ptr<workgroup, S>;
     Structure("S", utils::Vector{Member(Source{{12, 34}}, "m", ty.array(ty.i32()))});
-    Alias(Source{{56, 78}}, "t", ty.pointer(ty.type_name("S"), ast::AddressSpace::kWorkgroup));
+    Alias(Source{{56, 78}}, "t", ty.pointer(ty.type_name("S"), type::AddressSpace::kWorkgroup));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -150,7 +150,7 @@
 
 TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_Bool) {
     // var<storage> g : bool;
-    GlobalVar(Source{{56, 78}}, "g", ty.bool_(Source{{12, 34}}), ast::AddressSpace::kStorage,
+    GlobalVar(Source{{56, 78}}, "g", ty.bool_(Source{{12, 34}}), type::AddressSpace::kStorage,
               Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
@@ -164,7 +164,7 @@
 TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_Bool) {
     // type t = ptr<storage, bool>;
     Alias(Source{{56, 78}}, "t",
-          ty.pointer(ty.bool_(Source{{12, 34}}), ast::AddressSpace::kStorage));
+          ty.pointer(ty.bool_(Source{{12, 34}}), type::AddressSpace::kStorage));
 
     ASSERT_FALSE(r()->Resolve());
 
@@ -179,7 +179,7 @@
     // @binding(0) @group(0) var<storage, read> g : a;
     Alias("a", ty.bool_());
     GlobalVar(Source{{56, 78}}, "g", ty.type_name(Source{{12, 34}}, "a"),
-              ast::AddressSpace::kStorage, Binding(0_a), Group(0_a));
+              type::AddressSpace::kStorage, Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
 
@@ -194,7 +194,7 @@
     // type t = ptr<storage, a>;
     Alias("a", ty.bool_());
     Alias(Source{{56, 78}}, "t",
-          ty.pointer(ty.type_name(Source{{12, 34}}, "a"), ast::AddressSpace::kStorage));
+          ty.pointer(ty.type_name(Source{{12, 34}}, "a"), type::AddressSpace::kStorage));
 
     ASSERT_FALSE(r()->Resolve());
 
@@ -207,8 +207,8 @@
 TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_Pointer) {
     // var<storage> g : ptr<private, f32>;
     GlobalVar(Source{{56, 78}}, "g",
-              ty.pointer(Source{{12, 34}}, ty.f32(), ast::AddressSpace::kPrivate),
-              ast::AddressSpace::kStorage, Binding(0_a), Group(0_a));
+              ty.pointer(Source{{12, 34}}, ty.f32(), type::AddressSpace::kPrivate),
+              type::AddressSpace::kStorage, Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
 
@@ -221,8 +221,8 @@
 TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_Pointer) {
     // type t = ptr<storage, ptr<private, f32>>;
     Alias("t", ty.pointer(Source{{56, 78}},
-                          ty.pointer(Source{{12, 34}}, ty.f32(), ast::AddressSpace::kPrivate),
-                          ast::AddressSpace::kStorage));
+                          ty.pointer(Source{{12, 34}}, ty.f32(), type::AddressSpace::kPrivate),
+                          type::AddressSpace::kStorage));
 
     ASSERT_FALSE(r()->Resolve());
 
@@ -234,14 +234,14 @@
 
 TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_IntScalar) {
     // var<storage> g : i32;
-    GlobalVar("g", ty.i32(), ast::AddressSpace::kStorage, Binding(0_a), Group(0_a));
+    GlobalVar("g", ty.i32(), type::AddressSpace::kStorage, Binding(0_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_IntScalar) {
     // type t = ptr<storage, i32;
-    Alias("t", ty.pointer(ty.i32(), ast::AddressSpace::kStorage));
+    Alias("t", ty.pointer(ty.i32(), type::AddressSpace::kStorage));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -251,7 +251,7 @@
     // var<storage> g : f16;
     Enable(ast::Extension::kF16);
 
-    GlobalVar("g", ty.f16(), ast::AddressSpace::kStorage, Binding(0_a), Group(0_a));
+    GlobalVar("g", ty.f16(), type::AddressSpace::kStorage, Binding(0_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -261,7 +261,7 @@
     // type t = ptr<storage, f16>;
     Enable(ast::Extension::kF16);
 
-    Alias("t", ty.pointer(ty.f16(), ast::AddressSpace::kStorage));
+    Alias("t", ty.pointer(ty.f16(), type::AddressSpace::kStorage));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -273,7 +273,7 @@
     Enable(ast::Extension::kF16);
 
     Alias("a", ty.f16());
-    GlobalVar("g", ty.type_name("a"), ast::AddressSpace::kStorage, Binding(0_a), Group(0_a));
+    GlobalVar("g", ty.type_name("a"), type::AddressSpace::kStorage, Binding(0_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -285,21 +285,21 @@
     Enable(ast::Extension::kF16);
 
     Alias("a", ty.f16());
-    Alias("t", ty.pointer(ty.type_name("a"), ast::AddressSpace::kStorage));
+    Alias("t", ty.pointer(ty.type_name("a"), type::AddressSpace::kStorage));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_VectorF32) {
     // var<storage> g : vec4<f32>;
-    GlobalVar("g", ty.vec4<f32>(), ast::AddressSpace::kStorage, Binding(0_a), Group(0_a));
+    GlobalVar("g", ty.vec4<f32>(), type::AddressSpace::kStorage, Binding(0_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_VectorF32) {
     // type t = ptr<storage, vec4<f32>>;
-    Alias("t", ty.pointer(ty.vec4<f32>(), ast::AddressSpace::kStorage));
+    Alias("t", ty.pointer(ty.vec4<f32>(), type::AddressSpace::kStorage));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -307,7 +307,7 @@
 TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_VectorF16) {
     // var<storage> g : vec4<f16>;
     Enable(ast::Extension::kF16);
-    GlobalVar("g", ty.vec(ty.f16(), 4u), ast::AddressSpace::kStorage, Binding(0_a), Group(0_a));
+    GlobalVar("g", ty.vec(ty.f16(), 4u), type::AddressSpace::kStorage, Binding(0_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -315,7 +315,7 @@
 TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_VectorF16) {
     // type t = ptr<storage, vec4<f16>>;
     Enable(ast::Extension::kF16);
-    Alias("t", ty.pointer(ty.vec(ty.f16(), 4u), ast::AddressSpace::kStorage));
+    Alias("t", ty.pointer(ty.vec(ty.f16(), 4u), type::AddressSpace::kStorage));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -324,8 +324,8 @@
     // struct S{ a : f32 };
     // var<storage, read> g : array<S, 3u>;
     Structure("S", utils::Vector{Member("a", ty.f32())});
-    GlobalVar("g", ty.array(ty.type_name("S"), 3_u), ast::AddressSpace::kStorage,
-              ast::Access::kRead, Binding(0_a), Group(0_a));
+    GlobalVar("g", ty.array(ty.type_name("S"), 3_u), type::AddressSpace::kStorage,
+              type::Access::kRead, Binding(0_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -334,7 +334,7 @@
     // struct S{ a : f32 };
     // type t = ptr<storage, array<S, 3u>>;
     Structure("S", utils::Vector{Member("a", ty.f32())});
-    Alias("t", ty.pointer(ty.array(ty.type_name("S"), 3_u), ast::AddressSpace::kStorage));
+    Alias("t", ty.pointer(ty.array(ty.type_name("S"), 3_u), type::AddressSpace::kStorage));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -346,8 +346,8 @@
     Enable(ast::Extension::kF16);
 
     Structure("S", utils::Vector{Member("a", ty.f16())});
-    GlobalVar("g", ty.array(ty.type_name("S"), 3_u), ast::AddressSpace::kStorage,
-              ast::Access::kRead, Binding(0_a), Group(0_a));
+    GlobalVar("g", ty.array(ty.type_name("S"), 3_u), type::AddressSpace::kStorage,
+              type::Access::kRead, Binding(0_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -359,8 +359,8 @@
     Enable(ast::Extension::kF16);
 
     Structure("S", utils::Vector{Member("a", ty.f16())});
-    Alias("t", ty.pointer(ty.array(ty.type_name("S"), 3_u), ast::AddressSpace::kStorage,
-                          ast::Access::kRead));
+    Alias("t", ty.pointer(ty.array(ty.type_name("S"), 3_u), type::AddressSpace::kStorage,
+                          type::Access::kRead));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -369,8 +369,8 @@
     // struct S { x : i32 };
     // var<storage, read> g : S;
     Structure("S", utils::Vector{Member("x", ty.i32())});
-    GlobalVar("g", ty.type_name("S"), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
-              Group(0_a));
+    GlobalVar("g", ty.type_name("S"), type::AddressSpace::kStorage, type::Access::kRead,
+              Binding(0_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -379,7 +379,7 @@
     // struct S { x : i32 };
     // type t = ptr<storage, read, S>;
     Structure("S", utils::Vector{Member("x", ty.i32())});
-    Alias("t", ty.pointer(ty.type_name("S"), ast::AddressSpace::kStorage, ast::Access::kRead));
+    Alias("t", ty.pointer(ty.type_name("S"), type::AddressSpace::kStorage, type::Access::kRead));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -391,7 +391,7 @@
     Structure("S", utils::Vector{Member("x", ty.i32())});
     Alias("a1", ty.type_name("S"));
     Alias("a2", ty.type_name("a1"));
-    GlobalVar("g", ty.type_name("a2"), ast::AddressSpace::kStorage, ast::Access::kRead,
+    GlobalVar("g", ty.type_name("a2"), type::AddressSpace::kStorage, type::Access::kRead,
               Binding(0_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -404,7 +404,7 @@
     Structure("S", utils::Vector{Member("x", ty.i32())});
     Alias("a1", ty.type_name("S"));
     Alias("a2", ty.type_name("a1"));
-    Alias("t", ty.pointer(ty.type_name("a2"), ast::AddressSpace::kStorage, ast::Access::kRead));
+    Alias("t", ty.pointer(ty.type_name("a2"), type::AddressSpace::kStorage, type::Access::kRead));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -415,8 +415,8 @@
     Enable(ast::Extension::kF16);
 
     Structure("S", utils::Vector{Member("x", ty.f16())});
-    GlobalVar("g", ty.type_name("S"), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
-              Group(0_a));
+    GlobalVar("g", ty.type_name("S"), type::AddressSpace::kStorage, type::Access::kRead,
+              Binding(0_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -427,7 +427,7 @@
     Enable(ast::Extension::kF16);
 
     Structure("S", utils::Vector{Member("x", ty.f16())});
-    Alias("t", ty.pointer(ty.type_name("S"), ast::AddressSpace::kStorage, ast::Access::kRead));
+    Alias("t", ty.pointer(ty.type_name("S"), type::AddressSpace::kStorage, type::Access::kRead));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -441,7 +441,7 @@
     Structure("S", utils::Vector{Member("x", ty.f16())});
     Alias("a1", ty.type_name("S"));
     Alias("a2", ty.type_name("a1"));
-    GlobalVar("g", ty.type_name("a2"), ast::AddressSpace::kStorage, ast::Access::kRead,
+    GlobalVar("g", ty.type_name("a2"), type::AddressSpace::kStorage, type::Access::kRead,
               Binding(0_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -456,14 +456,14 @@
     Structure("S", utils::Vector{Member("x", ty.f16())});
     Alias("a1", ty.type_name("S"));
     Alias("a2", ty.type_name("a1"));
-    Alias("g", ty.pointer(ty.type_name("a2"), ast::AddressSpace::kStorage, ast::Access::kRead));
+    Alias("g", ty.pointer(ty.type_name("a2"), type::AddressSpace::kStorage, type::Access::kRead));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_NotStorage_AccessMode) {
     // var<private, read> g : a;
-    GlobalVar(Source{{12, 34}}, "g", ty.i32(), ast::AddressSpace::kPrivate, ast::Access::kRead);
+    GlobalVar(Source{{12, 34}}, "g", ty.i32(), type::AddressSpace::kPrivate, type::Access::kRead);
 
     ASSERT_FALSE(r()->Resolve());
 
@@ -474,8 +474,8 @@
 
 TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_NotStorage_AccessMode) {
     // type t = ptr<private, read, a>;
-    Alias("t",
-          ty.pointer(Source{{12, 34}}, ty.i32(), ast::AddressSpace::kPrivate, ast::Access::kRead));
+    Alias("t", ty.pointer(Source{{12, 34}}, ty.i32(), type::AddressSpace::kPrivate,
+                          type::Access::kRead));
 
     ASSERT_FALSE(r()->Resolve());
 
@@ -486,7 +486,7 @@
 
 TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_ReadAccessMode) {
     // @group(0) @binding(0) var<storage, read> a : i32;
-    GlobalVar("a", ty.i32(), ast::AddressSpace::kStorage, ast::Access::kRead, Group(0_a),
+    GlobalVar("a", ty.i32(), type::AddressSpace::kStorage, type::Access::kRead, Group(0_a),
               Binding(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -494,14 +494,14 @@
 
 TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_ReadAccessMode) {
     // type t = ptr<storage, read, i32>;
-    Alias("t", ty.pointer(ty.i32(), ast::AddressSpace::kStorage, ast::Access::kRead));
+    Alias("t", ty.pointer(ty.i32(), type::AddressSpace::kStorage, type::Access::kRead));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_ReadWriteAccessMode) {
     // @group(0) @binding(0) var<storage, read_write> a : i32;
-    GlobalVar("a", ty.i32(), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Group(0_a),
+    GlobalVar("a", ty.i32(), type::AddressSpace::kStorage, type::Access::kReadWrite, Group(0_a),
               Binding(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -509,14 +509,14 @@
 
 TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_ReadWriteAccessMode) {
     // type t = ptr<storage, read_write, i32>;
-    Alias("t", ty.pointer(ty.i32(), ast::AddressSpace::kStorage, ast::Access::kReadWrite));
+    Alias("t", ty.pointer(ty.i32(), type::AddressSpace::kStorage, type::Access::kReadWrite));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_Storage_WriteAccessMode) {
     // @group(0) @binding(0) var<storage, read_write> a : i32;
-    GlobalVar(Source{{12, 34}}, "a", ty.i32(), ast::AddressSpace::kStorage, ast::Access::kWrite,
+    GlobalVar(Source{{12, 34}}, "a", ty.i32(), type::AddressSpace::kStorage, type::Access::kWrite,
               Group(0_a), Binding(0_a));
 
     ASSERT_FALSE(r()->Resolve());
@@ -527,8 +527,8 @@
 
 TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_Storage_WriteAccessMode) {
     // type t = ptr<storage, read_write, i32>;
-    Alias("t",
-          ty.pointer(Source{{12, 34}}, ty.i32(), ast::AddressSpace::kStorage, ast::Access::kWrite));
+    Alias("t", ty.pointer(Source{{12, 34}}, ty.i32(), type::AddressSpace::kStorage,
+                          type::Access::kWrite));
 
     ASSERT_FALSE(r()->Resolve());
 
@@ -543,7 +543,7 @@
     Structure("S",
               utils::Vector{Member(Source{{56, 78}}, "m", ty.array(Source{{12, 34}}, ty.i32()))});
 
-    GlobalVar(Source{{90, 12}}, "svar", ty.type_name("S"), ast::AddressSpace::kUniform,
+    GlobalVar(Source{{90, 12}}, "svar", ty.type_name("S"), type::AddressSpace::kUniform,
               Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
@@ -560,7 +560,7 @@
     Structure("S",
               utils::Vector{Member(Source{{56, 78}}, "m", ty.array(Source{{12, 34}}, ty.i32()))});
 
-    Alias("t", ty.pointer(Source{{90, 12}}, ty.type_name("S"), ast::AddressSpace::kUniform));
+    Alias("t", ty.pointer(Source{{90, 12}}, ty.type_name("S"), type::AddressSpace::kUniform));
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -575,7 +575,7 @@
 
 TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_UniformBufferBool) {
     // var<uniform> g : bool;
-    GlobalVar(Source{{56, 78}}, "g", ty.bool_(Source{{12, 34}}), ast::AddressSpace::kUniform,
+    GlobalVar(Source{{56, 78}}, "g", ty.bool_(Source{{12, 34}}), type::AddressSpace::kUniform,
               Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
@@ -589,7 +589,7 @@
 TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_UniformBufferBool) {
     // type t = ptr<uniform, bool>;
     Alias("t",
-          ty.pointer(Source{{56, 78}}, ty.bool_(Source{{12, 34}}), ast::AddressSpace::kUniform));
+          ty.pointer(Source{{56, 78}}, ty.bool_(Source{{12, 34}}), type::AddressSpace::kUniform));
 
     ASSERT_FALSE(r()->Resolve());
 
@@ -604,7 +604,7 @@
     // var<uniform> g : a;
     Alias("a", ty.bool_());
     GlobalVar(Source{{56, 78}}, "g", ty.type_name(Source{{12, 34}}, "a"),
-              ast::AddressSpace::kUniform, Binding(0_a), Group(0_a));
+              type::AddressSpace::kUniform, Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
 
@@ -619,7 +619,7 @@
     // type t = ptr<uniform, a>;
     Alias("a", ty.bool_());
     Alias("t", ty.pointer(Source{{56, 78}}, ty.type_name(Source{{12, 34}}, "a"),
-                          ast::AddressSpace::kUniform));
+                          type::AddressSpace::kUniform));
 
     ASSERT_FALSE(r()->Resolve());
 
@@ -632,8 +632,8 @@
 TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_UniformPointer) {
     // var<uniform> g : ptr<private, f32>;
     GlobalVar(Source{{56, 78}}, "g",
-              ty.pointer(Source{{12, 34}}, ty.f32(), ast::AddressSpace::kPrivate),
-              ast::AddressSpace::kUniform, Binding(0_a), Group(0_a));
+              ty.pointer(Source{{12, 34}}, ty.f32(), type::AddressSpace::kPrivate),
+              type::AddressSpace::kUniform, Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
 
@@ -646,8 +646,8 @@
 TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_UniformPointer) {
     // type t = ptr<uniform, ptr<private, f32>>;
     Alias("t", ty.pointer(Source{{56, 78}},
-                          ty.pointer(Source{{12, 34}}, ty.f32(), ast::AddressSpace::kPrivate),
-                          ast::AddressSpace::kUniform));
+                          ty.pointer(Source{{12, 34}}, ty.f32(), type::AddressSpace::kPrivate),
+                          type::AddressSpace::kUniform));
 
     ASSERT_FALSE(r()->Resolve());
 
@@ -659,7 +659,7 @@
 
 TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_UniformBufferIntScalar) {
     // var<uniform> g : i32;
-    GlobalVar(Source{{56, 78}}, "g", ty.i32(), ast::AddressSpace::kUniform, Binding(0_a),
+    GlobalVar(Source{{56, 78}}, "g", ty.i32(), type::AddressSpace::kUniform, Binding(0_a),
               Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -667,7 +667,7 @@
 
 TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_UniformBufferIntScalar) {
     // type t = ptr<uniform, i32>;
-    Alias("t", ty.pointer(ty.i32(), ast::AddressSpace::kUniform));
+    Alias("t", ty.pointer(ty.i32(), type::AddressSpace::kUniform));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -677,7 +677,7 @@
     // var<uniform> g : f16;
     Enable(ast::Extension::kF16);
 
-    GlobalVar("g", ty.f16(), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a));
+    GlobalVar("g", ty.f16(), type::AddressSpace::kUniform, Binding(0_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -687,21 +687,21 @@
     // type t = ptr<uniform, f16>;
     Enable(ast::Extension::kF16);
 
-    Alias("t", ty.pointer(ty.f16(), ast::AddressSpace::kUniform));
+    Alias("t", ty.pointer(ty.f16(), type::AddressSpace::kUniform));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_UniformBufferVectorF32) {
     // var<uniform> g : vec4<f32>;
-    GlobalVar("g", ty.vec4<f32>(), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a));
+    GlobalVar("g", ty.vec4<f32>(), type::AddressSpace::kUniform, Binding(0_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_UniformBufferVectorF32) {
     // type t = ptr<uniform, vec4<f32>>;
-    Alias("t", ty.pointer(ty.vec4<f32>(), ast::AddressSpace::kUniform));
+    Alias("t", ty.pointer(ty.vec4<f32>(), type::AddressSpace::kUniform));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -711,7 +711,7 @@
     // var<uniform> g : vec4<f16>;
     Enable(ast::Extension::kF16);
 
-    GlobalVar("g", ty.vec4<f16>(), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a));
+    GlobalVar("g", ty.vec4<f16>(), type::AddressSpace::kUniform, Binding(0_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -721,7 +721,7 @@
     // type t = ptr<uniform, vec4<f16>>;
     Enable(ast::Extension::kF16);
 
-    Alias("t", ty.pointer(ty.vec4<f16>(), ast::AddressSpace::kUniform));
+    Alias("t", ty.pointer(ty.vec4<f16>(), type::AddressSpace::kUniform));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -732,7 +732,7 @@
     // }
     // var<uniform> g : array<S, 3u>;
     Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{MemberSize(16_a)})});
-    GlobalVar("g", ty.array(ty.type_name("S"), 3_u), ast::AddressSpace::kUniform, Binding(0_a),
+    GlobalVar("g", ty.array(ty.type_name("S"), 3_u), type::AddressSpace::kUniform, Binding(0_a),
               Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -744,7 +744,7 @@
     // }
     // type t = ptr<uniform, array<S, 3u>>;
     Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{MemberSize(16_a)})});
-    Alias("t", ty.pointer(ty.array(ty.type_name("S"), 3_u), ast::AddressSpace::kUniform));
+    Alias("t", ty.pointer(ty.array(ty.type_name("S"), 3_u), type::AddressSpace::kUniform));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -758,7 +758,7 @@
     Enable(ast::Extension::kF16);
 
     Structure("S", utils::Vector{Member("a", ty.f16(), utils::Vector{MemberSize(16_a)})});
-    GlobalVar("g", ty.array(ty.type_name("S"), 3_u), ast::AddressSpace::kUniform, Binding(0_a),
+    GlobalVar("g", ty.array(ty.type_name("S"), 3_u), type::AddressSpace::kUniform, Binding(0_a),
               Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -773,7 +773,7 @@
     Enable(ast::Extension::kF16);
 
     Structure("S", utils::Vector{Member("a", ty.f16(), utils::Vector{MemberSize(16_a)})});
-    Alias("t", ty.pointer(ty.array(ty.type_name("S"), 3_u), ast::AddressSpace::kUniform));
+    Alias("t", ty.pointer(ty.array(ty.type_name("S"), 3_u), type::AddressSpace::kUniform));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -782,7 +782,7 @@
     // struct S { x : i32 };
     // var<uniform> g : S;
     Structure("S", utils::Vector{Member("x", ty.i32())});
-    GlobalVar("g", ty.type_name("S"), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a));
+    GlobalVar("g", ty.type_name("S"), type::AddressSpace::kUniform, Binding(0_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -791,7 +791,7 @@
     // struct S { x : i32 };
     // type t = ptr<uniform, S>;
     Structure("S", utils::Vector{Member("x", ty.i32())});
-    Alias("t", ty.pointer(ty.type_name("S"), ast::AddressSpace::kUniform));
+    Alias("t", ty.pointer(ty.type_name("S"), type::AddressSpace::kUniform));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -802,7 +802,7 @@
     // var<uniform> g : a1;
     Structure("S", utils::Vector{Member("x", ty.i32())});
     Alias("a1", ty.type_name("S"));
-    GlobalVar("g", ty.type_name("a1"), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a));
+    GlobalVar("g", ty.type_name("a1"), type::AddressSpace::kUniform, Binding(0_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -813,7 +813,7 @@
     // type t = ptr<uniform, a1>;
     Structure("S", utils::Vector{Member("x", ty.i32())});
     Alias("a1", ty.type_name("S"));
-    Alias("t", ty.pointer(ty.type_name("a1"), ast::AddressSpace::kUniform));
+    Alias("t", ty.pointer(ty.type_name("a1"), type::AddressSpace::kUniform));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -825,7 +825,7 @@
     Enable(ast::Extension::kF16);
 
     Structure("S", utils::Vector{Member("x", ty.f16())});
-    GlobalVar("g", ty.type_name("S"), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a));
+    GlobalVar("g", ty.type_name("S"), type::AddressSpace::kUniform, Binding(0_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -837,7 +837,7 @@
     Enable(ast::Extension::kF16);
 
     Structure("S", utils::Vector{Member("x", ty.f16())});
-    Alias("t", ty.pointer(ty.type_name("S"), ast::AddressSpace::kUniform));
+    Alias("t", ty.pointer(ty.type_name("S"), type::AddressSpace::kUniform));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -851,7 +851,7 @@
 
     Structure("S", utils::Vector{Member("x", ty.f16())});
     Alias("a1", ty.type_name("S"));
-    GlobalVar("g", ty.type_name("a1"), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a));
+    GlobalVar("g", ty.type_name("a1"), type::AddressSpace::kUniform, Binding(0_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -865,7 +865,7 @@
 
     Structure("S", utils::Vector{Member("x", ty.f16())});
     Alias("a1", ty.type_name("S"));
-    Alias("t", ty.pointer(ty.type_name("a1"), ast::AddressSpace::kUniform));
+    Alias("t", ty.pointer(ty.type_name("a1"), type::AddressSpace::kUniform));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -874,7 +874,7 @@
     // enable chromium_experimental_push_constant;
     // var<push_constant> g : bool;
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
-    GlobalVar(Source{{56, 78}}, "g", ty.bool_(Source{{12, 34}}), ast::AddressSpace::kPushConstant);
+    GlobalVar(Source{{56, 78}}, "g", ty.bool_(Source{{12, 34}}), type::AddressSpace::kPushConstant);
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -888,7 +888,7 @@
     // type t = ptr<push_constant, bool>;
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
     Alias(Source{{56, 78}}, "t",
-          ty.pointer(ty.bool_(Source{{12, 34}}), ast::AddressSpace::kPushConstant));
+          ty.pointer(ty.bool_(Source{{12, 34}}), type::AddressSpace::kPushConstant));
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -903,7 +903,7 @@
     // var<push_constant> g : f16;
     Enable(ast::Extension::kF16);
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
-    GlobalVar("g", ty.f16(Source{{56, 78}}), ast::AddressSpace::kPushConstant);
+    GlobalVar("g", ty.f16(Source{{56, 78}}), type::AddressSpace::kPushConstant);
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -916,7 +916,7 @@
     // type t = ptr<push_constant, f16>;
     Enable(ast::Extension::kF16);
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
-    Alias("t", ty.pointer(ty.f16(Source{{56, 78}}), ast::AddressSpace::kPushConstant));
+    Alias("t", ty.pointer(ty.f16(Source{{56, 78}}), type::AddressSpace::kPushConstant));
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -928,8 +928,8 @@
     // var<push_constant> g : ptr<private, f32>;
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
     GlobalVar(Source{{56, 78}}, "g",
-              ty.pointer(Source{{12, 34}}, ty.f32(), ast::AddressSpace::kPrivate),
-              ast::AddressSpace::kPushConstant);
+              ty.pointer(Source{{12, 34}}, ty.f32(), type::AddressSpace::kPrivate),
+              type::AddressSpace::kPushConstant);
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -943,8 +943,8 @@
     // type t = ptr<push_constant, ptr<private, f32>>;
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
     Alias(Source{{56, 78}}, "t",
-          ty.pointer(ty.pointer(Source{{12, 34}}, ty.f32(), ast::AddressSpace::kPrivate),
-                     ast::AddressSpace::kPushConstant));
+          ty.pointer(ty.pointer(Source{{12, 34}}, ty.f32(), type::AddressSpace::kPrivate),
+                     type::AddressSpace::kPushConstant));
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -957,7 +957,7 @@
     // enable chromium_experimental_push_constant;
     // var<push_constant> g : i32;
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
-    GlobalVar("g", ty.i32(), ast::AddressSpace::kPushConstant);
+    GlobalVar("g", ty.i32(), type::AddressSpace::kPushConstant);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -966,7 +966,7 @@
     // enable chromium_experimental_push_constant;
     // type t = ptr<push_constant, i32>;
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
-    Alias("t", ty.pointer(ty.i32(), ast::AddressSpace::kPushConstant));
+    Alias("t", ty.pointer(ty.i32(), type::AddressSpace::kPushConstant));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -975,7 +975,7 @@
     // enable chromium_experimental_push_constant;
     // var<push_constant> g : vec4<f32>;
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
-    GlobalVar("g", ty.vec4<f32>(), ast::AddressSpace::kPushConstant);
+    GlobalVar("g", ty.vec4<f32>(), type::AddressSpace::kPushConstant);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -984,7 +984,7 @@
     // enable chromium_experimental_push_constant;
     // var<push_constant> g : vec4<f32>;
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
-    Alias("t", ty.pointer(ty.vec4<f32>(), ast::AddressSpace::kPushConstant));
+    Alias("t", ty.pointer(ty.vec4<f32>(), type::AddressSpace::kPushConstant));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -995,7 +995,7 @@
     // var<push_constant> g : array<S, 3u>;
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
     Structure("S", utils::Vector{Member("a", ty.f32())});
-    GlobalVar("g", ty.array(ty.type_name("S"), 3_u), ast::AddressSpace::kPushConstant);
+    GlobalVar("g", ty.array(ty.type_name("S"), 3_u), type::AddressSpace::kPushConstant);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -1006,7 +1006,7 @@
     // type t = ptr<push_constant, array<S, 3u>>;
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
     Structure("S", utils::Vector{Member("a", ty.f32())});
-    Alias("t", ty.pointer(ty.array(ty.type_name("S"), 3_u), ast::AddressSpace::kPushConstant));
+    Alias("t", ty.pointer(ty.array(ty.type_name("S"), 3_u), type::AddressSpace::kPushConstant));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
diff --git a/src/tint/resolver/alias_analysis_test.cc b/src/tint/resolver/alias_analysis_test.cc
index 490f54c..db78d64 100644
--- a/src/tint/resolver/alias_analysis_test.cc
+++ b/src/tint/resolver/alias_analysis_test.cc
@@ -35,19 +35,19 @@
 //   target(&v1, aliased ? &v1 : &v2);
 // }
 struct TwoPointerConfig {
-    ast::AddressSpace address_space;  // The address space for the pointers.
+    type::AddressSpace address_space;  // The address space for the pointers.
     bool aliased;                     // Whether the pointers alias or not.
 };
 class TwoPointers : public ResolverTestWithParam<TwoPointerConfig> {
   protected:
     void SetUp() override {
         utils::Vector<const ast::Statement*, 4> body;
-        if (GetParam().address_space == ast::AddressSpace::kFunction) {
+        if (GetParam().address_space == type::AddressSpace::kFunction) {
             body.Push(Decl(Var("v1", ty.i32())));
             body.Push(Decl(Var("v2", ty.i32())));
         } else {
-            GlobalVar("v1", ast::AddressSpace::kPrivate, ty.i32());
-            GlobalVar("v2", ast::AddressSpace::kPrivate, ty.i32());
+            GlobalVar("v1", type::AddressSpace::kPrivate, ty.i32());
+            GlobalVar("v2", type::AddressSpace::kPrivate, ty.i32());
         }
         body.Push(CallStmt(Call("target", AddressOf(Source{{12, 34}}, "v1"),
                                 AddressOf(Source{{56, 78}}, GetParam().aliased ? "v1" : "v2"))));
@@ -190,10 +190,10 @@
 
 INSTANTIATE_TEST_SUITE_P(ResolverAliasAnalysisTest,
                          TwoPointers,
-                         ::testing::Values(TwoPointerConfig{ast::AddressSpace::kFunction, false},
-                                           TwoPointerConfig{ast::AddressSpace::kFunction, true},
-                                           TwoPointerConfig{ast::AddressSpace::kPrivate, false},
-                                           TwoPointerConfig{ast::AddressSpace::kPrivate, true}),
+                         ::testing::Values(TwoPointerConfig{type::AddressSpace::kFunction, false},
+                                           TwoPointerConfig{type::AddressSpace::kFunction, true},
+                                           TwoPointerConfig{type::AddressSpace::kPrivate, false},
+                                           TwoPointerConfig{type::AddressSpace::kPrivate, true}),
                          [](const ::testing::TestParamInfo<TwoPointers::ParamType>& p) {
                              std::stringstream ss;
                              ss << (p.param.aliased ? "Aliased" : "Unaliased") << "_"
@@ -214,8 +214,8 @@
 class OnePointerOneModuleScope : public ResolverTestWithParam<bool> {
   protected:
     void SetUp() override {
-        GlobalVar("global_1", ast::AddressSpace::kPrivate, ty.i32());
-        GlobalVar("global_2", ast::AddressSpace::kPrivate, ty.i32());
+        GlobalVar("global_1", type::AddressSpace::kPrivate, ty.i32());
+        GlobalVar("global_2", type::AddressSpace::kPrivate, ty.i32());
         Func("caller", utils::Empty, ty.void_(),
              utils::Vector{
                  CallStmt(Call("target",
@@ -226,7 +226,7 @@
     void Run(utils::Vector<const ast::Statement*, 4>&& body, const char* err = nullptr) {
         Func("target",
              utils::Vector<const ast::Parameter*, 4>{
-                 Param("p1", ty.pointer<i32>(ast::AddressSpace::kPrivate)),
+                 Param("p1", ty.pointer<i32>(type::AddressSpace::kPrivate)),
              },
              ty.void_(), std::move(body));
         if (GetParam() && err) {
@@ -295,7 +295,7 @@
     // f1(p1);
     Func("f2",
          utils::Vector<const ast::Parameter*, 4>{
-             Param("p1", ty.pointer<i32>(ast::AddressSpace::kPrivate)),
+             Param("p1", ty.pointer<i32>(type::AddressSpace::kPrivate)),
          },
          ty.void_(),
          utils::Vector{
@@ -303,7 +303,7 @@
          });
     Func("f1",
          utils::Vector<const ast::Parameter*, 4>{
-             Param("p1", ty.pointer<i32>(ast::AddressSpace::kPrivate)),
+             Param("p1", ty.pointer<i32>(type::AddressSpace::kPrivate)),
          },
          ty.void_(),
          utils::Vector{
@@ -330,7 +330,7 @@
     // f1(p1);
     Func("f2",
          utils::Vector<const ast::Parameter*, 4>{
-             Param("p1", ty.pointer<i32>(ast::AddressSpace::kPrivate)),
+             Param("p1", ty.pointer<i32>(type::AddressSpace::kPrivate)),
          },
          ty.void_(),
          utils::Vector{
@@ -339,7 +339,7 @@
          });
     Func("f1",
          utils::Vector<const ast::Parameter*, 4>{
-             Param("p1", ty.pointer<i32>(ast::AddressSpace::kPrivate)),
+             Param("p1", ty.pointer<i32>(type::AddressSpace::kPrivate)),
          },
          ty.void_(),
          utils::Vector{
@@ -365,7 +365,7 @@
     // f1(p1);
     Func("f2",
          utils::Vector<const ast::Parameter*, 4>{
-             Param("p1", ty.pointer<i32>(ast::AddressSpace::kPrivate)),
+             Param("p1", ty.pointer<i32>(type::AddressSpace::kPrivate)),
          },
          ty.void_(),
          utils::Vector{
@@ -373,7 +373,7 @@
          });
     Func("f1",
          utils::Vector<const ast::Parameter*, 4>{
-             Param("p1", ty.pointer<i32>(ast::AddressSpace::kPrivate)),
+             Param("p1", ty.pointer<i32>(type::AddressSpace::kPrivate)),
          },
          ty.void_(),
          utils::Vector{
@@ -400,7 +400,7 @@
     // f1(p1);
     Func("f2",
          utils::Vector{
-             Param("p1", ty.pointer<i32>(ast::AddressSpace::kPrivate)),
+             Param("p1", ty.pointer<i32>(type::AddressSpace::kPrivate)),
          },
          ty.void_(),
          utils::Vector{
@@ -409,7 +409,7 @@
          });
     Func("f1",
          utils::Vector{
-             Param("p1", ty.pointer<i32>(ast::AddressSpace::kPrivate)),
+             Param("p1", ty.pointer<i32>(type::AddressSpace::kPrivate)),
          },
          ty.void_(),
          utils::Vector{
@@ -435,7 +435,7 @@
     // f2();
     Func("f1",
          utils::Vector{
-             Param("p1", ty.pointer<i32>(ast::AddressSpace::kPrivate)),
+             Param("p1", ty.pointer<i32>(type::AddressSpace::kPrivate)),
          },
          ty.void_(),
          utils::Vector{
@@ -487,8 +487,8 @@
     void Run(const ast::Statement* stmt, const char* err = nullptr) {
         Func("target",
              utils::Vector{
-                 Param("p1", ty.pointer<i32>(ast::AddressSpace::kFunction)),
-                 Param("p2", ty.pointer<i32>(ast::AddressSpace::kFunction)),
+                 Param("p1", ty.pointer<i32>(type::AddressSpace::kFunction)),
+                 Param("p2", ty.pointer<i32>(type::AddressSpace::kFunction)),
              },
              ty.void_(),
              utils::Vector{
@@ -531,7 +531,7 @@
 TEST_P(Use, Read_CompoundAssignment_RHS) {
     // var<private> global : i32;
     // global += *p2;
-    GlobalVar("global", ast::AddressSpace::kPrivate, ty.i32());
+    GlobalVar("global", type::AddressSpace::kPrivate, ty.i32());
     Run(CompoundAssign("global", Deref("p2"), ast::BinaryOp::kAdd),
         R"(56:78 warning: invalid aliased pointer argument
 12:34 note: aliases with another argument passed here)");
@@ -578,7 +578,7 @@
 TEST_P(Use, Read_IndexAccessor) {
     // var<private> data : array<f32, 4>;
     // _ = data[*p2];
-    GlobalVar("data", ast::AddressSpace::kPrivate, ty.array<f32, 4>());
+    GlobalVar("data", type::AddressSpace::kPrivate, ty.array<f32, 4>());
     Run(Assign(Phony(), IndexAccessor("data", Deref("p2"))),
         R"(56:78 warning: invalid aliased pointer argument
 12:34 note: aliases with another argument passed here)");
@@ -592,7 +592,7 @@
 
 TEST_P(Use, Read_VarInitializer) {
     // var x = *p2;
-    Run(Decl(Var("x", ast::AddressSpace::kFunction, Deref("p2"))),
+    Run(Decl(Var("x", type::AddressSpace::kFunction, Deref("p2"))),
         R"(56:78 warning: invalid aliased pointer argument
 12:34 note: aliases with another argument passed here)");
 }
@@ -602,7 +602,7 @@
     // foo(p2);
     Func("foo",
          utils::Vector{
-             Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction)),
+             Param("p", ty.pointer<i32>(type::AddressSpace::kFunction)),
          },
          ty.i32(),
          utils::Vector{
@@ -659,8 +659,8 @@
     void Run(const ast::Statement* stmt, const char* err = nullptr) {
         Func("target",
              utils::Vector{
-                 Param("p1", ty.pointer<bool>(ast::AddressSpace::kFunction)),
-                 Param("p2", ty.pointer<bool>(ast::AddressSpace::kFunction)),
+                 Param("p1", ty.pointer<bool>(type::AddressSpace::kFunction)),
+                 Param("p2", ty.pointer<bool>(type::AddressSpace::kFunction)),
              },
              ty.void_(),
              utils::Vector{
@@ -724,8 +724,8 @@
     Structure("S", utils::Vector{Member("a", ty.i32())});
     Func("f2",
          utils::Vector{
-             Param("p1", ty.pointer(ty.type_name("S"), ast::AddressSpace::kFunction)),
-             Param("p2", ty.pointer(ty.type_name("S"), ast::AddressSpace::kFunction)),
+             Param("p1", ty.pointer(ty.type_name("S"), type::AddressSpace::kFunction)),
+             Param("p2", ty.pointer(ty.type_name("S"), type::AddressSpace::kFunction)),
          },
          ty.void_(),
          utils::Vector{
@@ -753,8 +753,8 @@
     Structure("S", utils::Vector{Member("a", ty.i32())});
     Func("f2",
          utils::Vector{
-             Param("p1", ty.pointer(ty.type_name("S"), ast::AddressSpace::kFunction)),
-             Param("p2", ty.pointer(ty.type_name("S"), ast::AddressSpace::kFunction)),
+             Param("p1", ty.pointer(ty.type_name("S"), type::AddressSpace::kFunction)),
+             Param("p2", ty.pointer(ty.type_name("S"), type::AddressSpace::kFunction)),
          },
          ty.void_(),
          utils::Vector{
@@ -785,8 +785,8 @@
     Structure("S", utils::Vector{Member("a", ty.i32())});
     Func("f2",
          utils::Vector{
-             Param("p1", ty.pointer(ty.type_name("S"), ast::AddressSpace::kFunction)),
-             Param("p2", ty.pointer(ty.type_name("S"), ast::AddressSpace::kFunction)),
+             Param("p1", ty.pointer(ty.type_name("S"), type::AddressSpace::kFunction)),
+             Param("p2", ty.pointer(ty.type_name("S"), type::AddressSpace::kFunction)),
          },
          ty.void_(),
          utils::Vector{
@@ -816,8 +816,8 @@
     Structure("S", utils::Vector{Member("a", ty.i32())});
     Func("f2",
          utils::Vector{
-             Param("p1", ty.pointer(ty.vec4<f32>(), ast::AddressSpace::kFunction)),
-             Param("p2", ty.pointer(ty.vec4<f32>(), ast::AddressSpace::kFunction)),
+             Param("p1", ty.pointer(ty.vec4<f32>(), type::AddressSpace::kFunction)),
+             Param("p2", ty.pointer(ty.vec4<f32>(), type::AddressSpace::kFunction)),
          },
          ty.void_(),
          utils::Vector{
@@ -848,7 +848,7 @@
     // }
     Func("f1",
          utils::Vector{
-             Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction)),
+             Param("p", ty.pointer<i32>(type::AddressSpace::kFunction)),
          },
          ty.void_(),
          utils::Vector{
@@ -901,7 +901,7 @@
     // }
     Func("f2",
          utils::Vector{
-             Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction)),
+             Param("p", ty.pointer<i32>(type::AddressSpace::kFunction)),
          },
          ty.void_(),
          utils::Vector{
@@ -909,7 +909,7 @@
          });
     Func("f3",
          utils::Vector{
-             Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction)),
+             Param("p", ty.pointer<i32>(type::AddressSpace::kFunction)),
          },
          ty.void_(),
          utils::Vector{
diff --git a/src/tint/resolver/array_accessor_test.cc b/src/tint/resolver/array_accessor_test.cc
index 65fbb83..255d109 100644
--- a/src/tint/resolver/array_accessor_test.cc
+++ b/src/tint/resolver/array_accessor_test.cc
@@ -27,7 +27,7 @@
 using ResolverIndexAccessorTest = ResolverTest;
 
 TEST_F(ResolverIndexAccessorTest, Matrix_Dynamic_F32) {
-    GlobalVar("my_var", ty.mat2x3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_var", ty.mat2x3<f32>(), type::AddressSpace::kPrivate);
     auto* acc = IndexAccessor("my_var", Expr(Source{{12, 34}}, 1_f));
     WrapInFunction(acc);
 
@@ -36,7 +36,7 @@
 }
 
 TEST_F(ResolverIndexAccessorTest, Matrix_Dynamic_Ref) {
-    GlobalVar("my_var", ty.mat2x3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_var", ty.mat2x3<f32>(), type::AddressSpace::kPrivate);
     auto* idx = Var("idx", ty.i32(), Construct(ty.i32()));
     auto* acc = IndexAccessor("my_var", idx);
     WrapInFunction(Decl(idx), acc);
@@ -50,7 +50,7 @@
 }
 
 TEST_F(ResolverIndexAccessorTest, Matrix_BothDimensions_Dynamic_Ref) {
-    GlobalVar("my_var", ty.mat4x4<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_var", ty.mat4x4<f32>(), type::AddressSpace::kPrivate);
     auto* idx = Var("idx", ty.u32(), Expr(3_u));
     auto* idy = Var("idy", ty.u32(), Expr(2_u));
     auto* acc = IndexAccessor(IndexAccessor("my_var", idx), idy);
@@ -100,7 +100,7 @@
 }
 
 TEST_F(ResolverIndexAccessorTest, Matrix) {
-    GlobalVar("my_var", ty.mat2x3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_var", ty.mat2x3<f32>(), type::AddressSpace::kPrivate);
 
     auto* acc = IndexAccessor("my_var", 1_i);
     WrapInFunction(acc);
@@ -118,7 +118,7 @@
 }
 
 TEST_F(ResolverIndexAccessorTest, Matrix_BothDimensions) {
-    GlobalVar("my_var", ty.mat2x3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_var", ty.mat2x3<f32>(), type::AddressSpace::kPrivate);
 
     auto* acc = IndexAccessor(IndexAccessor("my_var", 0_i), 1_i);
     WrapInFunction(acc);
@@ -135,7 +135,7 @@
 }
 
 TEST_F(ResolverIndexAccessorTest, Vector_F32) {
-    GlobalVar("my_var", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_var", ty.vec3<f32>(), type::AddressSpace::kPrivate);
     auto* acc = IndexAccessor("my_var", Expr(Source{{12, 34}}, 2_f));
     WrapInFunction(acc);
 
@@ -144,7 +144,7 @@
 }
 
 TEST_F(ResolverIndexAccessorTest, Vector_Dynamic_Ref) {
-    GlobalVar("my_var", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_var", ty.vec3<f32>(), type::AddressSpace::kPrivate);
     auto* idx = Var("idx", ty.i32(), Expr(2_i));
     auto* acc = IndexAccessor("my_var", idx);
     WrapInFunction(Decl(idx), acc);
@@ -167,7 +167,7 @@
 }
 
 TEST_F(ResolverIndexAccessorTest, Vector) {
-    GlobalVar("my_var", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_var", ty.vec3<f32>(), type::AddressSpace::kPrivate);
 
     auto* acc = IndexAccessor("my_var", 2_i);
     WrapInFunction(acc);
@@ -184,7 +184,7 @@
 }
 
 TEST_F(ResolverIndexAccessorTest, Array_Literal_i32) {
-    GlobalVar("my_var", ty.array<f32, 3>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_var", ty.array<f32, 3>(), type::AddressSpace::kPrivate);
     auto* acc = IndexAccessor("my_var", 2_i);
     WrapInFunction(acc);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -197,7 +197,7 @@
 }
 
 TEST_F(ResolverIndexAccessorTest, Array_Literal_u32) {
-    GlobalVar("my_var", ty.array<f32, 3>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_var", ty.array<f32, 3>(), type::AddressSpace::kPrivate);
     auto* acc = IndexAccessor("my_var", 2_u);
     WrapInFunction(acc);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -210,7 +210,7 @@
 }
 
 TEST_F(ResolverIndexAccessorTest, Array_Literal_AInt) {
-    GlobalVar("my_var", ty.array<f32, 3>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_var", ty.array<f32, 3>(), type::AddressSpace::kPrivate);
     auto* acc = IndexAccessor("my_var", 2_a);
     WrapInFunction(acc);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -225,7 +225,7 @@
 TEST_F(ResolverIndexAccessorTest, Alias_Array) {
     auto* aary = Alias("myarrty", ty.array<f32, 3>());
 
-    GlobalVar("my_var", ty.Of(aary), ast::AddressSpace::kPrivate);
+    GlobalVar("my_var", ty.Of(aary), type::AddressSpace::kPrivate);
 
     auto* acc = IndexAccessor("my_var", 2_i);
     WrapInFunction(acc);
@@ -316,7 +316,7 @@
     //     let x: f32 = (*p)[idx];
     //     return x;
     // }
-    auto* p = Param("p", ty.pointer(ty.vec4<f32>(), ast::AddressSpace::kFunction));
+    auto* p = Param("p", ty.pointer(ty.vec4<f32>(), type::AddressSpace::kFunction));
     auto* idx = Let("idx", ty.u32(), Construct(ty.u32()));
     auto* star_p = Deref(p);
     auto* acc = IndexAccessor(Source{{12, 34}}, star_p, idx);
@@ -337,7 +337,7 @@
     //     let x: f32 = *p[idx];
     //     return x;
     // }
-    auto* p = Param("p", ty.pointer(ty.vec4<f32>(), ast::AddressSpace::kFunction));
+    auto* p = Param("p", ty.pointer(ty.vec4<f32>(), type::AddressSpace::kFunction));
     auto* idx = Let("idx", ty.u32(), Construct(ty.u32()));
     auto* accessor_expr = IndexAccessor(Source{{12, 34}}, p, idx);
     auto* star_p = Deref(accessor_expr);
diff --git a/src/tint/resolver/assignment_validation_test.cc b/src/tint/resolver/assignment_validation_test.cc
index ce8b314..3fc596d 100644
--- a/src/tint/resolver/assignment_validation_test.cc
+++ b/src/tint/resolver/assignment_validation_test.cc
@@ -17,6 +17,7 @@
 #include "gmock/gmock.h"
 #include "src/tint/resolver/resolver_test_helper.h"
 #include "src/tint/type/storage_texture.h"
+#include "src/tint/type/texture_dimension.h"
 
 using namespace tint::number_suffixes;  // NOLINT
 
@@ -32,7 +33,7 @@
     auto* s = Structure("S", utils::Vector{
                                  Member("m", ty.i32()),
                              });
-    GlobalVar(Source{{12, 34}}, "a", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{12, 34}}, "a", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead,
               Binding(0_a), Group(0_a));
 
     WrapInFunction(Assign(Source{{56, 78}}, MemberAccessor("a", "m"), 1_i));
@@ -192,7 +193,7 @@
     // var a : i32;
     // let b : ptr<function,i32> = &a;
     // *b = 2i;
-    const auto func = ast::AddressSpace::kFunction;
+    const auto func = type::AddressSpace::kFunction;
     WrapInFunction(Var("a", ty.i32(), func, Expr(2_i)),                    //
                    Let("b", ty.pointer<i32>(func), AddressOf(Expr("a"))),  //
                    Assign(Deref("b"), 2_i));
@@ -204,7 +205,7 @@
     // var a : i32;
     // let b : ptr<function,i32> = &a;
     // *b = 2;
-    const auto func = ast::AddressSpace::kFunction;
+    const auto func = type::AddressSpace::kFunction;
     auto* var_a = Var("a", ty.i32(), func, Expr(2_i));
     auto* var_b = Let("b", ty.pointer<i32>(func), AddressOf(Expr("a")));
     WrapInFunction(var_a, var_b, Assign(Deref("b"), 2_a));
@@ -230,8 +231,8 @@
     // a = b;
 
     auto make_type = [&] {
-        return ty.storage_texture(ast::TextureDimension::k1d, ast::TexelFormat::kRgba8Unorm,
-                                  ast::Access::kWrite);
+        return ty.storage_texture(type::TextureDimension::k1d, type::TexelFormat::kRgba8Unorm,
+                                  type::Access::kWrite);
     };
 
     GlobalVar("a", make_type(), Binding(0_a), Group(0_a));
@@ -251,8 +252,8 @@
     auto* s = Structure("S", utils::Vector{
                                  Member("a", ty.atomic(ty.i32())),
                              });
-    GlobalVar(Source{{12, 34}}, "v", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite,
-              Binding(0_a), Group(0_a));
+    GlobalVar(Source{{12, 34}}, "v", ty.Of(s), type::AddressSpace::kStorage,
+              type::Access::kReadWrite, Binding(0_a), Group(0_a));
 
     WrapInFunction(Assign(Source{{56, 78}}, MemberAccessor("v", "a"), MemberAccessor("v", "a")));
 
@@ -268,8 +269,8 @@
     auto* s = Structure("S", utils::Vector{
                                  Member("a", ty.array(ty.f32())),
                              });
-    GlobalVar(Source{{12, 34}}, "v", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite,
-              Binding(0_a), Group(0_a));
+    GlobalVar(Source{{12, 34}}, "v", ty.Of(s), type::AddressSpace::kStorage,
+              type::Access::kReadWrite, Binding(0_a), Group(0_a));
 
     WrapInFunction(Assign(Source{{56, 78}}, MemberAccessor("v", "a"), MemberAccessor("v", "a")));
 
@@ -288,7 +289,7 @@
     auto* s = Structure("S", utils::Vector{
                                  Member("arr", ty.array<i32>()),
                              });
-    GlobalVar("s", ty.Of(s), ast::AddressSpace::kStorage, Group(0_a), Binding(0_a));
+    GlobalVar("s", ty.Of(s), type::AddressSpace::kStorage, Group(0_a), Binding(0_a));
 
     WrapInFunction(Assign(Phony(), Expr(Source{{12, 34}}, "s")));
 
@@ -310,7 +311,7 @@
     auto* s = Structure("S", utils::Vector{
                                  Member("arr", ty.array<i32>()),
                              });
-    GlobalVar("s", ty.Of(s), ast::AddressSpace::kStorage, Group(0_a), Binding(0_a));
+    GlobalVar("s", ty.Of(s), type::AddressSpace::kStorage, Group(0_a), Binding(0_a));
 
     WrapInFunction(Assign(Phony(), MemberAccessor(Source{{12, 34}}, "s", "arr")));
 
@@ -360,12 +361,12 @@
     auto* U = Structure("U", utils::Vector{
                                  Member("i", ty.i32()),
                              });
-    GlobalVar("tex", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), Group(0_a),
+    GlobalVar("tex", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()), Group(0_a),
               Binding(0_a));
     GlobalVar("smp", ty.sampler(ast::SamplerKind::kSampler), Group(0_a), Binding(1_a));
-    GlobalVar("u", ty.Of(U), ast::AddressSpace::kUniform, Group(0_a), Binding(2_a));
-    GlobalVar("s", ty.Of(S), ast::AddressSpace::kStorage, Group(0_a), Binding(3_a));
-    GlobalVar("wg", ty.array<f32, 10>(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("u", ty.Of(U), type::AddressSpace::kUniform, Group(0_a), Binding(2_a));
+    GlobalVar("s", ty.Of(S), type::AddressSpace::kStorage, Group(0_a), Binding(3_a));
+    GlobalVar("wg", ty.array<f32, 10>(), type::AddressSpace::kWorkgroup);
 
     WrapInFunction(Assign(Phony(), 1_i),                                    //
                    Assign(Phony(), 2_u),                                    //
diff --git a/src/tint/resolver/atomics_test.cc b/src/tint/resolver/atomics_test.cc
index a7d4f07..ba83fcd 100644
--- a/src/tint/resolver/atomics_test.cc
+++ b/src/tint/resolver/atomics_test.cc
@@ -27,7 +27,7 @@
 struct ResolverAtomicTest : public resolver::TestHelper, public testing::Test {};
 
 TEST_F(ResolverAtomicTest, GlobalWorkgroupI32) {
-    auto* g = GlobalVar("a", ty.atomic(Source{{12, 34}}, ty.i32()), ast::AddressSpace::kWorkgroup);
+    auto* g = GlobalVar("a", ty.atomic(Source{{12, 34}}, ty.i32()), type::AddressSpace::kWorkgroup);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
     ASSERT_TRUE(TypeOf(g)->Is<type::Reference>());
@@ -37,7 +37,7 @@
 }
 
 TEST_F(ResolverAtomicTest, GlobalWorkgroupU32) {
-    auto* g = GlobalVar("a", ty.atomic(Source{{12, 34}}, ty.u32()), ast::AddressSpace::kWorkgroup);
+    auto* g = GlobalVar("a", ty.atomic(Source{{12, 34}}, ty.u32()), type::AddressSpace::kWorkgroup);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
     ASSERT_TRUE(TypeOf(g)->Is<type::Reference>());
@@ -48,7 +48,7 @@
 
 TEST_F(ResolverAtomicTest, GlobalStorageStruct) {
     auto* s = Structure("s", utils::Vector{Member("a", ty.atomic(Source{{12, 34}}, ty.i32()))});
-    auto* g = GlobalVar("g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite,
+    auto* g = GlobalVar("g", ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite,
                         Binding(0_a), Group(0_a));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
diff --git a/src/tint/resolver/atomics_validation_test.cc b/src/tint/resolver/atomics_validation_test.cc
index 1350935..f8f66a7 100644
--- a/src/tint/resolver/atomics_validation_test.cc
+++ b/src/tint/resolver/atomics_validation_test.cc
@@ -27,35 +27,35 @@
 struct ResolverAtomicValidationTest : public resolver::TestHelper, public testing::Test {};
 
 TEST_F(ResolverAtomicValidationTest, AddressSpace_WorkGroup) {
-    GlobalVar("a", ty.atomic(Source{{12, 34}}, ty.i32()), ast::AddressSpace::kWorkgroup);
+    GlobalVar("a", ty.atomic(Source{{12, 34}}, ty.i32()), type::AddressSpace::kWorkgroup);
 
     EXPECT_TRUE(r()->Resolve());
 }
 
 TEST_F(ResolverAtomicValidationTest, AddressSpace_Storage) {
-    GlobalVar("g", ty.atomic(Source{{12, 34}}, ty.i32()), ast::AddressSpace::kStorage,
-              ast::Access::kReadWrite, Group(0_a), Binding(0_a));
+    GlobalVar("g", ty.atomic(Source{{12, 34}}, ty.i32()), type::AddressSpace::kStorage,
+              type::Access::kReadWrite, Group(0_a), Binding(0_a));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverAtomicValidationTest, AddressSpace_Storage_Struct) {
     auto* s = Structure("s", utils::Vector{Member(Source{{12, 34}}, "a", ty.atomic(ty.i32()))});
-    GlobalVar("g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Group(0_a),
+    GlobalVar("g", ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite, Group(0_a),
               Binding(0_a));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverAtomicValidationTest, InvalidType) {
-    GlobalVar("a", ty.atomic(ty.f32(Source{{12, 34}})), ast::AddressSpace::kWorkgroup);
+    GlobalVar("a", ty.atomic(ty.f32(Source{{12, 34}})), type::AddressSpace::kWorkgroup);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: atomic only supports i32 or u32 types");
 }
 
 TEST_F(ResolverAtomicValidationTest, InvalidAddressSpace_Simple) {
-    GlobalVar(Source{{12, 34}}, "a", ty.atomic(ty.i32()), ast::AddressSpace::kPrivate);
+    GlobalVar(Source{{12, 34}}, "a", ty.atomic(ty.i32()), type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -63,7 +63,7 @@
 }
 
 TEST_F(ResolverAtomicValidationTest, InvalidAddressSpace_Array) {
-    GlobalVar(Source{{12, 34}}, "a", ty.atomic(ty.i32()), ast::AddressSpace::kPrivate);
+    GlobalVar(Source{{12, 34}}, "a", ty.atomic(ty.i32()), type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -72,7 +72,7 @@
 
 TEST_F(ResolverAtomicValidationTest, InvalidAddressSpace_Struct) {
     auto* s = Structure("s", utils::Vector{Member("a", ty.atomic(ty.i32()))});
-    GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::AddressSpace::kPrivate);
+    GlobalVar(Source{{56, 78}}, "g", ty.Of(s), type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -88,7 +88,7 @@
     auto* Inner =
         Structure("Inner", utils::Vector{Member("m", ty.atomic(Source{{12, 34}}, ty.i32()))});
     auto* Outer = Structure("Outer", utils::Vector{Member("m", ty.Of(Inner))});
-    GlobalVar(Source{{56, 78}}, "g", ty.Of(Outer), ast::AddressSpace::kPrivate);
+    GlobalVar(Source{{56, 78}}, "g", ty.Of(Outer), type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -104,7 +104,7 @@
     auto* Inner =
         Structure("Inner", utils::Vector{Member(Source{{12, 34}}, "m", ty.atomic(ty.i32()))});
     auto* Outer = Structure("Outer", utils::Vector{Member("m", ty.Of(Inner))});
-    GlobalVar(Source{{56, 78}}, "g", ty.Of(Outer), ast::AddressSpace::kPrivate);
+    GlobalVar(Source{{56, 78}}, "g", ty.Of(Outer), type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -118,7 +118,7 @@
 
     auto* atomic_array =
         Alias(Source{{12, 34}}, "AtomicArray", ty.atomic(Source{{12, 34}}, ty.i32()));
-    GlobalVar(Source{{56, 78}}, "v", ty.Of(atomic_array), ast::AddressSpace::kPrivate);
+    GlobalVar(Source{{56, 78}}, "v", ty.Of(atomic_array), type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -132,7 +132,7 @@
     // var<private> v: array<S, 5u>;
 
     auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "m", ty.atomic<u32>())});
-    GlobalVar(Source{{56, 78}}, "v", ty.array(ty.Of(s), 5_u), ast::AddressSpace::kPrivate);
+    GlobalVar(Source{{56, 78}}, "v", ty.array(ty.Of(s), 5_u), type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -149,7 +149,7 @@
 
     auto* atomic_array = Alias("AtomicArray", ty.atomic(ty.i32()));
     auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "m", ty.Of(atomic_array))});
-    GlobalVar(Source{{56, 78}}, "v", ty.array(ty.Of(s), 5_u), ast::AddressSpace::kPrivate);
+    GlobalVar(Source{{56, 78}}, "v", ty.array(ty.Of(s), 5_u), type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -188,7 +188,7 @@
     auto* s2 = Structure("S2", utils::Vector{Member("x", ty.Of(s3))});
     auto* s1 = Structure("S1", utils::Vector{Member("x", ty.Of(s2))});
     auto* s0 = Structure("S0", utils::Vector{Member("x", ty.Of(s1))});
-    GlobalVar(Source{{56, 78}}, "g", ty.Of(s0), ast::AddressSpace::kPrivate);
+    GlobalVar(Source{{56, 78}}, "g", ty.Of(s0), type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -198,7 +198,7 @@
 
 TEST_F(ResolverAtomicValidationTest, Struct_AccessMode_Read) {
     auto* s = Structure("s", utils::Vector{Member(Source{{12, 34}}, "a", ty.atomic(ty.i32()))});
-    GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{56, 78}}, "g", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead,
               Group(0_a), Binding(0_a));
 
     EXPECT_FALSE(r()->Resolve());
@@ -210,7 +210,7 @@
 
 TEST_F(ResolverAtomicValidationTest, InvalidAccessMode_Struct) {
     auto* s = Structure("s", utils::Vector{Member(Source{{12, 34}}, "a", ty.atomic(ty.i32()))});
-    GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{56, 78}}, "g", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead,
               Group(0_a), Binding(0_a));
 
     EXPECT_FALSE(r()->Resolve());
@@ -228,8 +228,8 @@
     auto* Inner =
         Structure("Inner", utils::Vector{Member(Source{{12, 34}}, "m", ty.atomic(ty.i32()))});
     auto* Outer = Structure("Outer", utils::Vector{Member("m", ty.Of(Inner))});
-    GlobalVar(Source{{56, 78}}, "g", ty.Of(Outer), ast::AddressSpace::kStorage, ast::Access::kRead,
-              Group(0_a), Binding(0_a));
+    GlobalVar(Source{{56, 78}}, "g", ty.Of(Outer), type::AddressSpace::kStorage,
+              type::Access::kRead, Group(0_a), Binding(0_a));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -246,8 +246,8 @@
     auto* Inner =
         Structure("Inner", utils::Vector{Member(Source{{12, 34}}, "m", ty.atomic(ty.i32()))});
     auto* Outer = Structure("Outer", utils::Vector{Member("m", ty.Of(Inner))});
-    GlobalVar(Source{{56, 78}}, "g", ty.Of(Outer), ast::AddressSpace::kStorage, ast::Access::kRead,
-              Group(0_a), Binding(0_a));
+    GlobalVar(Source{{56, 78}}, "g", ty.Of(Outer), type::AddressSpace::kStorage,
+              type::Access::kRead, Group(0_a), Binding(0_a));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -287,7 +287,7 @@
     auto* s2 = Structure("S2", utils::Vector{Member("x", ty.Of(s3))});
     auto* s1 = Structure("S1", utils::Vector{Member("x", ty.Of(s2))});
     auto* s0 = Structure("S0", utils::Vector{Member("x", ty.Of(s1))});
-    GlobalVar(Source{{12, 34}}, "g", ty.Of(s0), ast::AddressSpace::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{12, 34}}, "g", ty.Of(s0), type::AddressSpace::kStorage, type::Access::kRead,
               Group(0_a), Binding(0_a));
 
     EXPECT_FALSE(r()->Resolve());
diff --git a/src/tint/resolver/attribute_validation_test.cc b/src/tint/resolver/attribute_validation_test.cc
index 762eea9..00ee7aa 100644
--- a/src/tint/resolver/attribute_validation_test.cc
+++ b/src/tint/resolver/attribute_validation_test.cc
@@ -16,6 +16,7 @@
 #include "src/tint/resolver/resolver.h"
 #include "src/tint/resolver/resolver_test_helper.h"
 #include "src/tint/transform/add_block_attribute.h"
+#include "src/tint/type/texture_dimension.h"
 
 #include "gmock/gmock.h"
 
@@ -721,8 +722,8 @@
 }
 
 TEST_F(StructMemberAttributeTest, Align_Attribute_Var) {
-    GlobalVar(Source{{1, 2}}, "val", ty.f32(), ast::AddressSpace::kPrivate, ast::Access::kUndefined,
-              Expr(1.23_f));
+    GlobalVar(Source{{1, 2}}, "val", ty.f32(), type::AddressSpace::kPrivate,
+              type::Access::kUndefined, Expr(1.23_f));
 
     Structure(Source{{6, 4}}, "mystruct",
               utils::Vector{Member(Source{{12, 5}}, "a", ty.f32(),
@@ -795,8 +796,8 @@
 }
 
 TEST_F(StructMemberAttributeTest, Size_Attribute_Var) {
-    GlobalVar(Source{{1, 2}}, "val", ty.f32(), ast::AddressSpace::kPrivate, ast::Access::kUndefined,
-              Expr(1.23_f));
+    GlobalVar(Source{{1, 2}}, "val", ty.f32(), type::AddressSpace::kPrivate,
+              type::Access::kUndefined, Expr(1.23_f));
 
     Structure(Source{{6, 4}}, "mystruct",
               utils::Vector{Member(Source{{12, 5}}, "a", ty.f32(),
@@ -874,7 +875,7 @@
     if (IsBindingAttribute(params.kind)) {
         GlobalVar("a", ty.sampler(ast::SamplerKind::kSampler), attrs);
     } else {
-        GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate, attrs);
+        GlobalVar("a", ty.f32(), type::AddressSpace::kPrivate, attrs);
     }
 
     if (params.should_pass) {
@@ -1045,7 +1046,7 @@
                              create<ast::StrideAttribute>(Source{{12, 34}}, params.stride),
                          });
 
-    GlobalVar("myarray", arr, ast::AddressSpace::kPrivate);
+    GlobalVar("myarray", arr, type::AddressSpace::kPrivate);
 
     if (params.should_pass) {
         EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1128,7 +1129,7 @@
                              create<ast::StrideAttribute>(Source{{56, 78}}, 4u),
                          });
 
-    GlobalVar("myarray", arr, ast::AddressSpace::kPrivate);
+    GlobalVar("myarray", arr, type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -1147,7 +1148,7 @@
     auto* s = Structure("S", utils::Vector{
                                  Member("x", ty.i32()),
                              });
-    GlobalVar(Source{{12, 34}}, "G", ty.Of(s), ast::AddressSpace::kUniform);
+    GlobalVar(Source{{12, 34}}, "G", ty.Of(s), type::AddressSpace::kUniform);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -1158,7 +1159,7 @@
     auto* s = Structure("S", utils::Vector{
                                  Member("x", ty.i32()),
                              });
-    GlobalVar(Source{{12, 34}}, "G", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead);
+    GlobalVar(Source{{12, 34}}, "G", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -1166,7 +1167,7 @@
 }
 
 TEST_F(ResourceAttributeTest, TextureMissingBinding) {
-    GlobalVar(Source{{12, 34}}, "G", ty.depth_texture(ast::TextureDimension::k2d));
+    GlobalVar(Source{{12, 34}}, "G", ty.depth_texture(type::TextureDimension::k2d));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -1198,9 +1199,9 @@
 }
 
 TEST_F(ResourceAttributeTest, BindingPointUsedTwiceByEntryPoint) {
-    GlobalVar(Source{{12, 34}}, "A", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
+    GlobalVar(Source{{12, 34}}, "A", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()),
               Binding(1_a), Group(2_a));
-    GlobalVar(Source{{56, 78}}, "B", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
+    GlobalVar(Source{{56, 78}}, "B", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()),
               Binding(1_a), Group(2_a));
 
     Func("F", utils::Empty, ty.void_(),
@@ -1220,9 +1221,9 @@
 }
 
 TEST_F(ResourceAttributeTest, BindingPointUsedTwiceByDifferentEntryPoints) {
-    GlobalVar(Source{{12, 34}}, "A", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
+    GlobalVar(Source{{12, 34}}, "A", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()),
               Binding(1_a), Group(2_a));
-    GlobalVar(Source{{56, 78}}, "B", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
+    GlobalVar(Source{{56, 78}}, "B", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()),
               Binding(1_a), Group(2_a));
 
     Func("F_A", utils::Empty, ty.void_(),
@@ -1244,7 +1245,7 @@
 }
 
 TEST_F(ResourceAttributeTest, BindingPointOnNonResource) {
-    GlobalVar(Source{{12, 34}}, "G", ty.f32(), ast::AddressSpace::kPrivate, Binding(1_a),
+    GlobalVar(Source{{12, 34}}, "G", ty.f32(), type::AddressSpace::kPrivate, Binding(1_a),
               Group(2_a));
 
     EXPECT_FALSE(r()->Resolve());
@@ -1582,7 +1583,7 @@
 TEST_F(GroupAndBindingTest, Const_I32) {
     GlobalConst("b", Expr(4_i));
     GlobalConst("g", Expr(2_i));
-    GlobalVar("val", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), Binding("b"),
+    GlobalVar("val", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()), Binding("b"),
               Group("g"));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1591,7 +1592,7 @@
 TEST_F(GroupAndBindingTest, Const_U32) {
     GlobalConst("b", Expr(4_u));
     GlobalConst("g", Expr(2_u));
-    GlobalVar("val", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), Binding("b"),
+    GlobalVar("val", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()), Binding("b"),
               Group("g"));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1600,14 +1601,14 @@
 TEST_F(GroupAndBindingTest, Const_AInt) {
     GlobalConst("b", Expr(4_a));
     GlobalConst("g", Expr(2_a));
-    GlobalVar("val", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), Binding("b"),
+    GlobalVar("val", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()), Binding("b"),
               Group("g"));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(GroupAndBindingTest, Binding_NonConstant) {
-    GlobalVar("val", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
+    GlobalVar("val", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()),
               Binding(Construct(ty.u32(), Call(Source{{12, 34}}, "dpdx", 1_a))), Group(1_i));
 
     EXPECT_FALSE(r()->Resolve());
@@ -1617,7 +1618,7 @@
 }
 
 TEST_F(GroupAndBindingTest, Binding_Negative) {
-    GlobalVar("val", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
+    GlobalVar("val", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()),
               Binding(Source{{12, 34}}, -2_i), Group(1_i));
 
     EXPECT_FALSE(r()->Resolve());
@@ -1625,7 +1626,7 @@
 }
 
 TEST_F(GroupAndBindingTest, Binding_F32) {
-    GlobalVar("val", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
+    GlobalVar("val", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()),
               Binding(Source{{12, 34}}, 2.0_f), Group(1_u));
 
     EXPECT_FALSE(r()->Resolve());
@@ -1633,7 +1634,7 @@
 }
 
 TEST_F(GroupAndBindingTest, Binding_AFloat) {
-    GlobalVar("val", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
+    GlobalVar("val", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()),
               Binding(Source{{12, 34}}, 2.0_a), Group(1_u));
 
     EXPECT_FALSE(r()->Resolve());
@@ -1641,7 +1642,7 @@
 }
 
 TEST_F(GroupAndBindingTest, Group_NonConstant) {
-    GlobalVar("val", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), Binding(2_u),
+    GlobalVar("val", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()), Binding(2_u),
               Group(Construct(ty.u32(), Call(Source{{12, 34}}, "dpdx", 1_a))));
 
     EXPECT_FALSE(r()->Resolve());
@@ -1651,7 +1652,7 @@
 }
 
 TEST_F(GroupAndBindingTest, Group_Negative) {
-    GlobalVar("val", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), Binding(2_u),
+    GlobalVar("val", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()), Binding(2_u),
               Group(Source{{12, 34}}, -1_i));
 
     EXPECT_FALSE(r()->Resolve());
@@ -1659,7 +1660,7 @@
 }
 
 TEST_F(GroupAndBindingTest, Group_F32) {
-    GlobalVar("val", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), Binding(2_u),
+    GlobalVar("val", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()), Binding(2_u),
               Group(Source{{12, 34}}, 1.0_f));
 
     EXPECT_FALSE(r()->Resolve());
@@ -1667,7 +1668,7 @@
 }
 
 TEST_F(GroupAndBindingTest, Group_AFloat) {
-    GlobalVar("val", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), Binding(2_u),
+    GlobalVar("val", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()), Binding(2_u),
               Group(Source{{12, 34}}, 1.0_a));
 
     EXPECT_FALSE(r()->Resolve());
diff --git a/src/tint/resolver/builtin_test.cc b/src/tint/resolver/builtin_test.cc
index 955b945..b56caaa 100644
--- a/src/tint/resolver/builtin_test.cc
+++ b/src/tint/resolver/builtin_test.cc
@@ -36,6 +36,7 @@
 #include "src/tint/sem/variable.h"
 #include "src/tint/type/sampled_texture.h"
 #include "src/tint/type/test_helper.h"
+#include "src/tint/type/texture_dimension.h"
 
 using ::testing::ElementsAre;
 using ::testing::HasSubstr;
@@ -79,7 +80,7 @@
 TEST_P(ResolverBuiltinTest_BoolMethod, Scalar) {
     auto name = GetParam();
 
-    GlobalVar("my_var", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_var", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* expr = Call(name, "my_var");
     WrapInFunction(expr);
@@ -92,7 +93,7 @@
 TEST_P(ResolverBuiltinTest_BoolMethod, Vector) {
     auto name = GetParam();
 
-    GlobalVar("my_var", ty.vec3<bool>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_var", ty.vec3<bool>(), type::AddressSpace::kPrivate);
 
     auto* expr = Call(name, "my_var");
     WrapInFunction(expr);
@@ -107,9 +108,9 @@
                          testing::Values("any", "all"));
 
 TEST_F(ResolverBuiltinTest, Select) {
-    GlobalVar("my_var", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_var", ty.vec3<f32>(), type::AddressSpace::kPrivate);
 
-    GlobalVar("bool_var", ty.vec3<bool>(), ast::AddressSpace::kPrivate);
+    GlobalVar("bool_var", ty.vec3<bool>(), type::AddressSpace::kPrivate);
 
     auto* expr = Call("select", "my_var", "my_var", "bool_var");
     WrapInFunction(expr);
@@ -213,7 +214,7 @@
 TEST_F(ResolverBuiltinArrayTest, ArrayLength_Vector) {
     auto* ary = ty.array<i32>();
     auto* str = Structure("S", utils::Vector{Member("x", ary)});
-    GlobalVar("a", ty.Of(str), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("a", ty.Of(str), type::AddressSpace::kStorage, type::Access::kRead, Binding(0_a),
               Group(0_a));
 
     auto* call = Call("arrayLength", AddressOf(MemberAccessor("a", "x")));
@@ -226,7 +227,7 @@
 }
 
 TEST_F(ResolverBuiltinArrayTest, ArrayLength_Error_ArraySized) {
-    GlobalVar("arr", ty.array<i32, 4>(), ast::AddressSpace::kPrivate);
+    GlobalVar("arr", ty.array<i32, 4>(), type::AddressSpace::kPrivate);
     auto* call = Call("arrayLength", AddressOf("arr"));
     WrapInFunction(call);
 
@@ -1069,7 +1070,7 @@
 }
 
 TEST_F(ResolverBuiltinFloatTest, Frexp_Error_FirstParamInt) {
-    GlobalVar("v", ty.i32(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("v", ty.i32(), type::AddressSpace::kWorkgroup);
     auto* call = Call("frexp", 1_i, AddressOf("v"));
     WrapInFunction(call);
 
@@ -1318,7 +1319,7 @@
 }
 
 TEST_F(ResolverBuiltinFloatTest, Modf_Error_FirstParamInt) {
-    GlobalVar("whole", ty.f32(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("whole", ty.f32(), type::AddressSpace::kWorkgroup);
     auto* call = Call("modf", 1_i, AddressOf("whole"));
     WrapInFunction(call);
 
@@ -1334,7 +1335,7 @@
 }
 
 TEST_F(ResolverBuiltinFloatTest, Modf_Error_SecondParamIntPtr) {
-    GlobalVar("whole", ty.i32(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("whole", ty.i32(), type::AddressSpace::kWorkgroup);
     auto* call = Call("modf", 1_f, AddressOf("whole"));
     WrapInFunction(call);
 
@@ -1364,7 +1365,7 @@
 }
 
 TEST_F(ResolverBuiltinFloatTest, Modf_Error_VectorSizesDontMatch) {
-    GlobalVar("whole", ty.vec4<f32>(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("whole", ty.vec4<f32>(), type::AddressSpace::kWorkgroup);
     auto* call = Call("modf", vec2<f32>(1_f, 2_f), AddressOf("whole"));
     WrapInFunction(call);
 
@@ -1844,7 +1845,7 @@
 namespace matrix_builtin_tests {
 
 TEST_F(ResolverBuiltinTest, Determinant_2x2_f32) {
-    GlobalVar("var", ty.mat2x2<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("var", ty.mat2x2<f32>(), type::AddressSpace::kPrivate);
 
     auto* call = Call("determinant", "var");
     WrapInFunction(call);
@@ -1858,7 +1859,7 @@
 TEST_F(ResolverBuiltinTest, Determinant_2x2_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("var", ty.mat2x2<f16>(), ast::AddressSpace::kPrivate);
+    GlobalVar("var", ty.mat2x2<f16>(), type::AddressSpace::kPrivate);
 
     auto* call = Call("determinant", "var");
     WrapInFunction(call);
@@ -1870,7 +1871,7 @@
 }
 
 TEST_F(ResolverBuiltinTest, Determinant_3x3_f32) {
-    GlobalVar("var", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("var", ty.mat3x3<f32>(), type::AddressSpace::kPrivate);
 
     auto* call = Call("determinant", "var");
     WrapInFunction(call);
@@ -1884,7 +1885,7 @@
 TEST_F(ResolverBuiltinTest, Determinant_3x3_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("var", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
+    GlobalVar("var", ty.mat3x3<f16>(), type::AddressSpace::kPrivate);
 
     auto* call = Call("determinant", "var");
     WrapInFunction(call);
@@ -1896,7 +1897,7 @@
 }
 
 TEST_F(ResolverBuiltinTest, Determinant_4x4_f32) {
-    GlobalVar("var", ty.mat4x4<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("var", ty.mat4x4<f32>(), type::AddressSpace::kPrivate);
 
     auto* call = Call("determinant", "var");
     WrapInFunction(call);
@@ -1910,7 +1911,7 @@
 TEST_F(ResolverBuiltinTest, Determinant_4x4_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("var", ty.mat4x4<f16>(), ast::AddressSpace::kPrivate);
+    GlobalVar("var", ty.mat4x4<f16>(), type::AddressSpace::kPrivate);
 
     auto* call = Call("determinant", "var");
     WrapInFunction(call);
@@ -1922,7 +1923,7 @@
 }
 
 TEST_F(ResolverBuiltinTest, Determinant_NotSquare) {
-    GlobalVar("var", ty.mat2x3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("var", ty.mat2x3<f32>(), type::AddressSpace::kPrivate);
 
     auto* call = Call("determinant", "var");
     WrapInFunction(call);
@@ -1937,7 +1938,7 @@
 }
 
 TEST_F(ResolverBuiltinTest, Determinant_NotMatrix) {
-    GlobalVar("var", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("var", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* call = Call("determinant", "var");
     WrapInFunction(call);
@@ -1957,7 +1958,7 @@
 namespace vector_builtin_tests {
 
 TEST_F(ResolverBuiltinTest, Dot_Vec2_f32) {
-    GlobalVar("my_var", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_var", ty.vec2<f32>(), type::AddressSpace::kPrivate);
 
     auto* expr = Call("dot", "my_var", "my_var");
     WrapInFunction(expr);
@@ -1971,7 +1972,7 @@
 TEST_F(ResolverBuiltinTest, Dot_Vec2_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("my_var", ty.vec2<f16>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_var", ty.vec2<f16>(), type::AddressSpace::kPrivate);
 
     auto* expr = Call("dot", "my_var", "my_var");
     WrapInFunction(expr);
@@ -1983,7 +1984,7 @@
 }
 
 TEST_F(ResolverBuiltinTest, Dot_Vec3_i32) {
-    GlobalVar("my_var", ty.vec3<i32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_var", ty.vec3<i32>(), type::AddressSpace::kPrivate);
 
     auto* expr = Call("dot", "my_var", "my_var");
     WrapInFunction(expr);
@@ -1995,7 +1996,7 @@
 }
 
 TEST_F(ResolverBuiltinTest, Dot_Vec4_u32) {
-    GlobalVar("my_var", ty.vec4<u32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_var", ty.vec4<u32>(), type::AddressSpace::kPrivate);
 
     auto* expr = Call("dot", "my_var", "my_var");
     WrapInFunction(expr);
@@ -2030,7 +2031,7 @@
 TEST_P(ResolverBuiltinDerivativeTest, Scalar) {
     auto name = GetParam();
 
-    GlobalVar("ident", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("ident", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* expr = Call(name, "ident");
     Func("func", utils::Empty, ty.void_(), utils::Vector{Ignore(expr)},
@@ -2044,7 +2045,7 @@
 
 TEST_P(ResolverBuiltinDerivativeTest, Vector) {
     auto name = GetParam();
-    GlobalVar("ident", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("ident", ty.vec4<f32>(), type::AddressSpace::kPrivate);
 
     auto* expr = Call(name, "ident");
     Func("func", utils::Empty, ty.void_(), utils::Vector{Ignore(expr)},
@@ -2102,9 +2103,9 @@
 }
 
 struct TextureTestParams {
-    ast::TextureDimension dim;
+    type::TextureDimension dim;
     Texture type = Texture::kF32;
-    ast::TexelFormat format = ast::TexelFormat::kR32Float;
+    type::TexelFormat format = type::TexelFormat::kR32Float;
 };
 inline std::ostream& operator<<(std::ostream& out, TextureTestParams data) {
     out << data.dim << "_" << data.type;
@@ -2118,16 +2119,16 @@
     /// @param dim dimensionality of the texture being sampled
     /// @param scalar the scalar type
     /// @returns a pointer to a type appropriate for the coord param
-    const ast::Type* GetCoordsType(ast::TextureDimension dim, const ast::Type* scalar) {
+    const ast::Type* GetCoordsType(type::TextureDimension dim, const ast::Type* scalar) {
         switch (dim) {
-            case ast::TextureDimension::k1d:
+            case type::TextureDimension::k1d:
                 return scalar;
-            case ast::TextureDimension::k2d:
-            case ast::TextureDimension::k2dArray:
+            case type::TextureDimension::k2d:
+            case type::TextureDimension::k2dArray:
                 return ty.vec(scalar, 2);
-            case ast::TextureDimension::k3d:
-            case ast::TextureDimension::kCube:
-            case ast::TextureDimension::kCubeArray:
+            case type::TextureDimension::k3d:
+            case type::TextureDimension::kCube:
+            case type::TextureDimension::kCubeArray:
                 return ty.vec(scalar, 3);
             default:
                 [=]() { FAIL() << "Unsupported texture dimension: " << dim; }();
@@ -2140,7 +2141,7 @@
             GlobalVar(name, type, Binding(0_a), Group(0_a));
 
         } else {
-            GlobalVar(name, type, ast::AddressSpace::kPrivate);
+            GlobalVar(name, type, type::AddressSpace::kPrivate);
         }
 
         call_params->Push(Expr(name));
@@ -2169,7 +2170,7 @@
 
     add_call_param("texture", texture_type, &call_params);
     add_call_param("coords", coords_type, &call_params);
-    if (dim == ast::TextureDimension::k2dArray) {
+    if (dim == type::TextureDimension::k2dArray) {
         add_call_param("array_index", ty.i32(), &call_params);
     }
     add_call_param("level", ty.i32(), &call_params);
@@ -2193,10 +2194,10 @@
 
 INSTANTIATE_TEST_SUITE_P(ResolverTest,
                          ResolverBuiltinTest_SampledTextureOperation,
-                         testing::Values(TextureTestParams{ast::TextureDimension::k1d},
-                                         TextureTestParams{ast::TextureDimension::k2d},
-                                         TextureTestParams{ast::TextureDimension::k2dArray},
-                                         TextureTestParams{ast::TextureDimension::k3d}));
+                         testing::Values(TextureTestParams{type::TextureDimension::k1d},
+                                         TextureTestParams{type::TextureDimension::k2d},
+                                         TextureTestParams{type::TextureDimension::k2dArray},
+                                         TextureTestParams{type::TextureDimension::k3d}));
 
 using ResolverBuiltinTest_Texture = ResolverTestWithParam<ast::builtin::test::TextureOverloadCase>;
 
@@ -2469,20 +2470,20 @@
         switch (param.texture_dimension) {
             default:
                 FAIL() << "invalid texture dimensions: " << param.texture_dimension;
-            case ast::TextureDimension::k1d:
+            case type::TextureDimension::k1d:
                 EXPECT_TRUE(TypeOf(call)->Is<type::U32>());
                 break;
-            case ast::TextureDimension::k2d:
-            case ast::TextureDimension::k2dArray:
-            case ast::TextureDimension::kCube:
-            case ast::TextureDimension::kCubeArray: {
+            case type::TextureDimension::k2d:
+            case type::TextureDimension::k2dArray:
+            case type::TextureDimension::kCube:
+            case type::TextureDimension::kCubeArray: {
                 auto* vec = As<type::Vector>(TypeOf(call));
                 ASSERT_NE(vec, nullptr);
                 EXPECT_EQ(vec->Width(), 2u);
                 EXPECT_TRUE(vec->type()->Is<type::U32>());
                 break;
             }
-            case ast::TextureDimension::k3d: {
+            case type::TextureDimension::k3d: {
                 auto* vec = As<type::Vector>(TypeOf(call));
                 ASSERT_NE(vec, nullptr);
                 EXPECT_EQ(vec->Width(), 3u);
diff --git a/src/tint/resolver/builtin_validation_test.cc b/src/tint/resolver/builtin_validation_test.cc
index 2b45386..2d3f2f3 100644
--- a/src/tint/resolver/builtin_validation_test.cc
+++ b/src/tint/resolver/builtin_validation_test.cc
@@ -166,7 +166,7 @@
 }
 
 TEST_F(ResolverBuiltinValidationTest, BuiltinRedeclaredAsGlobalVarUsedAsFunction) {
-    GlobalVar(Source{{12, 34}}, "mix", ty.i32(), Expr(1_i), ast::AddressSpace::kPrivate);
+    GlobalVar(Source{{12, 34}}, "mix", ty.i32(), Expr(1_i), type::AddressSpace::kPrivate);
     WrapInFunction(Call(Expr(Source{{56, 78}}, "mix"), 1_f, 2_f, 3_f));
 
     EXPECT_FALSE(r()->Resolve());
@@ -176,7 +176,7 @@
 
 TEST_F(ResolverBuiltinValidationTest, BuiltinRedeclaredAsGlobalVarUsedAsVariable) {
     auto* mix =
-        GlobalVar(Source{{12, 34}}, "mix", ty.i32(), Expr(1_i), ast::AddressSpace::kPrivate);
+        GlobalVar(Source{{12, 34}}, "mix", ty.i32(), Expr(1_i), type::AddressSpace::kPrivate);
     auto* use = Expr("mix");
     WrapInFunction(Decl(Var("v", use)));
 
@@ -187,7 +187,7 @@
 }
 
 TEST_F(ResolverBuiltinValidationTest, BuiltinRedeclaredAsGlobalVarUsedAsType) {
-    GlobalVar(Source{{12, 34}}, "mix", ty.i32(), Expr(1_i), ast::AddressSpace::kPrivate);
+    GlobalVar(Source{{12, 34}}, "mix", ty.i32(), Expr(1_i), type::AddressSpace::kPrivate);
     WrapInFunction(Construct(ty.type_name(Source{{56, 78}}, "mix")));
 
     EXPECT_FALSE(r()->Resolve());
@@ -481,7 +481,7 @@
     overload.BuildSamplerVariable(this);
 
     // Build the module-scope var 'G' with the offset value
-    GlobalVar("G", expr({}, *this), ast::AddressSpace::kPrivate);
+    GlobalVar("G", expr({}, *this), type::AddressSpace::kPrivate);
 
     auto args = overload.args(this);
     auto*& arg_to_replace = (param.position == Position::kFirst) ? args.Front() : args.Back();
@@ -652,7 +652,7 @@
     // fn foo() {
     //   workgroupUniformLoad(&v);
     // }
-    GlobalVar("v", ty.i32(), ast::AddressSpace::kStorage, ast::Access::kReadWrite,
+    GlobalVar("v", ty.i32(), type::AddressSpace::kStorage, type::Access::kReadWrite,
               utils::Vector{Group(0_a), Binding(0_a)});
     WrapInFunction(CallStmt(Call("workgroupUniformLoad", AddressOf(Source{{12, 34}}, "v"))));
 
@@ -670,7 +670,7 @@
     // fn foo() {
     //   workgroupUniformLoad(&v);
     // }
-    GlobalVar("v", ty.atomic<i32>(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("v", ty.atomic<i32>(), type::AddressSpace::kWorkgroup);
     WrapInFunction(CallStmt(Call("workgroupUniformLoad", AddressOf(Source{{12, 34}}, "v"))));
 
     EXPECT_FALSE(r()->Resolve());
@@ -684,7 +684,7 @@
     // fn foo() {
     //   workgroupUniformLoad(&v);
     // }
-    GlobalVar("v", ty.array(ty.atomic<i32>(), 4_a), ast::AddressSpace::kWorkgroup);
+    GlobalVar("v", ty.array(ty.atomic<i32>(), 4_a), type::AddressSpace::kWorkgroup);
     WrapInFunction(CallStmt(Call("workgroupUniformLoad", AddressOf(Source{{12, 34}}, "v"))));
 
     EXPECT_FALSE(r()->Resolve());
@@ -703,7 +703,7 @@
     Structure("Inner", utils::Vector{Member("a", ty.array(ty.atomic<i32>(), 4_a))});
     Structure("S", utils::Vector{Member("i", ty.type_name("Inner"))});
     GlobalVar(Source{{12, 34}}, "v", ty.array(ty.type_name("S"), 4_a),
-              ast::AddressSpace::kWorkgroup);
+              type::AddressSpace::kWorkgroup);
     WrapInFunction(CallStmt(Call("workgroupUniformLoad", AddressOf("v"))));
 
     EXPECT_FALSE(r()->Resolve());
diff --git a/src/tint/resolver/builtins_validation_test.cc b/src/tint/resolver/builtins_validation_test.cc
index b6fdddb..efee2c9 100644
--- a/src/tint/resolver/builtins_validation_test.cc
+++ b/src/tint/resolver/builtins_validation_test.cc
@@ -100,7 +100,7 @@
 TEST_P(ResolverBuiltinsStageTest, All_input) {
     const Params& params = GetParam();
 
-    auto* p = GlobalVar("p", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
+    auto* p = GlobalVar("p", ty.vec4<f32>(), type::AddressSpace::kPrivate);
     auto* input = Param("input", params.type(*this),
                         utils::Vector{Builtin(Source{{12, 34}}, params.builtin)});
     switch (params.stage) {
diff --git a/src/tint/resolver/call_validation_test.cc b/src/tint/resolver/call_validation_test.cc
index e94e7b8..9e90cf8 100644
--- a/src/tint/resolver/call_validation_test.cc
+++ b/src/tint/resolver/call_validation_test.cc
@@ -103,7 +103,7 @@
     //   var z: i32 = 1i;
     //   foo(&z);
     // }
-    auto* param = Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction));
+    auto* param = Param("p", ty.pointer<i32>(type::AddressSpace::kFunction));
     Func("foo", utils::Vector{param}, ty.void_(), utils::Empty);
     Func("main", utils::Empty, ty.void_(),
          utils::Vector{
@@ -120,7 +120,7 @@
     //   let z: i32 = 1i;
     //   foo(&z);
     // }
-    auto* param = Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction));
+    auto* param = Param("p", ty.pointer<i32>(type::AddressSpace::kFunction));
     Func("foo", utils::Vector{param}, ty.void_(), utils::Empty);
     Func("main", utils::Empty, ty.void_(),
          utils::Vector{
@@ -142,7 +142,7 @@
     auto* S = Structure("S", utils::Vector{
                                  Member("m", ty.i32()),
                              });
-    auto* param = Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction));
+    auto* param = Param("p", ty.pointer<i32>(type::AddressSpace::kFunction));
     Func("foo", utils::Vector{param}, ty.void_(), utils::Empty);
     Func("main", utils::Empty, ty.void_(),
          utils::Vector{
@@ -169,7 +169,7 @@
     auto* S = Structure("S", utils::Vector{
                                  Member("m", ty.i32()),
                              });
-    auto* param = Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction));
+    auto* param = Param("p", ty.pointer<i32>(type::AddressSpace::kFunction));
     Func("foo", utils::Vector{param}, ty.void_(), utils::Empty);
     Func("main", utils::Empty, ty.void_(),
          utils::Vector{
@@ -189,7 +189,7 @@
     auto* S = Structure("S", utils::Vector{
                                  Member("m", ty.i32()),
                              });
-    auto* param = Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction));
+    auto* param = Param("p", ty.pointer<i32>(type::AddressSpace::kFunction));
     Func("foo", utils::Vector{param}, ty.void_(), utils::Empty);
     Func("main", utils::Empty, ty.void_(),
          utils::Vector{
@@ -208,12 +208,12 @@
     // }
     Func("foo",
          utils::Vector{
-             Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction)),
+             Param("p", ty.pointer<i32>(type::AddressSpace::kFunction)),
          },
          ty.void_(), utils::Empty);
     Func("bar",
          utils::Vector{
-             Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction)),
+             Param("p", ty.pointer<i32>(type::AddressSpace::kFunction)),
          },
          ty.void_(),
          utils::Vector{
@@ -235,12 +235,12 @@
     // }
     Func("foo",
          utils::Vector{
-             Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction)),
+             Param("p", ty.pointer<i32>(type::AddressSpace::kFunction)),
          },
          ty.void_(), utils::Empty);
     Func("bar",
          utils::Vector{
-             Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction)),
+             Param("p", ty.pointer<i32>(type::AddressSpace::kFunction)),
          },
          ty.void_(),
          utils::Vector{
@@ -268,13 +268,13 @@
     // }
     Func("x",
          utils::Vector{
-             Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction)),
+             Param("p", ty.pointer<i32>(type::AddressSpace::kFunction)),
          },
          ty.void_(), utils::Empty);
     Func("main", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(Var("v", ty.i32())),
-             Decl(Let("p", ty.pointer(ty.i32(), ast::AddressSpace::kFunction), AddressOf("v"))),
+             Decl(Let("p", ty.pointer(ty.i32(), type::AddressSpace::kFunction), AddressOf("v"))),
              CallStmt(Call("x", "p")),
          },
          utils::Vector{
@@ -293,13 +293,13 @@
     // }
     Func("foo",
          utils::Vector{
-             Param("p", ty.pointer<i32>(ast::AddressSpace::kPrivate)),
+             Param("p", ty.pointer<i32>(type::AddressSpace::kPrivate)),
          },
          ty.void_(), utils::Empty);
-    GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("v", ty.i32(), type::AddressSpace::kPrivate);
     Func("main", utils::Empty, ty.void_(),
          utils::Vector{
-             Decl(Let("p", ty.pointer(ty.i32(), ast::AddressSpace::kPrivate), AddressOf("v"))),
+             Decl(Let("p", ty.pointer(ty.i32(), type::AddressSpace::kPrivate), AddressOf("v"))),
              CallStmt(Call("foo", Expr(Source{{12, 34}}, "p"))),
          },
          utils::Vector{
@@ -318,13 +318,13 @@
     // }
     Func("foo",
          utils::Vector{
-             Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction)),
+             Param("p", ty.pointer<i32>(type::AddressSpace::kFunction)),
          },
          ty.void_(), utils::Empty);
     Func("main", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(Var("v", ty.array<i32, 4>())),
-             Decl(Let("p", ty.pointer(ty.i32(), ast::AddressSpace::kFunction),
+             Decl(Let("p", ty.pointer(ty.i32(), type::AddressSpace::kFunction),
                       AddressOf(IndexAccessor("v", 0_a)))),
              CallStmt(Call("foo", Expr(Source{{12, 34}}, "p"))),
          },
@@ -349,13 +349,13 @@
     Enable(ast::Extension::kChromiumExperimentalFullPtrParameters);
     Func("foo",
          utils::Vector{
-             Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction)),
+             Param("p", ty.pointer<i32>(type::AddressSpace::kFunction)),
          },
          ty.void_(), utils::Empty);
     Func("main", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(Var("v", ty.array<i32, 4>())),
-             Decl(Let("p", ty.pointer(ty.i32(), ast::AddressSpace::kFunction),
+             Decl(Let("p", ty.pointer(ty.i32(), type::AddressSpace::kFunction),
                       AddressOf(IndexAccessor("v", 0_a)))),
              CallStmt(Call("foo", Expr(Source{{12, 34}}, "p"))),
          },
@@ -377,7 +377,7 @@
     // }
     Func("foo",
          utils::Vector{
-             Param("p", ty.pointer(ty.array<i32, 4>(), ast::AddressSpace::kFunction)),
+             Param("p", ty.pointer(ty.array<i32, 4>(), type::AddressSpace::kFunction)),
          },
          ty.void_(), utils::Empty);
     Func("main", utils::Empty, ty.void_(),
@@ -406,7 +406,7 @@
     // }
     Func("foo",
          utils::Vector{
-             Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction)),
+             Param("p", ty.pointer<i32>(type::AddressSpace::kFunction)),
          },
          ty.void_(), utils::Empty);
     Func("main", utils::Empty, ty.void_(),
@@ -440,7 +440,7 @@
     Enable(ast::Extension::kChromiumExperimentalFullPtrParameters);
     Func("foo",
          utils::Vector{
-             Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction)),
+             Param("p", ty.pointer<i32>(type::AddressSpace::kFunction)),
          },
          ty.void_(), utils::Empty);
     Func("main", utils::Empty, ty.void_(),
@@ -462,7 +462,7 @@
     // fn f() {
     //   v();
     // }
-    GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("v", ty.i32(), type::AddressSpace::kPrivate);
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              CallStmt(Call(Source{{12, 34}}, "v")),
diff --git a/src/tint/resolver/compound_assignment_validation_test.cc b/src/tint/resolver/compound_assignment_validation_test.cc
index 941fce2..64a542c 100644
--- a/src/tint/resolver/compound_assignment_validation_test.cc
+++ b/src/tint/resolver/compound_assignment_validation_test.cc
@@ -51,7 +51,7 @@
     // var a : i32;
     // let b : ptr<function,i32> = &a;
     // *b += 2;
-    const auto func = ast::AddressSpace::kFunction;
+    const auto func = type::AddressSpace::kFunction;
     auto* var_a = Var("a", ty.i32(), func, Expr(2_i));
     auto* var_b = Let("b", ty.pointer<i32>(func), AddressOf(Expr("a")));
     WrapInFunction(var_a, var_b,
@@ -233,7 +233,7 @@
     // {
     //   a += 1i;
     // }
-    GlobalVar(Source{{12, 34}}, "a", ty.i32(), ast::AddressSpace::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{12, 34}}, "a", ty.i32(), type::AddressSpace::kStorage, type::Access::kRead,
               Group(0_a), Binding(0_a));
     WrapInFunction(CompoundAssign(Source{{56, 78}}, "a", 1_i, ast::BinaryOp::kAdd));
 
@@ -264,7 +264,7 @@
 TEST_F(ResolverCompoundAssignmentValidationTest, LhsAtomic) {
     // var<workgroup> a : atomic<i32>;
     // a += a;
-    GlobalVar(Source{{12, 34}}, "a", ty.atomic(ty.i32()), ast::AddressSpace::kWorkgroup);
+    GlobalVar(Source{{12, 34}}, "a", ty.atomic(ty.i32()), type::AddressSpace::kWorkgroup);
     WrapInFunction(CompoundAssign(Source{{56, 78}}, "a", "a", ast::BinaryOp::kAdd));
 
     EXPECT_FALSE(r()->Resolve());
diff --git a/src/tint/resolver/const_eval_indexing_test.cc b/src/tint/resolver/const_eval_indexing_test.cc
index 9229f98..e7c9688 100644
--- a/src/tint/resolver/const_eval_indexing_test.cc
+++ b/src/tint/resolver/const_eval_indexing_test.cc
@@ -279,7 +279,7 @@
 
 TEST_F(ResolverConstEvalTest, RuntimeArray_vec3_f32_Index_OOB_Low) {
     auto* sb = GlobalVar("sb", ty.array(ty.vec3<f32>()), Group(0_a), Binding(0_a),
-                         ast::AddressSpace::kStorage);
+                         type::AddressSpace::kStorage);
     auto* expr = IndexAccessor(sb, Expr(Source{{12, 34}}, -2_i));
     WrapInFunction(expr);
 
diff --git a/src/tint/resolver/dependency_graph_test.cc b/src/tint/resolver/dependency_graph_test.cc
index 81e79ff..e6f09a1 100644
--- a/src/tint/resolver/dependency_graph_test.cc
+++ b/src/tint/resolver/dependency_graph_test.cc
@@ -19,6 +19,7 @@
 #include "gmock/gmock.h"
 #include "src/tint/resolver/dependency_graph.h"
 #include "src/tint/resolver/resolver_test_helper.h"
+#include "src/tint/type/texture_dimension.h"
 
 using namespace tint::number_suffixes;  // NOLINT
 
@@ -425,7 +426,7 @@
     auto& b = *builder;
     switch (kind) {
         case SymbolDeclKind::GlobalVar:
-            return b.GlobalVar(source, symbol, b.ty.i32(), ast::AddressSpace::kPrivate);
+            return b.GlobalVar(source, symbol, b.ty.i32(), type::AddressSpace::kPrivate);
         case SymbolDeclKind::GlobalConst:
             return b.GlobalConst(source, symbol, b.ty.i32(), b.Expr(1_i));
         case SymbolDeclKind::Alias:
@@ -468,42 +469,42 @@
     switch (kind) {
         case SymbolUseKind::GlobalVarType: {
             auto* node = b.ty.type_name(source, symbol);
-            b.GlobalVar(b.Sym(), node, ast::AddressSpace::kPrivate);
+            b.GlobalVar(b.Sym(), node, type::AddressSpace::kPrivate);
             return node;
         }
         case SymbolUseKind::GlobalVarArrayElemType: {
             auto* node = b.ty.type_name(source, symbol);
-            b.GlobalVar(b.Sym(), b.ty.array(node, 4_i), ast::AddressSpace::kPrivate);
+            b.GlobalVar(b.Sym(), b.ty.array(node, 4_i), type::AddressSpace::kPrivate);
             return node;
         }
         case SymbolUseKind::GlobalVarArraySizeValue: {
             auto* node = b.Expr(source, symbol);
-            b.GlobalVar(b.Sym(), b.ty.array(b.ty.i32(), node), ast::AddressSpace::kPrivate);
+            b.GlobalVar(b.Sym(), b.ty.array(b.ty.i32(), node), type::AddressSpace::kPrivate);
             return node;
         }
         case SymbolUseKind::GlobalVarVectorElemType: {
             auto* node = b.ty.type_name(source, symbol);
-            b.GlobalVar(b.Sym(), b.ty.vec3(node), ast::AddressSpace::kPrivate);
+            b.GlobalVar(b.Sym(), b.ty.vec3(node), type::AddressSpace::kPrivate);
             return node;
         }
         case SymbolUseKind::GlobalVarMatrixElemType: {
             auto* node = b.ty.type_name(source, symbol);
-            b.GlobalVar(b.Sym(), b.ty.mat3x4(node), ast::AddressSpace::kPrivate);
+            b.GlobalVar(b.Sym(), b.ty.mat3x4(node), type::AddressSpace::kPrivate);
             return node;
         }
         case SymbolUseKind::GlobalVarSampledTexElemType: {
             auto* node = b.ty.type_name(source, symbol);
-            b.GlobalVar(b.Sym(), b.ty.sampled_texture(ast::TextureDimension::k2d, node));
+            b.GlobalVar(b.Sym(), b.ty.sampled_texture(type::TextureDimension::k2d, node));
             return node;
         }
         case SymbolUseKind::GlobalVarMultisampledTexElemType: {
             auto* node = b.ty.type_name(source, symbol);
-            b.GlobalVar(b.Sym(), b.ty.multisampled_texture(ast::TextureDimension::k2d, node));
+            b.GlobalVar(b.Sym(), b.ty.multisampled_texture(type::TextureDimension::k2d, node));
             return node;
         }
         case SymbolUseKind::GlobalVarValue: {
             auto* node = b.Expr(source, symbol);
-            b.GlobalVar(b.Sym(), b.ty.i32(), ast::AddressSpace::kPrivate, node);
+            b.GlobalVar(b.Sym(), b.ty.i32(), type::AddressSpace::kPrivate, node);
             return node;
         }
         case SymbolUseKind::GlobalConstType: {
@@ -724,7 +725,7 @@
              Block(Assign(Expr(Source{{12, 34}}, "G"), 3.14_f)),
          });
 
-    GlobalVar(Source{{56, 78}}, "G", ty.f32(), ast::AddressSpace::kPrivate, Expr(2.1_f));
+    GlobalVar(Source{{56, 78}}, "G", ty.f32(), type::AddressSpace::kPrivate, Expr(2.1_f));
 
     Build();
 }
@@ -1211,7 +1212,7 @@
     const auto type_sym = Sym("TYPE");
     const auto func_sym = Sym("FUNC");
 
-    const auto* value_decl = GlobalVar(value_sym, ty.i32(), ast::AddressSpace::kPrivate);
+    const auto* value_decl = GlobalVar(value_sym, ty.i32(), type::AddressSpace::kPrivate);
     const auto* type_decl = Alias(type_sym, ty.i32());
     const auto* func_decl = Func(func_sym, utils::Empty, ty.void_(), utils::Empty);
 
@@ -1289,14 +1290,14 @@
     GlobalVar(Sym(), ty.array(T, V, 4));
     GlobalVar(Sym(), ty.vec3(T));
     GlobalVar(Sym(), ty.mat3x2(T));
-    GlobalVar(Sym(), ty.pointer(T, ast::AddressSpace::kPrivate));
-    GlobalVar(Sym(), ty.sampled_texture(ast::TextureDimension::k2d, T));
-    GlobalVar(Sym(), ty.depth_texture(ast::TextureDimension::k2d));
-    GlobalVar(Sym(), ty.depth_multisampled_texture(ast::TextureDimension::k2d));
+    GlobalVar(Sym(), ty.pointer(T, type::AddressSpace::kPrivate));
+    GlobalVar(Sym(), ty.sampled_texture(type::TextureDimension::k2d, T));
+    GlobalVar(Sym(), ty.depth_texture(type::TextureDimension::k2d));
+    GlobalVar(Sym(), ty.depth_multisampled_texture(type::TextureDimension::k2d));
     GlobalVar(Sym(), ty.external_texture());
-    GlobalVar(Sym(), ty.multisampled_texture(ast::TextureDimension::k2d, T));
-    GlobalVar(Sym(), ty.storage_texture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Float,
-                                        ast::Access::kRead));  //
+    GlobalVar(Sym(), ty.multisampled_texture(type::TextureDimension::k2d, T));
+    GlobalVar(Sym(), ty.storage_texture(type::TextureDimension::k2d, type::TexelFormat::kR32Float,
+                                        type::Access::kRead));  //
     GlobalVar(Sym(), ty.sampler(ast::SamplerKind::kSampler));
 
     GlobalVar(Sym(), ty.i32(), utils::Vector{Binding(V), Group(V)});
diff --git a/src/tint/resolver/entry_point_validation_test.cc b/src/tint/resolver/entry_point_validation_test.cc
index cd49ded..9a026c7 100644
--- a/src/tint/resolver/entry_point_validation_test.cc
+++ b/src/tint/resolver/entry_point_validation_test.cc
@@ -453,14 +453,14 @@
     // enable chromium_experimental_push_constant;
     // var<push_constant> a : u32;
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
-    GlobalVar("a", ty.u32(), ast::AddressSpace::kPushConstant);
+    GlobalVar("a", ty.u32(), type::AddressSpace::kPushConstant);
 
     EXPECT_TRUE(r()->Resolve());
 }
 
 TEST_F(ResolverEntryPointValidationTest, PushConstantDisallowedWithoutEnable) {
     // var<push_constant> a : u32;
-    GlobalVar(Source{{1, 2}}, "a", ty.u32(), ast::AddressSpace::kPushConstant);
+    GlobalVar(Source{{1, 2}}, "a", ty.u32(), type::AddressSpace::kPushConstant);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -470,7 +470,7 @@
 
 TEST_F(ResolverEntryPointValidationTest, PushConstantAllowedWithIgnoreAddressSpaceAttribute) {
     // var<push_constant> a : u32; // With ast::DisabledValidation::kIgnoreAddressSpace
-    GlobalVar("a", ty.u32(), ast::AddressSpace::kPushConstant,
+    GlobalVar("a", ty.u32(), type::AddressSpace::kPushConstant,
               utils::Vector{Disable(ast::DisabledValidation::kIgnoreAddressSpace)});
 
     EXPECT_TRUE(r()->Resolve());
@@ -483,7 +483,7 @@
     //   _ = a;
     // }
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
-    GlobalVar("a", ty.u32(), ast::AddressSpace::kPushConstant);
+    GlobalVar("a", ty.u32(), type::AddressSpace::kPushConstant);
 
     Func("main", {}, ty.void_(), utils::Vector{Assign(Phony(), "a")},
          utils::Vector{Stage(ast::PipelineStage::kCompute),
@@ -501,8 +501,8 @@
     //   _ = b;
     // }
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
-    GlobalVar(Source{{1, 2}}, "a", ty.u32(), ast::AddressSpace::kPushConstant);
-    GlobalVar(Source{{3, 4}}, "b", ty.u32(), ast::AddressSpace::kPushConstant);
+    GlobalVar(Source{{1, 2}}, "a", ty.u32(), type::AddressSpace::kPushConstant);
+    GlobalVar(Source{{3, 4}}, "b", ty.u32(), type::AddressSpace::kPushConstant);
 
     Func(Source{{5, 6}}, "main", {}, ty.void_(),
          utils::Vector{Assign(Phony(), "a"), Assign(Phony(), "b")},
@@ -532,8 +532,8 @@
     //   uses_b();
     // }
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
-    GlobalVar(Source{{1, 2}}, "a", ty.u32(), ast::AddressSpace::kPushConstant);
-    GlobalVar(Source{{3, 4}}, "b", ty.u32(), ast::AddressSpace::kPushConstant);
+    GlobalVar(Source{{1, 2}}, "a", ty.u32(), type::AddressSpace::kPushConstant);
+    GlobalVar(Source{{3, 4}}, "b", ty.u32(), type::AddressSpace::kPushConstant);
 
     Func(Source{{5, 6}}, "uses_a", {}, ty.void_(), utils::Vector{Assign(Phony(), "a")});
     Func(Source{{7, 8}}, "uses_b", {}, ty.void_(), utils::Vector{Assign(Phony(), "b")});
@@ -565,8 +565,8 @@
     //   _ = a;
     // }
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
-    GlobalVar("a", ty.u32(), ast::AddressSpace::kPushConstant);
-    GlobalVar("b", ty.u32(), ast::AddressSpace::kPushConstant);
+    GlobalVar("a", ty.u32(), type::AddressSpace::kPushConstant);
+    GlobalVar("b", ty.u32(), type::AddressSpace::kPushConstant);
 
     Func("uses_a", {}, ty.void_(), utils::Vector{Assign(Phony(), "a")},
          utils::Vector{Stage(ast::PipelineStage::kCompute),
diff --git a/src/tint/resolver/f16_extension_test.cc b/src/tint/resolver/f16_extension_test.cc
index 4bcf6cc..8e5271e 100644
--- a/src/tint/resolver/f16_extension_test.cc
+++ b/src/tint/resolver/f16_extension_test.cc
@@ -29,14 +29,14 @@
     // var<private> v : f16;
     Enable(ast::Extension::kF16);
 
-    GlobalVar("v", ty.f16(), ast::AddressSpace::kPrivate);
+    GlobalVar("v", ty.f16(), type::AddressSpace::kPrivate);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverF16ExtensionTest, TypeUsedWithoutExtension) {
     // var<private> v : f16;
-    GlobalVar("v", ty.f16(Source{{12, 34}}), ast::AddressSpace::kPrivate);
+    GlobalVar("v", ty.f16(Source{{12, 34}}), type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: f16 type used without 'f16' extension enabled");
@@ -47,14 +47,14 @@
     // var<private> v : vec2<f16>;
     Enable(ast::Extension::kF16);
 
-    GlobalVar("v", ty.vec2<f16>(), ast::AddressSpace::kPrivate);
+    GlobalVar("v", ty.vec2<f16>(), type::AddressSpace::kPrivate);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverF16ExtensionTest, Vec2TypeUsedWithoutExtension) {
     // var<private> v : vec2<f16>;
-    GlobalVar("v", ty.vec2(ty.f16(Source{{12, 34}})), ast::AddressSpace::kPrivate);
+    GlobalVar("v", ty.vec2(ty.f16(Source{{12, 34}})), type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: f16 type used without 'f16' extension enabled");
@@ -65,14 +65,14 @@
     // var<private> v = vec2<f16>();
     Enable(ast::Extension::kF16);
 
-    GlobalVar("v", Construct(ty.vec2<f16>()), ast::AddressSpace::kPrivate);
+    GlobalVar("v", Construct(ty.vec2<f16>()), type::AddressSpace::kPrivate);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverF16ExtensionTest, Vec2TypeInitUsedWithoutExtension) {
     // var<private> v = vec2<f16>();
-    GlobalVar("v", Construct(ty.vec2(ty.f16(Source{{12, 34}}))), ast::AddressSpace::kPrivate);
+    GlobalVar("v", Construct(ty.vec2(ty.f16(Source{{12, 34}}))), type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: f16 type used without 'f16' extension enabled");
@@ -84,7 +84,7 @@
     Enable(ast::Extension::kF16);
 
     GlobalVar("v", Construct(ty.vec2<f16>(), Construct(ty.vec2<f32>())),
-              ast::AddressSpace::kPrivate);
+              type::AddressSpace::kPrivate);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -92,7 +92,7 @@
 TEST_F(ResolverF16ExtensionTest, Vec2TypeConvUsedWithoutExtension) {
     // var<private> v = vec2<f16>(vec2<f32>());
     GlobalVar("v", Construct(ty.vec2(ty.f16(Source{{12, 34}})), Construct(ty.vec2<f32>())),
-              ast::AddressSpace::kPrivate);
+              type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: f16 type used without 'f16' extension enabled");
@@ -103,14 +103,14 @@
     // var<private> v = 16h;
     Enable(ast::Extension::kF16);
 
-    GlobalVar("v", Expr(16_h), ast::AddressSpace::kPrivate);
+    GlobalVar("v", Expr(16_h), type::AddressSpace::kPrivate);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverF16ExtensionTest, F16LiteralUsedWithoutExtension) {
     // var<private> v = 16h;
-    GlobalVar("v", Expr(Source{{12, 34}}, 16_h), ast::AddressSpace::kPrivate);
+    GlobalVar("v", Expr(Source{{12, 34}}, 16_h), type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: f16 type used without 'f16' extension enabled");
@@ -123,14 +123,14 @@
     // var<private> v : vec2h;
     Enable(ast::Extension::kF16);
 
-    GlobalVar("v", ty.type_name(Source{{12, 34}}, GetParam()), ast::AddressSpace::kPrivate);
+    GlobalVar("v", ty.type_name(Source{{12, 34}}, GetParam()), type::AddressSpace::kPrivate);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_P(ResolverF16ExtensionShortNameTest, Vec2hTypeUsedWithoutExtension) {
     // var<private> v : vec2h;
-    GlobalVar("v", ty.type_name(Source{{12, 34}}, GetParam()), ast::AddressSpace::kPrivate);
+    GlobalVar("v", ty.type_name(Source{{12, 34}}, GetParam()), type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: f16 type used without 'f16' extension enabled");
diff --git a/src/tint/resolver/function_validation_test.cc b/src/tint/resolver/function_validation_test.cc
index ef40bff..0c075d7 100644
--- a/src/tint/resolver/function_validation_test.cc
+++ b/src/tint/resolver/function_validation_test.cc
@@ -39,7 +39,7 @@
 TEST_F(ResolverFunctionValidationTest, ParameterMayShadowGlobal) {
     // var<private> common_name : f32;
     // fn func(common_name : f32) { }
-    GlobalVar("common_name", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("common_name", ty.f32(), type::AddressSpace::kPrivate);
     Func("func", utils::Vector{Param("common_name", ty.f32())}, ty.void_(), utils::Empty);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -420,7 +420,7 @@
          utils::Vector{
              Return(1_i),
          });
-    GlobalVar("x", Call(Source{{12, 34}}, "F"), ast::AddressSpace::kPrivate);
+    GlobalVar("x", Call(Source{{12, 34}}, "F"), type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), R"(12:34 error: functions cannot be called at module-scope)");
@@ -874,7 +874,7 @@
     // var<private> x = 64i;
     // @compute @workgroup_size(x)
     // fn main() {}
-    GlobalVar("x", ty.i32(), ast::AddressSpace::kPrivate, Expr(64_i));
+    GlobalVar("x", ty.i32(), type::AddressSpace::kPrivate, Expr(64_i));
     Func("main", utils::Empty, ty.void_(), utils::Empty,
          utils::Vector{
              Stage(ast::PipelineStage::kCompute),
@@ -890,7 +890,7 @@
 TEST_F(ResolverFunctionValidationTest, WorkgroupSize_InvalidExpr_x) {
     // @compute @workgroup_size(1 << 2 + 4)
     // fn main() {}
-    GlobalVar("x", ty.i32(), ast::AddressSpace::kPrivate, Expr(0_i));
+    GlobalVar("x", ty.i32(), type::AddressSpace::kPrivate, Expr(0_i));
     Func("main", utils::Empty, ty.void_(), utils::Empty,
          utils::Vector{
              Stage(ast::PipelineStage::kCompute),
@@ -906,7 +906,7 @@
 TEST_F(ResolverFunctionValidationTest, WorkgroupSize_InvalidExpr_y) {
     // @compute @workgroup_size(1, 1 << 2 + 4)
     // fn main() {}
-    GlobalVar("x", ty.i32(), ast::AddressSpace::kPrivate, Expr(0_i));
+    GlobalVar("x", ty.i32(), type::AddressSpace::kPrivate, Expr(0_i));
     Func("main", utils::Empty, ty.void_(), utils::Empty,
          utils::Vector{
              Stage(ast::PipelineStage::kCompute),
@@ -922,7 +922,7 @@
 TEST_F(ResolverFunctionValidationTest, WorkgroupSize_InvalidExpr_z) {
     // @compute @workgroup_size(1, 1, 1 << 2 + 4)
     // fn main() {}
-    GlobalVar("x", ty.i32(), ast::AddressSpace::kPrivate, Expr(0_i));
+    GlobalVar("x", ty.i32(), type::AddressSpace::kPrivate, Expr(0_i));
     Func("main", utils::Empty, ty.void_(), utils::Empty,
          utils::Vector{
              Stage(ast::PipelineStage::kCompute),
@@ -936,7 +936,7 @@
 }
 
 TEST_F(ResolverFunctionValidationTest, ReturnIsConstructible_NonPlain) {
-    auto* ret_type = ty.pointer(Source{{12, 34}}, ty.i32(), ast::AddressSpace::kFunction);
+    auto* ret_type = ty.pointer(Source{{12, 34}}, ty.i32(), type::AddressSpace::kFunction);
     Func("f", utils::Empty, ret_type, utils::Empty);
 
     EXPECT_FALSE(r()->Resolve());
@@ -1050,7 +1050,7 @@
     kAlwaysFail,
 };
 struct TestParams {
-    ast::AddressSpace address_space;
+    type::AddressSpace address_space;
     Expectation expectation;
 };
 
@@ -1094,15 +1094,15 @@
     ResolverTest,
     ResolverFunctionParameterValidationTest,
     testing::Values(
-        TestParams{ast::AddressSpace::kNone, Expectation::kAlwaysFail},
-        TestParams{ast::AddressSpace::kIn, Expectation::kAlwaysFail},
-        TestParams{ast::AddressSpace::kOut, Expectation::kAlwaysFail},
-        TestParams{ast::AddressSpace::kUniform, Expectation::kPassWithFullPtrParameterExtension},
-        TestParams{ast::AddressSpace::kWorkgroup, Expectation::kPassWithFullPtrParameterExtension},
-        TestParams{ast::AddressSpace::kHandle, Expectation::kAlwaysFail},
-        TestParams{ast::AddressSpace::kStorage, Expectation::kPassWithFullPtrParameterExtension},
-        TestParams{ast::AddressSpace::kPrivate, Expectation::kAlwaysPass},
-        TestParams{ast::AddressSpace::kFunction, Expectation::kAlwaysPass}));
+        TestParams{type::AddressSpace::kNone, Expectation::kAlwaysFail},
+        TestParams{type::AddressSpace::kIn, Expectation::kAlwaysFail},
+        TestParams{type::AddressSpace::kOut, Expectation::kAlwaysFail},
+        TestParams{type::AddressSpace::kUniform, Expectation::kPassWithFullPtrParameterExtension},
+        TestParams{type::AddressSpace::kWorkgroup, Expectation::kPassWithFullPtrParameterExtension},
+        TestParams{type::AddressSpace::kHandle, Expectation::kAlwaysFail},
+        TestParams{type::AddressSpace::kStorage, Expectation::kPassWithFullPtrParameterExtension},
+        TestParams{type::AddressSpace::kPrivate, Expectation::kAlwaysPass},
+        TestParams{type::AddressSpace::kFunction, Expectation::kAlwaysPass}));
 
 }  // namespace
 }  // namespace tint::resolver
diff --git a/src/tint/resolver/host_shareable_validation_test.cc b/src/tint/resolver/host_shareable_validation_test.cc
index 325595c..1035842 100644
--- a/src/tint/resolver/host_shareable_validation_test.cc
+++ b/src/tint/resolver/host_shareable_validation_test.cc
@@ -29,7 +29,7 @@
     auto* s =
         Structure("S", utils::Vector{Member(Source{{56, 78}}, "x", ty.bool_(Source{{12, 34}}))});
 
-    GlobalVar(Source{{90, 12}}, "g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{90, 12}}, "g", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead,
               Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
@@ -45,7 +45,7 @@
     auto* s = Structure(
         "S", utils::Vector{Member(Source{{56, 78}}, "x", ty.vec3<bool>(Source{{12, 34}}))});
 
-    GlobalVar(Source{{90, 12}}, "g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{90, 12}}, "g", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead,
               Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
@@ -62,7 +62,7 @@
     auto* s = Structure(
         "S", utils::Vector{Member(Source{{56, 78}}, "x", ty.type_name(Source{{12, 34}}, "a1"))});
     auto* a2 = Alias("a2", ty.Of(s));
-    GlobalVar(Source{{90, 12}}, "g", ty.Of(a2), ast::AddressSpace::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{90, 12}}, "g", ty.Of(a2), type::AddressSpace::kStorage, type::Access::kRead,
               Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
@@ -81,7 +81,7 @@
 
     auto* s = Structure("S", utils::Vector{Member(Source{{7, 8}}, "m", ty.Of(i3))});
 
-    GlobalVar(Source{{9, 10}}, "g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{9, 10}}, "g", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead,
               Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
@@ -120,7 +120,7 @@
 
     auto* s = Structure("S", utils::Vector{Member(Source{{7, 8}}, "m", ty.Of(i3))});
 
-    GlobalVar(Source{{9, 10}}, "g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{9, 10}}, "g", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead,
               Binding(0_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
diff --git a/src/tint/resolver/increment_decrement_validation_test.cc b/src/tint/resolver/increment_decrement_validation_test.cc
index e822de3..9f41f3a 100644
--- a/src/tint/resolver/increment_decrement_validation_test.cc
+++ b/src/tint/resolver/increment_decrement_validation_test.cc
@@ -64,8 +64,8 @@
     // var a : i32;
     // let b : ptr<function,i32> = &a;
     // *b++;
-    auto* var_a = Var("a", ty.i32(), ast::AddressSpace::kFunction);
-    auto* var_b = Let("b", ty.pointer<i32>(ast::AddressSpace::kFunction), AddressOf(Expr("a")));
+    auto* var_a = Var("a", ty.i32(), type::AddressSpace::kFunction);
+    auto* var_b = Let("b", ty.pointer<i32>(type::AddressSpace::kFunction), AddressOf(Expr("a")));
     WrapInFunction(var_a, var_b, Increment(Source{{12, 34}}, Deref("b")));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -127,7 +127,7 @@
 TEST_F(ResolverIncrementDecrementValidationTest, Atomic) {
     // var<workgroup> a : atomic<i32>;
     // a++;
-    GlobalVar(Source{{12, 34}}, "a", ty.atomic(ty.i32()), ast::AddressSpace::kWorkgroup);
+    GlobalVar(Source{{12, 34}}, "a", ty.atomic(ty.i32()), type::AddressSpace::kWorkgroup);
     WrapInFunction(Increment(Expr(Source{{56, 78}}, "a")));
 
     EXPECT_FALSE(r()->Resolve());
@@ -193,7 +193,7 @@
     // {
     //   a++;
     // }
-    GlobalVar(Source{{12, 34}}, "a", ty.i32(), ast::AddressSpace::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{12, 34}}, "a", ty.i32(), type::AddressSpace::kStorage, type::Access::kRead,
               Group(0_a), Binding(0_a));
     WrapInFunction(Increment(Source{{56, 78}}, "a"));
 
diff --git a/src/tint/resolver/inferred_type_test.cc b/src/tint/resolver/inferred_type_test.cc
index 6406bea..0835275 100644
--- a/src/tint/resolver/inferred_type_test.cc
+++ b/src/tint/resolver/inferred_type_test.cc
@@ -97,7 +97,7 @@
 
     // var a = <type initializer>;
     auto* ctor_expr = params.create_value(*this, 0);
-    auto* var = GlobalVar("a", ast::AddressSpace::kPrivate, ctor_expr);
+    auto* var = GlobalVar("a", type::AddressSpace::kPrivate, ctor_expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
     EXPECT_EQ(TypeOf(var)->UnwrapRef(), expected_type);
@@ -124,7 +124,7 @@
 
     // var a = <type initializer>;
     auto* ctor_expr = params.create_value(*this, 0);
-    auto* var = Var("a", ast::AddressSpace::kFunction, ctor_expr);
+    auto* var = Var("a", type::AddressSpace::kFunction, ctor_expr);
     WrapInFunction(var);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -139,7 +139,7 @@
         create<type::U32>(), create<type::ConstantArrayCount>(10u), 4u, 4u * 10u, 4u, 4u);
 
     auto* ctor_expr = Construct(type);
-    auto* var = Var("a", ast::AddressSpace::kFunction, ctor_expr);
+    auto* var = Var("a", type::AddressSpace::kFunction, ctor_expr);
     WrapInFunction(var);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -158,7 +158,7 @@
 
     auto* ctor_expr = Construct(ty.Of(str));
 
-    auto* var = Var("a", ast::AddressSpace::kFunction, ctor_expr);
+    auto* var = Var("a", type::AddressSpace::kFunction, ctor_expr);
     WrapInFunction(var);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
diff --git a/src/tint/resolver/intrinsic_table.cc b/src/tint/resolver/intrinsic_table.cc
index 4b507b8..3d51c63 100644
--- a/src/tint/resolver/intrinsic_table.cc
+++ b/src/tint/resolver/intrinsic_table.cc
@@ -34,6 +34,7 @@
 #include "src/tint/type/multisampled_texture.h"
 #include "src/tint/type/sampled_texture.h"
 #include "src/tint/type/storage_texture.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/utils/hash.h"
 #include "src/tint/utils/hashmap.h"
 #include "src/tint/utils/math.h"
@@ -327,9 +328,9 @@
 // TODO(bclayton): See if we can move more of this hand-rolled code to the
 // template
 ////////////////////////////////////////////////////////////////////////////////
-using TexelFormat = ast::TexelFormat;
-using Access = ast::Access;
-using AddressSpace = ast::AddressSpace;
+using TexelFormat = type::TexelFormat;
+using Access = type::Access;
+using AddressSpace = type::AddressSpace;
 using ParameterUsage = sem::ParameterUsage;
 using PipelineStage = ast::PipelineStage;
 
@@ -559,8 +560,8 @@
 }
 
 const type::Pointer* build_ptr(MatchState& state, Number S, const type::Type* T, Number& A) {
-    return state.builder.create<type::Pointer>(T, static_cast<ast::AddressSpace>(S.Value()),
-                                               static_cast<ast::Access>(A.Value()));
+    return state.builder.create<type::Pointer>(T, static_cast<type::AddressSpace>(S.Value()),
+                                               static_cast<type::Access>(A.Value()));
 }
 
 bool match_atomic(MatchState&, const type::Type* ty, const type::Type*& T) {
@@ -605,7 +606,7 @@
 
 bool match_texture(MatchState&,
                    const type::Type* ty,
-                   ast::TextureDimension dim,
+                   type::TextureDimension dim,
                    const type::Type*& T) {
     if (ty->Is<Any>()) {
         T = ty;
@@ -632,17 +633,17 @@
         return state.builder.create<type::SampledTexture>(dim, T);                  \
     }
 
-DECLARE_SAMPLED_TEXTURE(1d, ast::TextureDimension::k1d)
-DECLARE_SAMPLED_TEXTURE(2d, ast::TextureDimension::k2d)
-DECLARE_SAMPLED_TEXTURE(2d_array, ast::TextureDimension::k2dArray)
-DECLARE_SAMPLED_TEXTURE(3d, ast::TextureDimension::k3d)
-DECLARE_SAMPLED_TEXTURE(cube, ast::TextureDimension::kCube)
-DECLARE_SAMPLED_TEXTURE(cube_array, ast::TextureDimension::kCubeArray)
+DECLARE_SAMPLED_TEXTURE(1d, type::TextureDimension::k1d)
+DECLARE_SAMPLED_TEXTURE(2d, type::TextureDimension::k2d)
+DECLARE_SAMPLED_TEXTURE(2d_array, type::TextureDimension::k2dArray)
+DECLARE_SAMPLED_TEXTURE(3d, type::TextureDimension::k3d)
+DECLARE_SAMPLED_TEXTURE(cube, type::TextureDimension::kCube)
+DECLARE_SAMPLED_TEXTURE(cube_array, type::TextureDimension::kCubeArray)
 #undef DECLARE_SAMPLED_TEXTURE
 
 bool match_texture_multisampled(MatchState&,
                                 const type::Type* ty,
-                                ast::TextureDimension dim,
+                                type::TextureDimension dim,
                                 const type::Type*& T) {
     if (ty->Is<Any>()) {
         T = ty;
@@ -667,10 +668,10 @@
         return state.builder.create<type::MultisampledTexture>(dim, T);                      \
     }
 
-DECLARE_MULTISAMPLED_TEXTURE(2d, ast::TextureDimension::k2d)
+DECLARE_MULTISAMPLED_TEXTURE(2d, type::TextureDimension::k2d)
 #undef DECLARE_MULTISAMPLED_TEXTURE
 
-bool match_texture_depth(MatchState&, const type::Type* ty, ast::TextureDimension dim) {
+bool match_texture_depth(MatchState&, const type::Type* ty, type::TextureDimension dim) {
     if (ty->Is<Any>()) {
         return true;
     }
@@ -685,10 +686,10 @@
         return state.builder.create<type::DepthTexture>(dim);                           \
     }
 
-DECLARE_DEPTH_TEXTURE(2d, ast::TextureDimension::k2d)
-DECLARE_DEPTH_TEXTURE(2d_array, ast::TextureDimension::k2dArray)
-DECLARE_DEPTH_TEXTURE(cube, ast::TextureDimension::kCube)
-DECLARE_DEPTH_TEXTURE(cube_array, ast::TextureDimension::kCubeArray)
+DECLARE_DEPTH_TEXTURE(2d, type::TextureDimension::k2d)
+DECLARE_DEPTH_TEXTURE(2d_array, type::TextureDimension::k2dArray)
+DECLARE_DEPTH_TEXTURE(cube, type::TextureDimension::kCube)
+DECLARE_DEPTH_TEXTURE(cube_array, type::TextureDimension::kCubeArray)
 #undef DECLARE_DEPTH_TEXTURE
 
 bool match_texture_depth_multisampled_2d(MatchState&, const type::Type* ty) {
@@ -696,17 +697,17 @@
         return true;
     }
     return ty->Is([&](const type::DepthMultisampledTexture* t) {
-        return t->dim() == ast::TextureDimension::k2d;
+        return t->dim() == type::TextureDimension::k2d;
     });
 }
 
 type::DepthMultisampledTexture* build_texture_depth_multisampled_2d(MatchState& state) {
-    return state.builder.create<type::DepthMultisampledTexture>(ast::TextureDimension::k2d);
+    return state.builder.create<type::DepthMultisampledTexture>(type::TextureDimension::k2d);
 }
 
 bool match_texture_storage(MatchState&,
                            const type::Type* ty,
-                           ast::TextureDimension dim,
+                           type::TextureDimension dim,
                            Number& F,
                            Number& A) {
     if (ty->Is<Any>()) {
@@ -737,10 +738,10 @@
         return state.builder.create<type::StorageTexture>(dim, format, access, T);                 \
     }
 
-DECLARE_STORAGE_TEXTURE(1d, ast::TextureDimension::k1d)
-DECLARE_STORAGE_TEXTURE(2d, ast::TextureDimension::k2d)
-DECLARE_STORAGE_TEXTURE(2d_array, ast::TextureDimension::k2dArray)
-DECLARE_STORAGE_TEXTURE(3d, ast::TextureDimension::k3d)
+DECLARE_STORAGE_TEXTURE(1d, type::TextureDimension::k1d)
+DECLARE_STORAGE_TEXTURE(2d, type::TextureDimension::k2d)
+DECLARE_STORAGE_TEXTURE(2d_array, type::TextureDimension::k2dArray)
+DECLARE_STORAGE_TEXTURE(3d, type::TextureDimension::k3d)
 #undef DECLARE_STORAGE_TEXTURE
 
 bool match_texture_external(MatchState&, const type::Type* ty) {
@@ -1274,8 +1275,8 @@
         params.Reserve(match.parameters.Length());
         for (auto& p : match.parameters) {
             params.Push(builder.create<sem::Parameter>(
-                nullptr, static_cast<uint32_t>(params.Length()), p.type, ast::AddressSpace::kNone,
-                ast::Access::kUndefined, p.usage));
+                nullptr, static_cast<uint32_t>(params.Length()), p.type, type::AddressSpace::kNone,
+                type::Access::kUndefined, p.usage));
         }
         sem::PipelineStageSet supported_stages;
         if (match.overload->flags.Contains(OverloadFlag::kSupportsVertexPipeline)) {
@@ -1475,8 +1476,8 @@
         params.Reserve(match.parameters.Length());
         for (auto& p : match.parameters) {
             params.Push(builder.create<sem::Parameter>(
-                nullptr, static_cast<uint32_t>(params.Length()), p.type, ast::AddressSpace::kNone,
-                ast::Access::kUndefined, p.usage));
+                nullptr, static_cast<uint32_t>(params.Length()), p.type, type::AddressSpace::kNone,
+                type::Access::kUndefined, p.usage));
         }
         auto eval_stage = match.overload->const_eval_fn ? sem::EvaluationStage::kConstant
                                                         : sem::EvaluationStage::kRuntime;
@@ -1490,8 +1491,8 @@
     // Conversion.
     auto* target = converters.GetOrCreate(match, [&]() {
         auto param = builder.create<sem::Parameter>(
-            nullptr, 0u, match.parameters[0].type, ast::AddressSpace::kNone,
-            ast::Access::kUndefined, match.parameters[0].usage);
+            nullptr, 0u, match.parameters[0].type, type::AddressSpace::kNone,
+            type::Access::kUndefined, match.parameters[0].usage);
         auto eval_stage = match.overload->const_eval_fn ? sem::EvaluationStage::kConstant
                                                         : sem::EvaluationStage::kRuntime;
         return builder.create<sem::TypeConversion>(match.return_type, param, eval_stage);
diff --git a/src/tint/resolver/intrinsic_table_test.cc b/src/tint/resolver/intrinsic_table_test.cc
index bb17bae..e0d32f3 100644
--- a/src/tint/resolver/intrinsic_table_test.cc
+++ b/src/tint/resolver/intrinsic_table_test.cc
@@ -30,6 +30,7 @@
 #include "src/tint/type/sampled_texture.h"
 #include "src/tint/type/storage_texture.h"
 #include "src/tint/type/test_helper.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::resolver {
 namespace {
@@ -97,7 +98,7 @@
     auto* f32 = create<type::F32>();
     auto* i32 = create<type::I32>();
     auto* vec4_f32 = create<type::Vector>(f32, 4u);
-    auto* tex = create<type::SampledTexture>(ast::TextureDimension::k1d, f32);
+    auto* tex = create<type::SampledTexture>(type::TextureDimension::k1d, f32);
     auto result = table->Lookup(BuiltinType::kTextureLoad, utils::Vector{tex, i32, i32},
                                 sem::EvaluationStage::kConstant, Source{});
     ASSERT_NE(result.sem, nullptr) << Diagnostics().str();
@@ -115,7 +116,7 @@
 
 TEST_F(IntrinsicTableTest, MismatchI32) {
     auto* f32 = create<type::F32>();
-    auto* tex = create<type::SampledTexture>(ast::TextureDimension::k1d, f32);
+    auto* tex = create<type::SampledTexture>(type::TextureDimension::k1d, f32);
     auto result = table->Lookup(BuiltinType::kTextureLoad, utils::Vector{tex, f32},
                                 sem::EvaluationStage::kConstant, Source{});
     ASSERT_EQ(result.sem, nullptr);
@@ -231,7 +232,7 @@
     auto* i32 = create<type::I32>();
     auto* atomicI32 = create<type::Atomic>(i32);
     auto* ptr =
-        create<type::Pointer>(atomicI32, ast::AddressSpace::kWorkgroup, ast::Access::kReadWrite);
+        create<type::Pointer>(atomicI32, type::AddressSpace::kWorkgroup, type::Access::kReadWrite);
     auto result = table->Lookup(BuiltinType::kAtomicLoad, utils::Vector{ptr},
                                 sem::EvaluationStage::kConstant, Source{});
     ASSERT_NE(result.sem, nullptr) << Diagnostics().str();
@@ -255,7 +256,7 @@
     auto* arr =
         create<type::Array>(create<type::U32>(), create<type::RuntimeArrayCount>(), 4u, 4u, 4u, 4u);
     auto* arr_ptr =
-        create<type::Pointer>(arr, ast::AddressSpace::kStorage, ast::Access::kReadWrite);
+        create<type::Pointer>(arr, type::AddressSpace::kStorage, type::Access::kReadWrite);
     auto result = table->Lookup(BuiltinType::kArrayLength, utils::Vector{arr_ptr},
                                 sem::EvaluationStage::kConstant, Source{});
     ASSERT_NE(result.sem, nullptr) << Diagnostics().str();
@@ -280,7 +281,7 @@
     auto* f32 = create<type::F32>();
     auto* vec2_f32 = create<type::Vector>(f32, 2u);
     auto* vec4_f32 = create<type::Vector>(f32, 4u);
-    auto* tex = create<type::SampledTexture>(ast::TextureDimension::k2d, f32);
+    auto* tex = create<type::SampledTexture>(type::TextureDimension::k2d, f32);
     auto* sampler = create<type::Sampler>(ast::SamplerKind::kSampler);
     auto result = table->Lookup(BuiltinType::kTextureSample, utils::Vector{tex, sampler, vec2_f32},
                                 sem::EvaluationStage::kConstant, Source{});
@@ -300,7 +301,7 @@
 TEST_F(IntrinsicTableTest, MismatchSampler) {
     auto* f32 = create<type::F32>();
     auto* vec2_f32 = create<type::Vector>(f32, 2u);
-    auto* tex = create<type::SampledTexture>(ast::TextureDimension::k2d, f32);
+    auto* tex = create<type::SampledTexture>(type::TextureDimension::k2d, f32);
     auto result = table->Lookup(BuiltinType::kTextureSample, utils::Vector{tex, f32, vec2_f32},
                                 sem::EvaluationStage::kConstant, Source{});
     ASSERT_EQ(result.sem, nullptr);
@@ -312,7 +313,7 @@
     auto* f32 = create<type::F32>();
     auto* vec2_i32 = create<type::Vector>(i32, 2u);
     auto* vec4_f32 = create<type::Vector>(f32, 4u);
-    auto* tex = create<type::SampledTexture>(ast::TextureDimension::k2d, f32);
+    auto* tex = create<type::SampledTexture>(type::TextureDimension::k2d, f32);
     auto result = table->Lookup(BuiltinType::kTextureLoad, utils::Vector{tex, vec2_i32, i32},
                                 sem::EvaluationStage::kConstant, Source{});
     ASSERT_NE(result.sem, nullptr) << Diagnostics().str();
@@ -333,7 +334,7 @@
     auto* f32 = create<type::F32>();
     auto* vec2_i32 = create<type::Vector>(i32, 2u);
     auto* vec4_f32 = create<type::Vector>(f32, 4u);
-    auto* tex = create<type::MultisampledTexture>(ast::TextureDimension::k2d, f32);
+    auto* tex = create<type::MultisampledTexture>(type::TextureDimension::k2d, f32);
     auto result = table->Lookup(BuiltinType::kTextureLoad, utils::Vector{tex, vec2_i32, i32},
                                 sem::EvaluationStage::kConstant, Source{});
     ASSERT_NE(result.sem, nullptr) << Diagnostics().str();
@@ -353,7 +354,7 @@
     auto* f32 = create<type::F32>();
     auto* i32 = create<type::I32>();
     auto* vec2_i32 = create<type::Vector>(i32, 2u);
-    auto* tex = create<type::DepthTexture>(ast::TextureDimension::k2d);
+    auto* tex = create<type::DepthTexture>(type::TextureDimension::k2d);
     auto result = table->Lookup(BuiltinType::kTextureLoad, utils::Vector{tex, vec2_i32, i32},
                                 sem::EvaluationStage::kConstant, Source{});
     ASSERT_NE(result.sem, nullptr) << Diagnostics().str();
@@ -373,7 +374,7 @@
     auto* f32 = create<type::F32>();
     auto* i32 = create<type::I32>();
     auto* vec2_i32 = create<type::Vector>(i32, 2u);
-    auto* tex = create<type::DepthMultisampledTexture>(ast::TextureDimension::k2d);
+    auto* tex = create<type::DepthMultisampledTexture>(type::TextureDimension::k2d);
     auto result = table->Lookup(BuiltinType::kTextureLoad, utils::Vector{tex, vec2_i32, i32},
                                 sem::EvaluationStage::kConstant, Source{});
     ASSERT_NE(result.sem, nullptr) << Diagnostics().str();
@@ -413,9 +414,9 @@
     auto* i32 = create<type::I32>();
     auto* vec2_i32 = create<type::Vector>(i32, 2u);
     auto* vec4_f32 = create<type::Vector>(f32, 4u);
-    auto* subtype = type::StorageTexture::SubtypeFor(ast::TexelFormat::kR32Float, Types());
+    auto* subtype = type::StorageTexture::SubtypeFor(type::TexelFormat::kR32Float, Types());
     auto* tex = create<type::StorageTexture>(
-        ast::TextureDimension::k2d, ast::TexelFormat::kR32Float, ast::Access::kWrite, subtype);
+        type::TextureDimension::k2d, type::TexelFormat::kR32Float, type::Access::kWrite, subtype);
 
     auto result = table->Lookup(BuiltinType::kTextureStore, utils::Vector{tex, vec2_i32, vec4_f32},
                                 sem::EvaluationStage::kConstant, Source{});
@@ -447,7 +448,7 @@
     auto result = table->Lookup(
         BuiltinType::kCos,
         utils::Vector{
-            create<type::Reference>(f32, ast::AddressSpace::kFunction, ast::Access::kReadWrite),
+            create<type::Reference>(f32, type::AddressSpace::kFunction, type::Access::kReadWrite),
         },
         sem::EvaluationStage::kConstant, Source{});
     ASSERT_NE(result.sem, nullptr) << Diagnostics().str();
@@ -547,8 +548,8 @@
 
 TEST_F(IntrinsicTableTest, MatchDifferentArgsElementType_Builtin_RuntimeEval) {
     auto* af = create<type::AbstractFloat>();
-    auto* bool_ref = create<type::Reference>(create<type::Bool>(), ast::AddressSpace::kFunction,
-                                             ast::Access::kReadWrite);
+    auto* bool_ref = create<type::Reference>(create<type::Bool>(), type::AddressSpace::kFunction,
+                                             type::Access::kReadWrite);
     auto result = table->Lookup(BuiltinType::kSelect, utils::Vector{af, af, bool_ref},
                                 sem::EvaluationStage::kRuntime, Source{});
     ASSERT_NE(result.sem, nullptr) << Diagnostics().str();
@@ -629,7 +630,7 @@
 }
 
 TEST_F(IntrinsicTableTest, OverloadOrderByMatchingParameter) {
-    auto* tex = create<type::DepthTexture>(ast::TextureDimension::k2d);
+    auto* tex = create<type::DepthTexture>(type::TextureDimension::k2d);
     auto* bool_ = create<type::Bool>();
     table->Lookup(BuiltinType::kTextureDimensions, utils::Vector{tex, bool_},
                   sem::EvaluationStage::kConstant, Source{});
diff --git a/src/tint/resolver/is_host_shareable_test.cc b/src/tint/resolver/is_host_shareable_test.cc
index 1bc38b4..8696900 100644
--- a/src/tint/resolver/is_host_shareable_test.cc
+++ b/src/tint/resolver/is_host_shareable_test.cc
@@ -95,8 +95,8 @@
 }
 
 TEST_F(ResolverIsHostShareable, Pointer) {
-    auto* ptr = create<type::Pointer>(create<type::I32>(), ast::AddressSpace::kPrivate,
-                                      ast::Access::kReadWrite);
+    auto* ptr = create<type::Pointer>(create<type::I32>(), type::AddressSpace::kPrivate,
+                                      type::Access::kReadWrite);
     EXPECT_FALSE(r()->IsHostShareable(ptr));
 }
 
diff --git a/src/tint/resolver/is_storeable_test.cc b/src/tint/resolver/is_storeable_test.cc
index 58c0871..bfe64c4 100644
--- a/src/tint/resolver/is_storeable_test.cc
+++ b/src/tint/resolver/is_storeable_test.cc
@@ -78,8 +78,8 @@
 }
 
 TEST_F(ResolverIsStorableTest, Pointer) {
-    auto* ptr = create<type::Pointer>(create<type::I32>(), ast::AddressSpace::kPrivate,
-                                      ast::Access::kReadWrite);
+    auto* ptr = create<type::Pointer>(create<type::I32>(), type::AddressSpace::kPrivate,
+                                      type::Access::kReadWrite);
     EXPECT_FALSE(r()->IsStorable(ptr));
 }
 
@@ -112,7 +112,7 @@
 TEST_F(ResolverIsStorableTest, Struct_SomeMembersNonStorable) {
     Structure("S", utils::Vector{
                        Member("a", ty.i32()),
-                       Member("b", ty.pointer<i32>(ast::AddressSpace::kPrivate)),
+                       Member("b", ty.pointer<i32>(type::AddressSpace::kPrivate)),
                    });
 
     EXPECT_FALSE(r()->Resolve());
@@ -138,7 +138,7 @@
     auto* non_storable =
         Structure("nonstorable", utils::Vector{
                                      Member("a", ty.i32()),
-                                     Member("b", ty.pointer<i32>(ast::AddressSpace::kPrivate)),
+                                     Member("b", ty.pointer<i32>(type::AddressSpace::kPrivate)),
                                  });
     Structure("S", utils::Vector{
                        Member("a", ty.i32()),
diff --git a/src/tint/resolver/load_test.cc b/src/tint/resolver/load_test.cc
index fea60ff..a97b011 100644
--- a/src/tint/resolver/load_test.cc
+++ b/src/tint/resolver/load_test.cc
@@ -12,14 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#include "src/tint/sem/load.h"
+#include "gmock/gmock.h"
 #include "src/tint/resolver/resolver.h"
 #include "src/tint/resolver/resolver_test_helper.h"
 #include "src/tint/sem/test_helper.h"
-
-#include "src/tint/sem/load.h"
 #include "src/tint/type/reference.h"
-
-#include "gmock/gmock.h"
+#include "src/tint/type/texture_dimension.h"
 
 using namespace tint::number_suffixes;  // NOLINT
 
@@ -220,12 +219,12 @@
     //   return textureSampleLevel(tp, sp, vec2(), 0);
     // }
     // f(t, s);
-    GlobalVar("t", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
+    GlobalVar("t", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()),
               utils::Vector{Group(0_a), Binding(0_a)});
     GlobalVar("s", ty.sampler(ast::SamplerKind::kSampler), utils::Vector{Group(0_a), Binding(1_a)});
     Func("f",
          utils::Vector{
-             Param("tp", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32())),
+             Param("tp", ty.sampled_texture(type::TextureDimension::k2d, ty.f32())),
              Param("sp", ty.sampler(ast::SamplerKind::kSampler)),
          },
          ty.vec4<f32>(),
diff --git a/src/tint/resolver/materialize_test.cc b/src/tint/resolver/materialize_test.cc
index 49da494..3f7740f 100644
--- a/src/tint/resolver/materialize_test.cc
+++ b/src/tint/resolver/materialize_test.cc
@@ -929,7 +929,7 @@
             break;
         }
         case Method::kIndex: {
-            GlobalVar("arr", ty.array<i32, 4>(), ast::AddressSpace::kPrivate);
+            GlobalVar("arr", ty.array<i32, 4>(), type::AddressSpace::kPrivate);
             WrapInFunction(IndexAccessor("arr", abstract_expr()));
             break;
         }
diff --git a/src/tint/resolver/override_test.cc b/src/tint/resolver/override_test.cc
index 8d6b8e7..69102c7 100644
--- a/src/tint/resolver/override_test.cc
+++ b/src/tint/resolver/override_test.cc
@@ -159,7 +159,7 @@
 
 TEST_F(ResolverOverrideTest, TransitiveReferences_ViaPrivateInit) {
     auto* a = Override("a", ty.f32());
-    auto* b = GlobalVar("b", ast::AddressSpace::kPrivate, ty.f32(), Mul(2_a, "a"));
+    auto* b = GlobalVar("b", type::AddressSpace::kPrivate, ty.f32(), Mul(2_a, "a"));
     Override("unused", ty.f32(), Expr(1_f));
     auto* func = Func("foo", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -209,7 +209,7 @@
     auto* a = Override("a", ty.i32());
     auto* b = Override("b", ty.i32(), Mul(2_a, "a"));
     auto* arr_ty = ty.array(ty.i32(), Mul(2_a, "b"));
-    auto* arr = GlobalVar("arr", ast::AddressSpace::kWorkgroup, arr_ty);
+    auto* arr = GlobalVar("arr", type::AddressSpace::kWorkgroup, arr_ty);
     Override("unused", ty.i32(), Expr(1_a));
     auto* func = Func("foo", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -249,7 +249,7 @@
     auto* a = Override("a", ty.i32());
     auto* b = Override("b", ty.i32(), Mul(2_a, "a"));
     auto* arr_ty = Alias("arr_ty", ty.array(ty.i32(), Mul(2_a, "b")));
-    auto* arr = GlobalVar("arr", ast::AddressSpace::kWorkgroup, ty.type_name("arr_ty"));
+    auto* arr = GlobalVar("arr", type::AddressSpace::kWorkgroup, ty.type_name("arr_ty"));
     Override("unused", ty.i32(), Expr(1_a));
     auto* func = Func("foo", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -294,8 +294,8 @@
     auto* d = Override("d", ty.i32());
     Alias("arr_ty1", ty.array(ty.i32(), Mul("b1", "c1")));
     Alias("arr_ty2", ty.array(ty.i32(), Mul("b2", "c2")));
-    auto* arr1 = GlobalVar("arr1", ast::AddressSpace::kWorkgroup, ty.type_name("arr_ty1"));
-    auto* arr2 = GlobalVar("arr2", ast::AddressSpace::kWorkgroup, ty.type_name("arr_ty2"));
+    auto* arr1 = GlobalVar("arr1", type::AddressSpace::kWorkgroup, ty.type_name("arr_ty1"));
+    auto* arr2 = GlobalVar("arr2", type::AddressSpace::kWorkgroup, ty.type_name("arr_ty2"));
     Override("unused", ty.i32(), Expr(1_a));
     auto* func1 = Func("foo1", utils::Empty, ty.void_(),
                        utils::Vector{
diff --git a/src/tint/resolver/ptr_ref_test.cc b/src/tint/resolver/ptr_ref_test.cc
index 4176423..64b21ae 100644
--- a/src/tint/resolver/ptr_ref_test.cc
+++ b/src/tint/resolver/ptr_ref_test.cc
@@ -39,7 +39,7 @@
 
     ASSERT_TRUE(TypeOf(expr)->Is<type::Pointer>());
     EXPECT_TRUE(TypeOf(expr)->As<type::Pointer>()->StoreType()->Is<type::I32>());
-    EXPECT_EQ(TypeOf(expr)->As<type::Pointer>()->AddressSpace(), ast::AddressSpace::kFunction);
+    EXPECT_EQ(TypeOf(expr)->As<type::Pointer>()->AddressSpace(), type::AddressSpace::kFunction);
 }
 
 TEST_F(ResolverPtrRefTest, AddressOfThenDeref) {
@@ -68,23 +68,23 @@
 
     auto* buf = Structure("S", utils::Vector{Member("m", ty.i32())});
     auto* function = Var("f", ty.i32());
-    auto* private_ = GlobalVar("p", ty.i32(), ast::AddressSpace::kPrivate);
-    auto* workgroup = GlobalVar("w", ty.i32(), ast::AddressSpace::kWorkgroup);
+    auto* private_ = GlobalVar("p", ty.i32(), type::AddressSpace::kPrivate);
+    auto* workgroup = GlobalVar("w", ty.i32(), type::AddressSpace::kWorkgroup);
     auto* uniform =
-        GlobalVar("ub", ty.Of(buf), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a));
+        GlobalVar("ub", ty.Of(buf), type::AddressSpace::kUniform, Binding(0_a), Group(0_a));
     auto* storage =
-        GlobalVar("sb", ty.Of(buf), ast::AddressSpace::kStorage, Binding(1_a), Group(0_a));
+        GlobalVar("sb", ty.Of(buf), type::AddressSpace::kStorage, Binding(1_a), Group(0_a));
 
     auto* function_ptr =
-        Let("f_ptr", ty.pointer(ty.i32(), ast::AddressSpace::kFunction), AddressOf(function));
+        Let("f_ptr", ty.pointer(ty.i32(), type::AddressSpace::kFunction), AddressOf(function));
     auto* private_ptr =
-        Let("p_ptr", ty.pointer(ty.i32(), ast::AddressSpace::kPrivate), AddressOf(private_));
+        Let("p_ptr", ty.pointer(ty.i32(), type::AddressSpace::kPrivate), AddressOf(private_));
     auto* workgroup_ptr =
-        Let("w_ptr", ty.pointer(ty.i32(), ast::AddressSpace::kWorkgroup), AddressOf(workgroup));
+        Let("w_ptr", ty.pointer(ty.i32(), type::AddressSpace::kWorkgroup), AddressOf(workgroup));
     auto* uniform_ptr =
-        Let("ub_ptr", ty.pointer(ty.Of(buf), ast::AddressSpace::kUniform), AddressOf(uniform));
+        Let("ub_ptr", ty.pointer(ty.Of(buf), type::AddressSpace::kUniform), AddressOf(uniform));
     auto* storage_ptr =
-        Let("sb_ptr", ty.pointer(ty.Of(buf), ast::AddressSpace::kStorage), AddressOf(storage));
+        Let("sb_ptr", ty.pointer(ty.Of(buf), type::AddressSpace::kStorage), AddressOf(storage));
 
     WrapInFunction(function, function_ptr, private_ptr, workgroup_ptr, uniform_ptr, storage_ptr);
 
@@ -101,11 +101,11 @@
     ASSERT_TRUE(TypeOf(storage_ptr)->Is<type::Pointer>())
         << "storage_ptr is " << TypeOf(storage_ptr)->TypeInfo().name;
 
-    EXPECT_EQ(TypeOf(function_ptr)->As<type::Pointer>()->Access(), ast::Access::kReadWrite);
-    EXPECT_EQ(TypeOf(private_ptr)->As<type::Pointer>()->Access(), ast::Access::kReadWrite);
-    EXPECT_EQ(TypeOf(workgroup_ptr)->As<type::Pointer>()->Access(), ast::Access::kReadWrite);
-    EXPECT_EQ(TypeOf(uniform_ptr)->As<type::Pointer>()->Access(), ast::Access::kRead);
-    EXPECT_EQ(TypeOf(storage_ptr)->As<type::Pointer>()->Access(), ast::Access::kRead);
+    EXPECT_EQ(TypeOf(function_ptr)->As<type::Pointer>()->Access(), type::Access::kReadWrite);
+    EXPECT_EQ(TypeOf(private_ptr)->As<type::Pointer>()->Access(), type::Access::kReadWrite);
+    EXPECT_EQ(TypeOf(workgroup_ptr)->As<type::Pointer>()->Access(), type::Access::kReadWrite);
+    EXPECT_EQ(TypeOf(uniform_ptr)->As<type::Pointer>()->Access(), type::Access::kRead);
+    EXPECT_EQ(TypeOf(storage_ptr)->As<type::Pointer>()->Access(), type::Access::kRead);
 }
 
 }  // namespace
diff --git a/src/tint/resolver/ptr_ref_validation_test.cc b/src/tint/resolver/ptr_ref_validation_test.cc
index efd77a6..9f6f390 100644
--- a/src/tint/resolver/ptr_ref_validation_test.cc
+++ b/src/tint/resolver/ptr_ref_validation_test.cc
@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#include "gmock/gmock.h"
 #include "src/tint/ast/bitcast_expression.h"
 #include "src/tint/resolver/resolver.h"
 #include "src/tint/resolver/resolver_test_helper.h"
 #include "src/tint/type/reference.h"
-
-#include "gmock/gmock.h"
+#include "src/tint/type/texture_dimension.h"
 
 using namespace tint::number_suffixes;  // NOLINT
 
@@ -54,7 +54,7 @@
 TEST_F(ResolverPtrRefValidationTest, AddressOfHandle) {
     // @group(0) @binding(0) var t: texture_3d<f32>;
     // &t
-    GlobalVar("t", ty.sampled_texture(ast::TextureDimension::k3d, ty.f32()), Group(0_a),
+    GlobalVar("t", ty.sampled_texture(type::TextureDimension::k3d, ty.f32()), Group(0_a),
               Binding(0_a));
     auto* expr = AddressOf(Expr(Source{{12, 34}}, "t"));
     WrapInFunction(expr);
@@ -94,7 +94,7 @@
 TEST_F(ResolverPtrRefValidationTest, IndirectOfAddressOfHandle) {
     // @group(0) @binding(0) var t: texture_3d<f32>;
     // *&t
-    GlobalVar("t", ty.sampled_texture(ast::TextureDimension::k3d, ty.f32()), Group(0_a),
+    GlobalVar("t", ty.sampled_texture(type::TextureDimension::k3d, ty.f32()), Group(0_a),
               Binding(0_a));
     auto* expr = Deref(AddressOf(Expr(Source{{12, 34}}, "t")));
     WrapInFunction(expr);
@@ -143,12 +143,12 @@
     // }
     auto* inner = Structure("Inner", utils::Vector{Member("arr", ty.array<i32, 4>())});
     auto* buf = Structure("S", utils::Vector{Member("inner", ty.Of(inner))});
-    auto* storage = GlobalVar("s", ty.Of(buf), ast::AddressSpace::kStorage, ast::Access::kReadWrite,
-                              Binding(0_a), Group(0_a));
+    auto* storage = GlobalVar("s", ty.Of(buf), type::AddressSpace::kStorage,
+                              type::Access::kReadWrite, Binding(0_a), Group(0_a));
 
     auto* expr = IndexAccessor(MemberAccessor(MemberAccessor(storage, "inner"), "arr"), 2_i);
     auto* ptr =
-        Let(Source{{12, 34}}, "p", ty.pointer<i32>(ast::AddressSpace::kStorage), AddressOf(expr));
+        Let(Source{{12, 34}}, "p", ty.pointer<i32>(type::AddressSpace::kStorage), AddressOf(expr));
 
     WrapInFunction(ptr);
 
diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc
index 48c310f..3f306b5 100644
--- a/src/tint/resolver/resolver.cc
+++ b/src/tint/resolver/resolver.cc
@@ -257,7 +257,7 @@
         [&](const ast::Pointer* t) -> type::Pointer* {
             if (auto* el = Type(t->type)) {
                 auto access = t->access;
-                if (access == ast::Access::kUndefined) {
+                if (access == type::Access::kUndefined) {
                     access = DefaultAccessForAddressSpace(t->address_space);
                 }
                 auto ptr = builder_->create<type::Pointer>(el, t->address_space, access);
@@ -391,11 +391,11 @@
         ty = rhs->Type()->UnwrapRef();  // Implicit load of RHS
     }
 
-    if (rhs && !validator_.VariableInitializer(v, ast::AddressSpace::kNone, ty, rhs)) {
+    if (rhs && !validator_.VariableInitializer(v, type::AddressSpace::kNone, ty, rhs)) {
         return nullptr;
     }
 
-    if (!ApplyAddressSpaceUsageToType(ast::AddressSpace::kNone, const_cast<type::Type*>(ty),
+    if (!ApplyAddressSpaceUsageToType(type::AddressSpace::kNone, const_cast<type::Type*>(ty),
                                       v->source)) {
         AddNote("while instantiating 'let' " + builder_->Symbols().NameFor(v->symbol), v->source);
         return nullptr;
@@ -404,13 +404,13 @@
     sem::Variable* sem = nullptr;
     if (is_global) {
         sem = builder_->create<sem::GlobalVariable>(
-            v, ty, sem::EvaluationStage::kRuntime, ast::AddressSpace::kNone,
-            ast::Access::kUndefined,
+            v, ty, sem::EvaluationStage::kRuntime, type::AddressSpace::kNone,
+            type::Access::kUndefined,
             /* constant_value */ nullptr, sem::BindingPoint{}, std::nullopt);
     } else {
         sem = builder_->create<sem::LocalVariable>(v, ty, sem::EvaluationStage::kRuntime,
-                                                   ast::AddressSpace::kNone,
-                                                   ast::Access::kUndefined, current_statement_,
+                                                   type::AddressSpace::kNone,
+                                                   type::Access::kUndefined, current_statement_,
                                                    /* constant_value */ nullptr);
     }
 
@@ -453,11 +453,11 @@
         return nullptr;
     }
 
-    if (rhs && !validator_.VariableInitializer(v, ast::AddressSpace::kNone, ty, rhs)) {
+    if (rhs && !validator_.VariableInitializer(v, type::AddressSpace::kNone, ty, rhs)) {
         return nullptr;
     }
 
-    if (!ApplyAddressSpaceUsageToType(ast::AddressSpace::kNone, const_cast<type::Type*>(ty),
+    if (!ApplyAddressSpaceUsageToType(type::AddressSpace::kNone, const_cast<type::Type*>(ty),
                                       v->source)) {
         AddNote("while instantiating 'override' " + builder_->Symbols().NameFor(v->symbol),
                 v->source);
@@ -465,7 +465,7 @@
     }
 
     auto* sem = builder_->create<sem::GlobalVariable>(
-        v, ty, sem::EvaluationStage::kOverride, ast::AddressSpace::kNone, ast::Access::kUndefined,
+        v, ty, sem::EvaluationStage::kOverride, type::AddressSpace::kNone, type::Access::kUndefined,
         /* constant_value */ nullptr, sem::BindingPoint{}, std::nullopt);
     sem->SetInitializer(rhs);
 
@@ -546,11 +546,11 @@
         ty = rhs->Type();
     }
 
-    if (!validator_.VariableInitializer(c, ast::AddressSpace::kNone, ty, rhs)) {
+    if (!validator_.VariableInitializer(c, type::AddressSpace::kNone, ty, rhs)) {
         return nullptr;
     }
 
-    if (!ApplyAddressSpaceUsageToType(ast::AddressSpace::kNone, const_cast<type::Type*>(ty),
+    if (!ApplyAddressSpaceUsageToType(type::AddressSpace::kNone, const_cast<type::Type*>(ty),
                                       c->source)) {
         AddNote("while instantiating 'const' " + builder_->Symbols().NameFor(c->symbol), c->source);
         return nullptr;
@@ -558,11 +558,11 @@
 
     const auto value = rhs->ConstantValue();
     auto* sem = is_global ? static_cast<sem::Variable*>(builder_->create<sem::GlobalVariable>(
-                                c, ty, sem::EvaluationStage::kConstant, ast::AddressSpace::kNone,
-                                ast::Access::kUndefined, value, sem::BindingPoint{}, std::nullopt))
+                                c, ty, sem::EvaluationStage::kConstant, type::AddressSpace::kNone,
+                                type::Access::kUndefined, value, sem::BindingPoint{}, std::nullopt))
                           : static_cast<sem::Variable*>(builder_->create<sem::LocalVariable>(
-                                c, ty, sem::EvaluationStage::kConstant, ast::AddressSpace::kNone,
-                                ast::Access::kUndefined, current_statement_, value));
+                                c, ty, sem::EvaluationStage::kConstant, type::AddressSpace::kNone,
+                                type::Access::kUndefined, current_statement_, value));
 
     sem->SetInitializer(rhs);
     builder_->Sem().Add(c, sem);
@@ -606,20 +606,20 @@
     }
 
     auto address_space = var->declared_address_space;
-    if (address_space == ast::AddressSpace::kNone) {
+    if (address_space == type::AddressSpace::kNone) {
         // No declared address space. Infer from usage / type.
         if (!is_global) {
-            address_space = ast::AddressSpace::kFunction;
+            address_space = type::AddressSpace::kFunction;
         } else if (storage_ty->UnwrapRef()->is_handle()) {
             // https://gpuweb.github.io/gpuweb/wgsl/#module-scope-variables
             // If the store type is a texture type or a sampler type, then the
             // variable declaration must not have a address space attribute. The
             // address space will always be handle.
-            address_space = ast::AddressSpace::kHandle;
+            address_space = type::AddressSpace::kHandle;
         }
     }
 
-    if (!is_global && address_space != ast::AddressSpace::kFunction &&
+    if (!is_global && address_space != type::AddressSpace::kFunction &&
         validator_.IsValidationEnabled(var->attributes,
                                        ast::DisabledValidation::kIgnoreAddressSpace)) {
         AddError("function-scope 'var' declaration must use 'function' address space", var->source);
@@ -627,7 +627,7 @@
     }
 
     auto access = var->declared_access;
-    if (access == ast::Access::kUndefined) {
+    if (access == type::Access::kUndefined) {
         access = DefaultAccessForAddressSpace(address_space);
     }
 
@@ -740,7 +740,7 @@
         return nullptr;
     }
 
-    if (!ApplyAddressSpaceUsageToType(ast::AddressSpace::kNone, ty, param->type->source)) {
+    if (!ApplyAddressSpaceUsageToType(type::AddressSpace::kNone, ty, param->type->source)) {
         add_note();
         return nullptr;
     }
@@ -791,7 +791,7 @@
     }
 
     auto* sem = builder_->create<sem::Parameter>(
-        param, index, ty, ast::AddressSpace::kNone, ast::Access::kUndefined,
+        param, index, ty, type::AddressSpace::kNone, type::Access::kUndefined,
         sem::ParameterUsage::kNone, binding_point, location);
     builder_->Sem().Add(param, sem);
     return sem;
@@ -821,17 +821,17 @@
     return static_cast<uint32_t>(value);
 }
 
-ast::Access Resolver::DefaultAccessForAddressSpace(ast::AddressSpace address_space) {
+type::Access Resolver::DefaultAccessForAddressSpace(type::AddressSpace address_space) {
     // https://gpuweb.github.io/gpuweb/wgsl/#storage-class
     switch (address_space) {
-        case ast::AddressSpace::kStorage:
-        case ast::AddressSpace::kUniform:
-        case ast::AddressSpace::kHandle:
-            return ast::Access::kRead;
+        case type::AddressSpace::kStorage:
+        case type::AddressSpace::kUniform:
+        case type::AddressSpace::kHandle:
+            return type::Access::kRead;
         default:
             break;
     }
-    return ast::Access::kReadWrite;
+    return type::Access::kReadWrite;
 }
 
 bool Resolver::AllocateOverridableConstantIds() {
@@ -1036,7 +1036,7 @@
     }
 
     if (auto* str = return_type->As<sem::Struct>()) {
-        if (!ApplyAddressSpaceUsageToType(ast::AddressSpace::kNone, str, decl->source)) {
+        if (!ApplyAddressSpaceUsageToType(type::AddressSpace::kNone, str, decl->source)) {
             AddNote(
                 "while instantiating return type for " + builder_->Symbols().NameFor(decl->symbol),
                 decl->source);
@@ -2099,11 +2099,11 @@
                     [&]() -> sem::TypeInitializer* {
                         auto params = utils::Transform(args, [&](auto, size_t i) {
                             return builder_->create<sem::Parameter>(
-                                nullptr,                   // declaration
-                                static_cast<uint32_t>(i),  // index
-                                arr->ElemType(),           // type
-                                ast::AddressSpace::kNone,  // address_space
-                                ast::Access::kUndefined);
+                                nullptr,                    // declaration
+                                static_cast<uint32_t>(i),   // index
+                                arr->ElemType(),            // type
+                                type::AddressSpace::kNone,  // address_space
+                                type::Access::kUndefined);
                         });
                         return builder_->create<sem::TypeInitializer>(arr, std::move(params),
                                                                       args_stage);
@@ -2131,8 +2131,8 @@
                                 nullptr,                    // declaration
                                 static_cast<uint32_t>(i),   // index
                                 str->Members()[i]->Type(),  // type
-                                ast::AddressSpace::kNone,   // address_space
-                                ast::Access::kUndefined);   // access
+                                type::AddressSpace::kNone,  // address_space
+                                type::Access::kUndefined);  // access
                         }
                         return builder_->create<sem::TypeInitializer>(str, std::move(params),
                                                                       args_stage);
@@ -3759,7 +3759,7 @@
     });
 }
 
-bool Resolver::ApplyAddressSpaceUsageToType(ast::AddressSpace address_space,
+bool Resolver::ApplyAddressSpaceUsageToType(type::AddressSpace address_space,
                                             type::Type* ty,
                                             const Source& usage) {
     ty = const_cast<type::Type*>(ty->UnwrapRef());
@@ -3787,7 +3787,7 @@
     }
 
     if (auto* arr = ty->As<type::Array>()) {
-        if (address_space != ast::AddressSpace::kStorage) {
+        if (address_space != type::AddressSpace::kStorage) {
             if (arr->Count()->Is<type::RuntimeArrayCount>()) {
                 AddError("runtime-sized arrays can only be used in the <storage> address space",
                          usage);
@@ -3806,7 +3806,7 @@
                                             usage);
     }
 
-    if (ast::IsHostShareable(address_space) && !validator_.IsHostShareable(ty)) {
+    if (type::IsHostShareable(address_space) && !validator_.IsHostShareable(ty)) {
         std::stringstream err;
         err << "Type '" << sem_.TypeNameOf(ty) << "' cannot be used in address space '"
             << address_space << "' as it is non-host-shareable";
diff --git a/src/tint/resolver/resolver.h b/src/tint/resolver/resolver.h
index 1a29a75..38d08c0 100644
--- a/src/tint/resolver/resolver.h
+++ b/src/tint/resolver/resolver.h
@@ -378,11 +378,11 @@
     /// given type and address space. Used for generating sensible error
     /// messages.
     /// @returns true on success, false on error
-    bool ApplyAddressSpaceUsageToType(ast::AddressSpace sc, type::Type* ty, const Source& usage);
+    bool ApplyAddressSpaceUsageToType(type::AddressSpace sc, type::Type* ty, const Source& usage);
 
     /// @param address_space the address space
     /// @returns the default access control for the given address space
-    ast::Access DefaultAccessForAddressSpace(ast::AddressSpace address_space);
+    type::Access DefaultAccessForAddressSpace(type::AddressSpace address_space);
 
     /// Allocate constant IDs for pipeline-overridable constants.
     /// @returns true on success, false on error
diff --git a/src/tint/resolver/resolver_test.cc b/src/tint/resolver/resolver_test.cc
index e5538c5..8be16c1 100644
--- a/src/tint/resolver/resolver_test.cc
+++ b/src/tint/resolver/resolver_test.cc
@@ -44,6 +44,7 @@
 #include "src/tint/sem/variable.h"
 #include "src/tint/type/reference.h"
 #include "src/tint/type/sampled_texture.h"
+#include "src/tint/type/texture_dimension.h"
 
 using ::testing::ElementsAre;
 using ::testing::HasSubstr;
@@ -324,7 +325,7 @@
 
 TEST_F(ResolverTest, Stmt_VariableDecl_ModuleScope) {
     auto* init = Expr(2_i);
-    GlobalVar("my_var", ty.i32(), ast::AddressSpace::kPrivate, init);
+    GlobalVar("my_var", ty.i32(), type::AddressSpace::kPrivate, init);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
@@ -404,7 +405,7 @@
     Func("func_i32", utils::Empty, ty.void_(), utils::Vector{fn_i32_decl});
 
     // Declare f32 "foo" at module scope
-    auto* mod_f32 = Var("foo", ty.f32(), ast::AddressSpace::kPrivate, Expr(2_f));
+    auto* mod_f32 = Var("foo", ty.f32(), type::AddressSpace::kPrivate, Expr(2_f));
     auto* mod_init = mod_f32->initializer;
     AST().AddGlobalVariable(mod_f32);
 
@@ -432,7 +433,7 @@
 
 TEST_F(ResolverTest, ArraySize_UnsignedLiteral) {
     // var<private> a : array<f32, 10u>;
-    auto* a = GlobalVar("a", ty.array(ty.f32(), Expr(10_u)), ast::AddressSpace::kPrivate);
+    auto* a = GlobalVar("a", ty.array(ty.f32(), Expr(10_u)), type::AddressSpace::kPrivate);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
@@ -445,7 +446,7 @@
 
 TEST_F(ResolverTest, ArraySize_SignedLiteral) {
     // var<private> a : array<f32, 10i>;
-    auto* a = GlobalVar("a", ty.array(ty.f32(), Expr(10_i)), ast::AddressSpace::kPrivate);
+    auto* a = GlobalVar("a", ty.array(ty.f32(), Expr(10_i)), type::AddressSpace::kPrivate);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
@@ -460,7 +461,7 @@
     // const size = 10u;
     // var<private> a : array<f32, size>;
     GlobalConst("size", Expr(10_u));
-    auto* a = GlobalVar("a", ty.array(ty.f32(), Expr("size")), ast::AddressSpace::kPrivate);
+    auto* a = GlobalVar("a", ty.array(ty.f32(), Expr("size")), type::AddressSpace::kPrivate);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
@@ -475,7 +476,7 @@
     // const size = 0;
     // var<private> a : array<f32, size>;
     GlobalConst("size", Expr(10_i));
-    auto* a = GlobalVar("a", ty.array(ty.f32(), Expr("size")), ast::AddressSpace::kPrivate);
+    auto* a = GlobalVar("a", ty.array(ty.f32(), Expr("size")), type::AddressSpace::kPrivate);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
@@ -490,7 +491,7 @@
     // override size = 10i;
     // var<workgroup> a : array<f32, size>;
     auto* override = Override("size", Expr(10_i));
-    auto* a = GlobalVar("a", ty.array(ty.f32(), Expr("size")), ast::AddressSpace::kWorkgroup);
+    auto* a = GlobalVar("a", ty.array(ty.f32(), Expr("size")), type::AddressSpace::kWorkgroup);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
@@ -508,8 +509,8 @@
     // var<workgroup> a : array<f32, size>;
     // var<workgroup> b : array<f32, size>;
     auto* override = Override("size", Expr(10_i));
-    auto* a = GlobalVar("a", ty.array(ty.f32(), Expr("size")), ast::AddressSpace::kWorkgroup);
-    auto* b = GlobalVar("b", ty.array(ty.f32(), Expr("size")), ast::AddressSpace::kWorkgroup);
+    auto* a = GlobalVar("a", ty.array(ty.f32(), Expr("size")), type::AddressSpace::kWorkgroup);
+    auto* b = GlobalVar("b", ty.array(ty.f32(), Expr("size")), type::AddressSpace::kWorkgroup);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
@@ -535,7 +536,7 @@
     // var<workgroup> a : array<f32, size*2>;
     auto* override = Override("size", Expr(10_i));
     auto* cnt = Mul("size", 2_a);
-    auto* a = GlobalVar("a", ty.array(ty.f32(), cnt), ast::AddressSpace::kWorkgroup);
+    auto* a = GlobalVar("a", ty.array(ty.f32(), cnt), type::AddressSpace::kWorkgroup);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
@@ -555,8 +556,8 @@
     auto* override = Override("size", Expr(10_i));
     auto* a_cnt = Mul("size", 2_a);
     auto* b_cnt = Mul("size", 2_a);
-    auto* a = GlobalVar("a", ty.array(ty.f32(), a_cnt), ast::AddressSpace::kWorkgroup);
-    auto* b = GlobalVar("b", ty.array(ty.f32(), b_cnt), ast::AddressSpace::kWorkgroup);
+    auto* a = GlobalVar("a", ty.array(ty.f32(), a_cnt), type::AddressSpace::kWorkgroup);
+    auto* b = GlobalVar("b", ty.array(ty.f32(), b_cnt), type::AddressSpace::kWorkgroup);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
@@ -578,7 +579,7 @@
 }
 
 TEST_F(ResolverTest, Expr_Bitcast) {
-    GlobalVar("name", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("name", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* bitcast = create<ast::BitcastExpression>(ty.f32(), Expr("name"));
     WrapInFunction(bitcast);
@@ -641,7 +642,7 @@
 }
 
 TEST_F(ResolverTest, Expr_Cast) {
-    GlobalVar("name", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("name", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* cast = Construct(ty.f32(), "name");
     WrapInFunction(cast);
@@ -699,7 +700,7 @@
 }
 
 TEST_F(ResolverTest, Expr_Identifier_GlobalVariable) {
-    auto* my_var = GlobalVar("my_var", ty.f32(), ast::AddressSpace::kPrivate);
+    auto* my_var = GlobalVar("my_var", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* ident = Expr("my_var");
     WrapInFunction(ident);
@@ -800,7 +801,7 @@
     auto* v = Expr("v");
     auto* p = Expr("p");
     auto* v_decl = Decl(Var("v", ty.f32()));
-    auto* p_decl = Decl(Let("p", ty.pointer<f32>(ast::AddressSpace::kFunction), AddressOf(v)));
+    auto* p_decl = Decl(Let("p", ty.pointer<f32>(type::AddressSpace::kFunction), AddressOf(v)));
     auto* assign = Assign(Deref(p), 1.23_f);
     Func("my_func", utils::Empty, ty.void_(),
          utils::Vector{
@@ -875,7 +876,7 @@
     auto* param_b = Param("b", ty.u32(), utils::Vector{Builtin(ast::BuiltinValue::kVertexIndex)});
     auto* param_c = Param("c", ty.u32(), utils::Vector{Location(1_a)});
 
-    GlobalVar("my_vec", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_vec", ty.vec4<f32>(), type::AddressSpace::kPrivate);
     auto* func = Func("my_func",
                       utils::Vector{
                           param_a,
@@ -905,7 +906,7 @@
 
 TEST_F(ResolverTest, Function_GlobalVariable_Location) {
     auto* var = GlobalVar(
-        "my_vec", ty.vec4<f32>(), ast::AddressSpace::kIn,
+        "my_vec", ty.vec4<f32>(), type::AddressSpace::kIn,
         utils::Vector{Location(3_a), Disable(ast::DisabledValidation::kIgnoreAddressSpace)});
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -918,10 +919,10 @@
 TEST_F(ResolverTest, Function_RegisterInputOutputVariables) {
     auto* s = Structure("S", utils::Vector{Member("m", ty.u32())});
 
-    auto* sb_var = GlobalVar("sb_var", ty.Of(s), ast::AddressSpace::kStorage,
-                             ast::Access::kReadWrite, Binding(0_a), Group(0_a));
-    auto* wg_var = GlobalVar("wg_var", ty.f32(), ast::AddressSpace::kWorkgroup);
-    auto* priv_var = GlobalVar("priv_var", ty.f32(), ast::AddressSpace::kPrivate);
+    auto* sb_var = GlobalVar("sb_var", ty.Of(s), type::AddressSpace::kStorage,
+                             type::Access::kReadWrite, Binding(0_a), Group(0_a));
+    auto* wg_var = GlobalVar("wg_var", ty.f32(), type::AddressSpace::kWorkgroup);
+    auto* priv_var = GlobalVar("priv_var", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* func = Func("my_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -964,7 +965,7 @@
 }
 
 TEST_F(ResolverTest, Function_ReturnType_NoLocation) {
-    GlobalVar("my_vec", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_vec", ty.vec4<f32>(), type::AddressSpace::kPrivate);
     auto* func = Func("my_func", utils::Empty, ty.vec4<f32>(),
                       utils::Vector{
                           Return("my_vec"),
@@ -986,10 +987,10 @@
 TEST_F(ResolverTest, Function_RegisterInputOutputVariables_SubFunction) {
     auto* s = Structure("S", utils::Vector{Member("m", ty.u32())});
 
-    auto* sb_var = GlobalVar("sb_var", ty.Of(s), ast::AddressSpace::kStorage,
-                             ast::Access::kReadWrite, Binding(0_a), Group(0_a));
-    auto* wg_var = GlobalVar("wg_var", ty.f32(), ast::AddressSpace::kWorkgroup);
-    auto* priv_var = GlobalVar("priv_var", ty.f32(), ast::AddressSpace::kPrivate);
+    auto* sb_var = GlobalVar("sb_var", ty.Of(s), type::AddressSpace::kStorage,
+                             type::Access::kReadWrite, Binding(0_a), Group(0_a));
+    auto* wg_var = GlobalVar("wg_var", ty.f32(), type::AddressSpace::kWorkgroup);
+    auto* priv_var = GlobalVar("priv_var", ty.f32(), type::AddressSpace::kPrivate);
 
     Func("my_func", utils::Empty, ty.f32(),
          utils::Vector{Assign("wg_var", "wg_var"), Assign("sb_var", "sb_var"),
@@ -1240,7 +1241,7 @@
 TEST_F(ResolverTest, Expr_MemberAccessor_Struct) {
     auto* st = Structure(
         "S", utils::Vector{Member("first_member", ty.i32()), Member("second_member", ty.f32())});
-    GlobalVar("my_struct", ty.Of(st), ast::AddressSpace::kPrivate);
+    GlobalVar("my_struct", ty.Of(st), type::AddressSpace::kPrivate);
 
     auto* mem = MemberAccessor("my_struct", "second_member");
     WrapInFunction(mem);
@@ -1261,7 +1262,7 @@
     auto* st = Structure(
         "S", utils::Vector{Member("first_member", ty.i32()), Member("second_member", ty.f32())});
     auto* alias = Alias("alias", ty.Of(st));
-    GlobalVar("my_struct", ty.Of(alias), ast::AddressSpace::kPrivate);
+    GlobalVar("my_struct", ty.Of(alias), type::AddressSpace::kPrivate);
 
     auto* mem = MemberAccessor("my_struct", "second_member");
     WrapInFunction(mem);
@@ -1278,7 +1279,7 @@
 }
 
 TEST_F(ResolverTest, Expr_MemberAccessor_VectorSwizzle) {
-    GlobalVar("my_vec", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_vec", ty.vec4<f32>(), type::AddressSpace::kPrivate);
 
     auto* mem = MemberAccessor("my_vec", "xzyw");
     WrapInFunction(mem);
@@ -1296,7 +1297,7 @@
 }
 
 TEST_F(ResolverTest, Expr_MemberAccessor_VectorSwizzle_SingleElement) {
-    GlobalVar("my_vec", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_vec", ty.vec3<f32>(), type::AddressSpace::kPrivate);
 
     auto* mem = MemberAccessor("my_vec", "b");
     WrapInFunction(mem);
@@ -1329,7 +1330,7 @@
 
     auto* stB = Structure("B", utils::Vector{Member("foo", ty.vec4<f32>())});
     auto* stA = Structure("A", utils::Vector{Member("mem", ty.array(ty.Of(stB), 3_i))});
-    GlobalVar("c", ty.Of(stA), ast::AddressSpace::kPrivate);
+    GlobalVar("c", ty.Of(stA), type::AddressSpace::kPrivate);
 
     auto* mem =
         MemberAccessor(MemberAccessor(IndexAccessor(MemberAccessor("c", "mem"), 0_i), "foo"), "yx");
@@ -1347,7 +1348,7 @@
 TEST_F(ResolverTest, Expr_MemberAccessor_InBinaryOp) {
     auto* st = Structure(
         "S", utils::Vector{Member("first_member", ty.f32()), Member("second_member", ty.f32())});
-    GlobalVar("my_struct", ty.Of(st), ast::AddressSpace::kPrivate);
+    GlobalVar("my_struct", ty.Of(st), type::AddressSpace::kPrivate);
 
     auto* expr = Add(MemberAccessor("my_struct", "first_member"),
                      MemberAccessor("my_struct", "second_member"));
@@ -1650,8 +1651,8 @@
     ss << FriendlyName(lhs_type) << " " << params.op << " " << FriendlyName(rhs_type);
     SCOPED_TRACE(ss.str());
 
-    GlobalVar("lhs", lhs_type, ast::AddressSpace::kPrivate);
-    GlobalVar("rhs", rhs_type, ast::AddressSpace::kPrivate);
+    GlobalVar("lhs", lhs_type, type::AddressSpace::kPrivate);
+    GlobalVar("rhs", rhs_type, type::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(params.op, Expr("lhs"), Expr("rhs"));
     WrapInFunction(expr);
@@ -1685,8 +1686,8 @@
        << FriendlyName(rhs_type);
     SCOPED_TRACE(ss.str());
 
-    GlobalVar("lhs", lhs_type, ast::AddressSpace::kPrivate);
-    GlobalVar("rhs", rhs_type, ast::AddressSpace::kPrivate);
+    GlobalVar("lhs", lhs_type, type::AddressSpace::kPrivate);
+    GlobalVar("rhs", rhs_type, type::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(params.op, Expr("lhs"), Expr("rhs"));
     WrapInFunction(expr);
@@ -1731,8 +1732,8 @@
     ss << FriendlyName(lhs_type) << " " << op << " " << FriendlyName(rhs_type);
     SCOPED_TRACE(ss.str());
 
-    GlobalVar("lhs", lhs_type, ast::AddressSpace::kPrivate);
-    GlobalVar("rhs", rhs_type, ast::AddressSpace::kPrivate);
+    GlobalVar("lhs", lhs_type, type::AddressSpace::kPrivate);
+    GlobalVar("rhs", rhs_type, type::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(Source{{12, 34}}, op, Expr("lhs"), Expr("rhs"));
     WrapInFunction(expr);
@@ -1771,8 +1772,8 @@
         is_valid_expr = vec_size == mat_cols;
     }
 
-    GlobalVar("lhs", lhs_type, ast::AddressSpace::kPrivate);
-    GlobalVar("rhs", rhs_type, ast::AddressSpace::kPrivate);
+    GlobalVar("lhs", lhs_type, type::AddressSpace::kPrivate);
+    GlobalVar("rhs", rhs_type, type::AddressSpace::kPrivate);
 
     auto* expr = Mul(Source{{12, 34}}, Expr("lhs"), Expr("rhs"));
     WrapInFunction(expr);
@@ -1808,8 +1809,8 @@
     auto* col = create<type::Vector>(f32, lhs_mat_rows);
     auto* result_type = create<type::Matrix>(col, rhs_mat_cols);
 
-    GlobalVar("lhs", lhs_type, ast::AddressSpace::kPrivate);
-    GlobalVar("rhs", rhs_type, ast::AddressSpace::kPrivate);
+    GlobalVar("lhs", lhs_type, type::AddressSpace::kPrivate);
+    GlobalVar("rhs", rhs_type, type::AddressSpace::kPrivate);
 
     auto* expr = Mul(Source{{12, 34}}, Expr("lhs"), Expr("rhs"));
     WrapInFunction(expr);
@@ -1837,11 +1838,11 @@
     auto op = GetParam();
 
     if (op == ast::UnaryOp::kNot) {
-        GlobalVar("ident", ty.vec4<bool>(), ast::AddressSpace::kPrivate);
+        GlobalVar("ident", ty.vec4<bool>(), type::AddressSpace::kPrivate);
     } else if (op == ast::UnaryOp::kNegation || op == ast::UnaryOp::kComplement) {
-        GlobalVar("ident", ty.vec4<i32>(), ast::AddressSpace::kPrivate);
+        GlobalVar("ident", ty.vec4<i32>(), type::AddressSpace::kPrivate);
     } else {
-        GlobalVar("ident", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
+        GlobalVar("ident", ty.vec4<f32>(), type::AddressSpace::kPrivate);
     }
     auto* der = create<ast::UnaryOpExpression>(op, Expr("ident"));
     WrapInFunction(der);
@@ -1873,7 +1874,7 @@
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
-    EXPECT_EQ(Sem().Get(var)->AddressSpace(), ast::AddressSpace::kFunction);
+    EXPECT_EQ(Sem().Get(var)->AddressSpace(), type::AddressSpace::kFunction);
 }
 
 TEST_F(ResolverTest, AddressSpace_SetForSampler) {
@@ -1882,16 +1883,16 @@
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
-    EXPECT_EQ(Sem().Get(var)->AddressSpace(), ast::AddressSpace::kHandle);
+    EXPECT_EQ(Sem().Get(var)->AddressSpace(), type::AddressSpace::kHandle);
 }
 
 TEST_F(ResolverTest, AddressSpace_SetForTexture) {
-    auto* t = ty.sampled_texture(ast::TextureDimension::k1d, ty.f32());
+    auto* t = ty.sampled_texture(type::TextureDimension::k1d, ty.f32());
     auto* var = GlobalVar("var", t, Binding(0_a), Group(0_a));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
-    EXPECT_EQ(Sem().Get(var)->AddressSpace(), ast::AddressSpace::kHandle);
+    EXPECT_EQ(Sem().Get(var)->AddressSpace(), type::AddressSpace::kHandle);
 }
 
 TEST_F(ResolverTest, AddressSpace_DoesNotSetOnConst) {
@@ -1901,19 +1902,19 @@
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
-    EXPECT_EQ(Sem().Get(var)->AddressSpace(), ast::AddressSpace::kNone);
+    EXPECT_EQ(Sem().Get(var)->AddressSpace(), type::AddressSpace::kNone);
 }
 
 TEST_F(ResolverTest, Access_SetForStorageBuffer) {
     // struct S { x : i32 };
     // var<storage> g : S;
     auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.i32())});
-    auto* var = GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::AddressSpace::kStorage,
+    auto* var = GlobalVar(Source{{56, 78}}, "g", ty.Of(s), type::AddressSpace::kStorage,
                           Binding(0_a), Group(0_a));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
-    EXPECT_EQ(Sem().Get(var)->Access(), ast::Access::kRead);
+    EXPECT_EQ(Sem().Get(var)->Access(), type::Access::kRead);
 }
 
 TEST_F(ResolverTest, BindingPoint_SetForResources) {
@@ -1941,11 +1942,11 @@
     // ep_1 -> {}
     // ep_2 -> {}
 
-    GlobalVar("first", ty.f32(), ast::AddressSpace::kPrivate);
-    GlobalVar("second", ty.f32(), ast::AddressSpace::kPrivate);
-    GlobalVar("call_a", ty.f32(), ast::AddressSpace::kPrivate);
-    GlobalVar("call_b", ty.f32(), ast::AddressSpace::kPrivate);
-    GlobalVar("call_c", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("first", ty.f32(), type::AddressSpace::kPrivate);
+    GlobalVar("second", ty.f32(), type::AddressSpace::kPrivate);
+    GlobalVar("call_a", ty.f32(), type::AddressSpace::kPrivate);
+    GlobalVar("call_b", ty.f32(), type::AddressSpace::kPrivate);
+    GlobalVar("call_c", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* func_b = Func("b", utils::Empty, ty.f32(),
                         utils::Vector{
@@ -2085,8 +2086,8 @@
         {
             ProgramBuilder b;
             auto* expr = b.Expr(1_i);
-            b.GlobalVar("a", b.ty.i32(), ast::AddressSpace::kPrivate, expr);
-            b.GlobalVar("b", b.ty.i32(), ast::AddressSpace::kPrivate, expr);
+            b.GlobalVar("a", b.ty.i32(), type::AddressSpace::kPrivate, expr);
+            b.GlobalVar("b", b.ty.i32(), type::AddressSpace::kPrivate, expr);
             Resolver(&b).Resolve();
         },
         "internal compiler error: AST node 'tint::ast::IntLiteralExpression' was encountered twice "
@@ -2094,7 +2095,7 @@
 }
 
 TEST_F(ResolverTest, UnaryOp_Not) {
-    GlobalVar("ident", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("ident", ty.vec4<f32>(), type::AddressSpace::kPrivate);
     auto* der = create<ast::UnaryOpExpression>(ast::UnaryOp::kNot, Expr(Source{{12, 34}}, "ident"));
     WrapInFunction(der);
 
@@ -2103,7 +2104,7 @@
 }
 
 TEST_F(ResolverTest, UnaryOp_Complement) {
-    GlobalVar("ident", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("ident", ty.vec4<f32>(), type::AddressSpace::kPrivate);
     auto* der =
         create<ast::UnaryOpExpression>(ast::UnaryOp::kComplement, Expr(Source{{12, 34}}, "ident"));
     WrapInFunction(der);
@@ -2113,7 +2114,7 @@
 }
 
 TEST_F(ResolverTest, UnaryOp_Negation) {
-    GlobalVar("ident", ty.u32(), ast::AddressSpace::kPrivate);
+    GlobalVar("ident", ty.u32(), type::AddressSpace::kPrivate);
     auto* der =
         create<ast::UnaryOpExpression>(ast::UnaryOp::kNegation, Expr(Source{{12, 34}}, "ident"));
     WrapInFunction(der);
@@ -2123,7 +2124,7 @@
 }
 
 TEST_F(ResolverTest, TextureSampler_TextureSample) {
-    GlobalVar("t", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), Group(1_a),
+    GlobalVar("t", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()), Group(1_a),
               Binding(1_a));
     GlobalVar("s", ty.sampler(ast::SamplerKind::kSampler), Group(1_a), Binding(2_a));
 
@@ -2141,7 +2142,7 @@
 }
 
 TEST_F(ResolverTest, TextureSampler_TextureSampleInFunction) {
-    GlobalVar("t", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), Group(1_a),
+    GlobalVar("t", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()), Group(1_a),
               Binding(1_a));
     GlobalVar("s", ty.sampler(ast::SamplerKind::kSampler), Group(1_a), Binding(2_a));
 
@@ -2167,7 +2168,7 @@
 }
 
 TEST_F(ResolverTest, TextureSampler_TextureSampleFunctionDiamondSameVariables) {
-    GlobalVar("t", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), Group(1_a),
+    GlobalVar("t", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()), Group(1_a),
               Binding(1_a));
     GlobalVar("s", ty.sampler(ast::SamplerKind::kSampler), Group(1_a), Binding(2_a));
 
@@ -2202,9 +2203,9 @@
 }
 
 TEST_F(ResolverTest, TextureSampler_TextureSampleFunctionDiamondDifferentVariables) {
-    GlobalVar("t1", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), Group(1_a),
+    GlobalVar("t1", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()), Group(1_a),
               Binding(1_a));
-    GlobalVar("t2", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), Group(1_a),
+    GlobalVar("t2", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()), Group(1_a),
               Binding(2_a));
     GlobalVar("s", ty.sampler(ast::SamplerKind::kSampler), Group(1_a), Binding(3_a));
 
@@ -2241,7 +2242,7 @@
 }
 
 TEST_F(ResolverTest, TextureSampler_TextureDimensions) {
-    GlobalVar("t", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), Group(1_a),
+    GlobalVar("t", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()), Group(1_a),
               Binding(2_a));
 
     auto* call = Call("textureDimensions", "t");
@@ -2270,9 +2271,9 @@
     //     return textureSampleLevel(*tl, *sl, c, 0.0);
     // }
     GlobalVar("s", ty.sampler(ast::SamplerKind::kSampler), Group(0_a), Binding(0_a));
-    GlobalVar("t", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), Group(0_a),
+    GlobalVar("t", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()), Group(0_a),
               Binding(1_a));
-    GlobalVar("c", ty.vec2<f32>(), ast::AddressSpace::kUniform, Group(0_a), Binding(2_a));
+    GlobalVar("c", ty.vec2<f32>(), type::AddressSpace::kUniform, Group(0_a), Binding(2_a));
 
     Func("main", utils::Empty, ty.vec4<f32>(),
          utils::Vector{
@@ -2288,9 +2289,9 @@
     Func("helper",
          utils::Vector{
              Param("sl", ty.pointer(ty.sampler(ast::SamplerKind::kSampler),
-                                    ast::AddressSpace::kFunction)),
-             Param("tl", ty.pointer(ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
-                                    ast::AddressSpace::kFunction)),
+                                    type::AddressSpace::kFunction)),
+             Param("tl", ty.pointer(ty.sampled_texture(type::TextureDimension::k2d, ty.f32()),
+                                    type::AddressSpace::kFunction)),
          },
          ty.vec4<f32>(),
          utils::Vector{
@@ -2303,15 +2304,15 @@
 
 TEST_F(ResolverTest, ModuleDependencyOrderedDeclarations) {
     auto* f0 = Func("f0", utils::Empty, ty.void_(), utils::Empty);
-    auto* v0 = GlobalVar("v0", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* v0 = GlobalVar("v0", ty.i32(), type::AddressSpace::kPrivate);
     auto* a0 = Alias("a0", ty.i32());
     auto* s0 = Structure("s0", utils::Vector{Member("m", ty.i32())});
     auto* f1 = Func("f1", utils::Empty, ty.void_(), utils::Empty);
-    auto* v1 = GlobalVar("v1", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* v1 = GlobalVar("v1", ty.i32(), type::AddressSpace::kPrivate);
     auto* a1 = Alias("a1", ty.i32());
     auto* s1 = Structure("s1", utils::Vector{Member("m", ty.i32())});
     auto* f2 = Func("f2", utils::Empty, ty.void_(), utils::Empty);
-    auto* v2 = GlobalVar("v2", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* v2 = GlobalVar("v2", ty.i32(), type::AddressSpace::kPrivate);
     auto* a2 = Alias("a2", ty.i32());
     auto* s2 = Structure("s2", utils::Vector{Member("m", ty.i32())});
 
diff --git a/src/tint/resolver/resolver_test_helper.h b/src/tint/resolver/resolver_test_helper.h
index 53c187f..3158b63 100644
--- a/src/tint/resolver/resolver_test_helper.h
+++ b/src/tint/resolver/resolver_test_helper.h
@@ -616,14 +616,14 @@
     /// @param b the ProgramBuilder
     /// @return a new AST alias type
     static inline const ast::Type* AST(ProgramBuilder& b) {
-        return b.create<ast::Pointer>(DataType<T>::AST(b), ast::AddressSpace::kPrivate,
-                                      ast::Access::kUndefined);
+        return b.create<ast::Pointer>(DataType<T>::AST(b), type::AddressSpace::kPrivate,
+                                      type::Access::kUndefined);
     }
     /// @param b the ProgramBuilder
     /// @return the semantic aliased type
     static inline const type::Type* Sem(ProgramBuilder& b) {
-        return b.create<type::Pointer>(DataType<T>::Sem(b), ast::AddressSpace::kPrivate,
-                                       ast::Access::kReadWrite);
+        return b.create<type::Pointer>(DataType<T>::Sem(b), type::AddressSpace::kPrivate,
+                                       type::Access::kReadWrite);
     }
 
     /// @param b the ProgramBuilder
@@ -631,7 +631,7 @@
     static inline const ast::Expression* Expr(ProgramBuilder& b,
                                               utils::VectorRef<Scalar> /*unused*/) {
         auto sym = b.Symbols().New("global_for_ptr");
-        b.GlobalVar(sym, DataType<T>::AST(b), ast::AddressSpace::kPrivate);
+        b.GlobalVar(sym, DataType<T>::AST(b), type::AddressSpace::kPrivate);
         return b.AddressOf(sym);
     }
 
diff --git a/src/tint/resolver/root_identifier_test.cc b/src/tint/resolver/root_identifier_test.cc
index 934feae..9580695 100644
--- a/src/tint/resolver/root_identifier_test.cc
+++ b/src/tint/resolver/root_identifier_test.cc
@@ -17,6 +17,7 @@
 #include "src/tint/resolver/resolver_test_helper.h"
 #include "src/tint/sem/index_accessor_expression.h"
 #include "src/tint/sem/member_accessor_expression.h"
+#include "src/tint/type/texture_dimension.h"
 
 using namespace tint::number_suffixes;  // NOLINT
 
@@ -26,7 +27,7 @@
 class ResolverRootIdentifierTest : public ResolverTest {};
 
 TEST_F(ResolverRootIdentifierTest, GlobalPrivateVar) {
-    auto* a = GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
+    auto* a = GlobalVar("a", ty.f32(), type::AddressSpace::kPrivate);
     auto* expr = Expr(a);
     WrapInFunction(expr);
 
@@ -37,7 +38,7 @@
 }
 
 TEST_F(ResolverRootIdentifierTest, GlobalWorkgroupVar) {
-    auto* a = GlobalVar("a", ty.f32(), ast::AddressSpace::kWorkgroup);
+    auto* a = GlobalVar("a", ty.f32(), type::AddressSpace::kWorkgroup);
     auto* expr = Expr(a);
     WrapInFunction(expr);
 
@@ -48,7 +49,7 @@
 }
 
 TEST_F(ResolverRootIdentifierTest, GlobalStorageVar) {
-    auto* a = GlobalVar("a", ty.f32(), ast::AddressSpace::kStorage, Group(0_a), Binding(0_a));
+    auto* a = GlobalVar("a", ty.f32(), type::AddressSpace::kStorage, Group(0_a), Binding(0_a));
     auto* expr = Expr(a);
     WrapInFunction(expr);
 
@@ -59,7 +60,7 @@
 }
 
 TEST_F(ResolverRootIdentifierTest, GlobalUniformVar) {
-    auto* a = GlobalVar("a", ty.f32(), ast::AddressSpace::kUniform, Group(0_a), Binding(0_a));
+    auto* a = GlobalVar("a", ty.f32(), type::AddressSpace::kUniform, Group(0_a), Binding(0_a));
     auto* expr = Expr(a);
     WrapInFunction(expr);
 
@@ -70,8 +71,8 @@
 }
 
 TEST_F(ResolverRootIdentifierTest, GlobalTextureVar) {
-    auto* a = GlobalVar("a", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
-                        ast::AddressSpace::kNone, Group(0_a), Binding(0_a));
+    auto* a = GlobalVar("a", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()),
+                        type::AddressSpace::kNone, Group(0_a), Binding(0_a));
     auto* expr = Expr(a);
     WrapInFunction(Call("textureDimensions", expr));
 
@@ -141,7 +142,7 @@
     // {
     //   let b = a;
     // }
-    auto* param = Param("a", ty.pointer(ty.f32(), ast::AddressSpace::kFunction));
+    auto* param = Param("a", ty.pointer(ty.f32(), type::AddressSpace::kFunction));
     auto* expr_param = Expr(param);
     auto* let = Let("b", expr_param);
     auto* expr_let = Expr("b");
@@ -198,7 +199,7 @@
     // {
     //   a[2i]
     // }
-    auto* a = GlobalVar("a", ty.array(ty.f32(), 4_u), ast::AddressSpace::kPrivate);
+    auto* a = GlobalVar("a", ty.array(ty.f32(), 4_u), type::AddressSpace::kPrivate);
     auto* expr = IndexAccessor(a, 2_i);
     WrapInFunction(expr);
 
@@ -215,7 +216,7 @@
     //   a.f
     // }
     auto* S = Structure("S", utils::Vector{Member("f", ty.f32())});
-    auto* a = GlobalVar("a", ty.Of(S), ast::AddressSpace::kPrivate);
+    auto* a = GlobalVar("a", ty.Of(S), type::AddressSpace::kPrivate);
     auto* expr = MemberAccessor(a, "f");
     WrapInFunction(expr);
 
@@ -231,7 +232,7 @@
     //   let a_ptr1 = &*&a;
     //   let a_ptr2 = &*a_ptr1;
     // }
-    auto* a = GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
+    auto* a = GlobalVar("a", ty.f32(), type::AddressSpace::kPrivate);
     auto* address_of_1 = AddressOf(a);
     auto* deref_1 = Deref(address_of_1);
     auto* address_of_2 = AddressOf(deref_1);
diff --git a/src/tint/resolver/side_effects_test.cc b/src/tint/resolver/side_effects_test.cc
index 8265586..2fb95e2 100644
--- a/src/tint/resolver/side_effects_test.cc
+++ b/src/tint/resolver/side_effects_test.cc
@@ -19,6 +19,7 @@
 #include "src/tint/sem/expression.h"
 #include "src/tint/sem/index_accessor_expression.h"
 #include "src/tint/sem/member_accessor_expression.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/utils/vector.h"
 
 using namespace tint::number_suffixes;  // NOLINT
@@ -30,7 +31,7 @@
     template <typename T>
     void MakeSideEffectFunc(const char* name) {
         auto global = Sym();
-        GlobalVar(global, ty.Of<T>(), ast::AddressSpace::kPrivate);
+        GlobalVar(global, ty.Of<T>(), type::AddressSpace::kPrivate);
         auto local = Sym();
         Func(name, utils::Empty, ty.Of<T>(),
              utils::Vector{
@@ -43,7 +44,7 @@
     template <typename MAKE_TYPE_FUNC>
     void MakeSideEffectFunc(const char* name, MAKE_TYPE_FUNC make_type) {
         auto global = Sym();
-        GlobalVar(global, make_type(), ast::AddressSpace::kPrivate);
+        GlobalVar(global, make_type(), type::AddressSpace::kPrivate);
         auto local = Sym();
         Func(name, utils::Empty, make_type(),
              utils::Vector{
@@ -88,7 +89,7 @@
 }
 
 TEST_F(SideEffectsTest, Call_Builtin_NoSE) {
-    GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.f32(), type::AddressSpace::kPrivate);
     auto* expr = Call("dpdx", "a");
     Func("f", utils::Empty, ty.void_(), utils::Vector{Ignore(expr)},
          utils::Vector{create<ast::StageAttribute>(ast::PipelineStage::kFragment)});
@@ -114,7 +115,7 @@
 }
 
 TEST_F(SideEffectsTest, Call_Builtin_SE) {
-    GlobalVar("a", ty.atomic(ty.i32()), ast::AddressSpace::kWorkgroup);
+    GlobalVar("a", ty.atomic(ty.i32()), type::AddressSpace::kWorkgroup);
     auto* expr = Call("atomicAdd", AddressOf("a"), 1_i);
     WrapInFunction(expr);
 
@@ -163,34 +164,34 @@
     auto& c = GetParam();
 
     uint32_t next_binding = 0;
-    GlobalVar("f", ty.f32(), ast::AddressSpace::kPrivate);
-    GlobalVar("i", ty.i32(), ast::AddressSpace::kPrivate);
-    GlobalVar("u", ty.u32(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("vf", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("vf2", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("vi2", ty.vec2<i32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("vf4", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("vb", ty.vec3<bool>(), ast::AddressSpace::kPrivate);
-    GlobalVar("m", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("arr", ty.array<f32, 10>(), ast::AddressSpace::kPrivate);
-    GlobalVar("storage_arr", ty.array<f32>(), ast::AddressSpace::kStorage, Group(0_a),
+    GlobalVar("f", ty.f32(), type::AddressSpace::kPrivate);
+    GlobalVar("i", ty.i32(), type::AddressSpace::kPrivate);
+    GlobalVar("u", ty.u32(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("vf", ty.vec3<f32>(), type::AddressSpace::kPrivate);
+    GlobalVar("vf2", ty.vec2<f32>(), type::AddressSpace::kPrivate);
+    GlobalVar("vi2", ty.vec2<i32>(), type::AddressSpace::kPrivate);
+    GlobalVar("vf4", ty.vec4<f32>(), type::AddressSpace::kPrivate);
+    GlobalVar("vb", ty.vec3<bool>(), type::AddressSpace::kPrivate);
+    GlobalVar("m", ty.mat3x3<f32>(), type::AddressSpace::kPrivate);
+    GlobalVar("arr", ty.array<f32, 10>(), type::AddressSpace::kPrivate);
+    GlobalVar("storage_arr", ty.array<f32>(), type::AddressSpace::kStorage, Group(0_a),
               Binding(AInt(next_binding++)));
-    GlobalVar("workgroup_arr", ty.array<f32, 4>(), ast::AddressSpace::kWorkgroup);
-    GlobalVar("a", ty.atomic(ty.i32()), ast::AddressSpace::kStorage, ast::Access::kReadWrite,
+    GlobalVar("workgroup_arr", ty.array<f32, 4>(), type::AddressSpace::kWorkgroup);
+    GlobalVar("a", ty.atomic(ty.i32()), type::AddressSpace::kStorage, type::Access::kReadWrite,
               Group(0_a), Binding(AInt(next_binding++)));
     if (c.pipeline_stage != ast::PipelineStage::kCompute) {
-        GlobalVar("t2d", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), Group(0_a),
+        GlobalVar("t2d", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()), Group(0_a),
                   Binding(AInt(next_binding++)));
-        GlobalVar("tdepth2d", ty.depth_texture(ast::TextureDimension::k2d), Group(0_a),
+        GlobalVar("tdepth2d", ty.depth_texture(type::TextureDimension::k2d), Group(0_a),
                   Binding(AInt(next_binding++)));
-        GlobalVar("t2d_arr", ty.sampled_texture(ast::TextureDimension::k2dArray, ty.f32()),
+        GlobalVar("t2d_arr", ty.sampled_texture(type::TextureDimension::k2dArray, ty.f32()),
                   Group(0_a), Binding(AInt(next_binding++)));
-        GlobalVar("t2d_multi", ty.multisampled_texture(ast::TextureDimension::k2d, ty.f32()),
+        GlobalVar("t2d_multi", ty.multisampled_texture(type::TextureDimension::k2d, ty.f32()),
                   Group(0_a), Binding(AInt(next_binding++)));
         GlobalVar("tstorage2d",
-                  ty.storage_texture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Float,
-                                     ast::Access::kWrite),
+                  ty.storage_texture(type::TextureDimension::k2d, type::TexelFormat::kR32Float,
+                                     type::Access::kWrite),
                   Group(0_a), Binding(AInt(next_binding++)));
         GlobalVar("s2d", ty.sampler(ast::SamplerKind::kSampler), Group(0_a),
                   Binding(AInt(next_binding++)));
diff --git a/src/tint/resolver/static_assert_test.cc b/src/tint/resolver/static_assert_test.cc
index 6e8ecb7..3915dcd 100644
--- a/src/tint/resolver/static_assert_test.cc
+++ b/src/tint/resolver/static_assert_test.cc
@@ -84,7 +84,7 @@
 }
 
 TEST_F(ResolverStaticAssertTest, Local_NonConst) {
-    GlobalVar("V", ty.bool_(), Expr(true), ast::AddressSpace::kPrivate);
+    GlobalVar("V", ty.bool_(), Expr(true), type::AddressSpace::kPrivate);
     WrapInFunction(StaticAssert(Expr(Source{{12, 34}}, "V")));
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
diff --git a/src/tint/resolver/struct_address_space_use_test.cc b/src/tint/resolver/struct_address_space_use_test.cc
index ff85ce4..a0ff744 100644
--- a/src/tint/resolver/struct_address_space_use_test.cc
+++ b/src/tint/resolver/struct_address_space_use_test.cc
@@ -46,7 +46,7 @@
 
     auto* sem = TypeOf(s)->As<sem::Struct>();
     ASSERT_NE(sem, nullptr);
-    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(ast::AddressSpace::kNone));
+    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(type::AddressSpace::kNone));
 }
 
 TEST_F(ResolverAddressSpaceUseTest, StructReachableFromReturnType) {
@@ -58,55 +58,55 @@
 
     auto* sem = TypeOf(s)->As<sem::Struct>();
     ASSERT_NE(sem, nullptr);
-    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(ast::AddressSpace::kNone));
+    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(type::AddressSpace::kNone));
 }
 
 TEST_F(ResolverAddressSpaceUseTest, StructReachableFromGlobal) {
     auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
 
-    GlobalVar("g", ty.Of(s), ast::AddressSpace::kPrivate);
+    GlobalVar("g", ty.Of(s), type::AddressSpace::kPrivate);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 
     auto* sem = TypeOf(s)->As<sem::Struct>();
     ASSERT_NE(sem, nullptr);
-    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(ast::AddressSpace::kPrivate));
+    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(type::AddressSpace::kPrivate));
 }
 
 TEST_F(ResolverAddressSpaceUseTest, StructReachableViaGlobalAlias) {
     auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
     auto* a = Alias("A", ty.Of(s));
-    GlobalVar("g", ty.Of(a), ast::AddressSpace::kPrivate);
+    GlobalVar("g", ty.Of(a), type::AddressSpace::kPrivate);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 
     auto* sem = TypeOf(s)->As<sem::Struct>();
     ASSERT_NE(sem, nullptr);
-    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(ast::AddressSpace::kPrivate));
+    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(type::AddressSpace::kPrivate));
 }
 
 TEST_F(ResolverAddressSpaceUseTest, StructReachableViaGlobalStruct) {
     auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
     auto* o = Structure("O", utils::Vector{Member("a", ty.Of(s))});
-    GlobalVar("g", ty.Of(o), ast::AddressSpace::kPrivate);
+    GlobalVar("g", ty.Of(o), type::AddressSpace::kPrivate);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 
     auto* sem = TypeOf(s)->As<sem::Struct>();
     ASSERT_NE(sem, nullptr);
-    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(ast::AddressSpace::kPrivate));
+    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(type::AddressSpace::kPrivate));
 }
 
 TEST_F(ResolverAddressSpaceUseTest, StructReachableViaGlobalArray) {
     auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
     auto* a = ty.array(ty.Of(s), 3_u);
-    GlobalVar("g", a, ast::AddressSpace::kPrivate);
+    GlobalVar("g", a, type::AddressSpace::kPrivate);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 
     auto* sem = TypeOf(s)->As<sem::Struct>();
     ASSERT_NE(sem, nullptr);
-    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(ast::AddressSpace::kPrivate));
+    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(type::AddressSpace::kPrivate));
 }
 
 TEST_F(ResolverAddressSpaceUseTest, StructReachableFromLocal) {
@@ -118,7 +118,7 @@
 
     auto* sem = TypeOf(s)->As<sem::Struct>();
     ASSERT_NE(sem, nullptr);
-    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(ast::AddressSpace::kFunction));
+    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(type::AddressSpace::kFunction));
 }
 
 TEST_F(ResolverAddressSpaceUseTest, StructReachableViaLocalAlias) {
@@ -130,7 +130,7 @@
 
     auto* sem = TypeOf(s)->As<sem::Struct>();
     ASSERT_NE(sem, nullptr);
-    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(ast::AddressSpace::kFunction));
+    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(type::AddressSpace::kFunction));
 }
 
 TEST_F(ResolverAddressSpaceUseTest, StructReachableViaLocalStruct) {
@@ -142,7 +142,7 @@
 
     auto* sem = TypeOf(s)->As<sem::Struct>();
     ASSERT_NE(sem, nullptr);
-    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(ast::AddressSpace::kFunction));
+    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(type::AddressSpace::kFunction));
 }
 
 TEST_F(ResolverAddressSpaceUseTest, StructReachableViaLocalArray) {
@@ -154,13 +154,13 @@
 
     auto* sem = TypeOf(s)->As<sem::Struct>();
     ASSERT_NE(sem, nullptr);
-    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(ast::AddressSpace::kFunction));
+    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(type::AddressSpace::kFunction));
 }
 
 TEST_F(ResolverAddressSpaceUseTest, StructMultipleAddressSpaceUses) {
     auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
-    GlobalVar("x", ty.Of(s), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a));
-    GlobalVar("y", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("x", ty.Of(s), type::AddressSpace::kUniform, Binding(0_a), Group(0_a));
+    GlobalVar("y", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(1_a),
               Group(0_a));
     WrapInFunction(Var("g", ty.Of(s)));
 
@@ -169,8 +169,8 @@
     auto* sem = TypeOf(s)->As<sem::Struct>();
     ASSERT_NE(sem, nullptr);
     EXPECT_THAT(sem->AddressSpaceUsage(),
-                UnorderedElementsAre(ast::AddressSpace::kUniform, ast::AddressSpace::kStorage,
-                                     ast::AddressSpace::kFunction));
+                UnorderedElementsAre(type::AddressSpace::kUniform, type::AddressSpace::kStorage,
+                                     type::AddressSpace::kFunction));
 }
 
 }  // namespace
diff --git a/src/tint/resolver/type_initializer_validation_test.cc b/src/tint/resolver/type_initializer_validation_test.cc
index 6f7d78b..27b6dc1 100644
--- a/src/tint/resolver/type_initializer_validation_test.cc
+++ b/src/tint/resolver/type_initializer_validation_test.cc
@@ -69,10 +69,12 @@
     ASSERT_TRUE(r()->Resolve()) << r()->error();
     ASSERT_TRUE(TypeOf(a_ident)->Is<type::Reference>());
     EXPECT_TRUE(TypeOf(a_ident)->As<type::Reference>()->StoreType()->Is<type::I32>());
-    EXPECT_EQ(TypeOf(a_ident)->As<type::Reference>()->AddressSpace(), ast::AddressSpace::kFunction);
+    EXPECT_EQ(TypeOf(a_ident)->As<type::Reference>()->AddressSpace(),
+              type::AddressSpace::kFunction);
     ASSERT_TRUE(TypeOf(b_ident)->Is<type::Reference>());
     EXPECT_TRUE(TypeOf(b_ident)->As<type::Reference>()->StoreType()->Is<type::I32>());
-    EXPECT_EQ(TypeOf(b_ident)->As<type::Reference>()->AddressSpace(), ast::AddressSpace::kFunction);
+    EXPECT_EQ(TypeOf(b_ident)->As<type::Reference>()->AddressSpace(),
+              type::AddressSpace::kFunction);
 }
 
 using InferTypeTest_FromInitializerExpression = ResolverTestWithParam<Params>;
@@ -95,8 +97,8 @@
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
     auto* got = TypeOf(a_ident);
-    auto* expected = create<type::Reference>(params.create_rhs_sem_type(*this),
-                                             ast::AddressSpace::kFunction, ast::Access::kReadWrite);
+    auto* expected = create<type::Reference>(
+        params.create_rhs_sem_type(*this), type::AddressSpace::kFunction, type::Access::kReadWrite);
     ASSERT_EQ(got, expected) << "got:      " << FriendlyName(got) << "\n"
                              << "expected: " << FriendlyName(expected) << "\n";
 }
@@ -149,8 +151,8 @@
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
     auto* got = TypeOf(a_ident);
-    auto* expected = create<type::Reference>(params.create_rhs_sem_type(*this),
-                                             ast::AddressSpace::kFunction, ast::Access::kReadWrite);
+    auto* expected = create<type::Reference>(
+        params.create_rhs_sem_type(*this), type::AddressSpace::kFunction, type::Access::kReadWrite);
     ASSERT_EQ(got, expected) << "got:      " << FriendlyName(got) << "\n"
                              << "expected: " << FriendlyName(expected) << "\n";
 }
@@ -197,8 +199,8 @@
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
     auto* got = TypeOf(a_ident);
-    auto* expected = create<type::Reference>(params.create_rhs_sem_type(*this),
-                                             ast::AddressSpace::kFunction, ast::Access::kReadWrite);
+    auto* expected = create<type::Reference>(
+        params.create_rhs_sem_type(*this), type::AddressSpace::kFunction, type::Access::kReadWrite);
     ASSERT_EQ(got, expected) << "got:      " << FriendlyName(got) << "\n"
                              << "expected: " << FriendlyName(expected) << "\n";
 }
@@ -1968,7 +1970,7 @@
 
 TEST_F(ResolverTypeInitializerValidationTest, Vector_Alias_Argument_Error) {
     auto* alias = Alias("UnsignedInt", ty.u32());
-    GlobalVar("uint_var", ty.Of(alias), ast::AddressSpace::kPrivate);
+    GlobalVar("uint_var", ty.Of(alias), type::AddressSpace::kPrivate);
 
     auto* tc = vec2<f32>(Source{{12, 34}}, "uint_var");
     WrapInFunction(tc);
@@ -1980,8 +1982,8 @@
 TEST_F(ResolverTypeInitializerValidationTest, Vector_Alias_Argument_Success) {
     auto* f32_alias = Alias("Float32", ty.f32());
     auto* vec2_alias = Alias("VectorFloat2", ty.vec2<f32>());
-    GlobalVar("my_f32", ty.Of(f32_alias), ast::AddressSpace::kPrivate);
-    GlobalVar("my_vec2", ty.Of(vec2_alias), ast::AddressSpace::kPrivate);
+    GlobalVar("my_f32", ty.Of(f32_alias), type::AddressSpace::kPrivate);
+    GlobalVar("my_vec2", ty.Of(vec2_alias), type::AddressSpace::kPrivate);
 
     auto* tc = vec3<f32>("my_vec2", "my_f32");
     WrapInFunction(tc);
diff --git a/src/tint/resolver/type_validation_test.cc b/src/tint/resolver/type_validation_test.cc
index ebd40b0..c75db20 100644
--- a/src/tint/resolver/type_validation_test.cc
+++ b/src/tint/resolver/type_validation_test.cc
@@ -19,6 +19,7 @@
 #include "src/tint/resolver/resolver_test_helper.h"
 #include "src/tint/type/multisampled_texture.h"
 #include "src/tint/type/storage_texture.h"
+#include "src/tint/type/texture_dimension.h"
 
 #include "gmock/gmock.h"
 
@@ -94,7 +95,7 @@
 
 TEST_F(ResolverTypeValidationTest, GlobalVariableWithAddressSpace_Pass) {
     // var<private> global_var: f32;
-    GlobalVar(Source{{12, 34}}, "global_var", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar(Source{{12, 34}}, "global_var", ty.f32(), type::AddressSpace::kPrivate);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -110,9 +111,9 @@
     // var global_var0 : f32 = 0.1;
     // var global_var1 : i32 = 0;
 
-    GlobalVar("global_var0", ty.f32(), ast::AddressSpace::kPrivate, Expr(0.1_f));
+    GlobalVar("global_var0", ty.f32(), type::AddressSpace::kPrivate, Expr(0.1_f));
 
-    GlobalVar(Source{{12, 34}}, "global_var1", ty.f32(), ast::AddressSpace::kPrivate, Expr(1_f));
+    GlobalVar(Source{{12, 34}}, "global_var1", ty.f32(), type::AddressSpace::kPrivate, Expr(1_f));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -128,7 +129,7 @@
              Decl(Var("a", ty.f32(), Expr(2_f))),
          });
 
-    GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate, Expr(2.1_f));
+    GlobalVar("a", ty.f32(), type::AddressSpace::kPrivate, Expr(2.1_f));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -192,19 +193,19 @@
 
 TEST_F(ResolverTypeValidationTest, ArraySize_AIntLiteral_Pass) {
     // var<private> a : array<f32, 4>;
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 4_a)), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 4_a)), type::AddressSpace::kPrivate);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedLiteral_Pass) {
     // var<private> a : array<f32, 4u>;
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 4_u)), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 4_u)), type::AddressSpace::kPrivate);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_SignedLiteral_Pass) {
     // var<private> a : array<f32, 4i>;
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 4_i)), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 4_i)), type::AddressSpace::kPrivate);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
@@ -212,7 +213,8 @@
     // const size = 4u;
     // var<private> a : array<f32, size>;
     GlobalConst("size", Expr(4_u));
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")),
+              type::AddressSpace::kPrivate);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
@@ -220,34 +222,35 @@
     // const size = 4i;
     // var<private> a : array<f32, size>;
     GlobalConst("size", Expr(4_i));
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")),
+              type::AddressSpace::kPrivate);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_AIntLiteral_Zero) {
     // var<private> a : array<f32, 0>;
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_a)), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_a)), type::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array count (0) must be greater than 0");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedLiteral_Zero) {
     // var<private> a : array<f32, 0u>;
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_u)), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_u)), type::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array count (0) must be greater than 0");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_SignedLiteral_Zero) {
     // var<private> a : array<f32, 0i>;
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_i)), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_i)), type::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array count (0) must be greater than 0");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_SignedLiteral_Negative) {
     // var<private> a : array<f32, -10i>;
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, -10_i)), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, -10_i)), type::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array count (-10) must be greater than 0");
 }
@@ -256,7 +259,8 @@
     // const size = 0u;
     // var<private> a : array<f32, size>;
     GlobalConst("size", Expr(0_u));
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")),
+              type::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array count (0) must be greater than 0");
 }
@@ -265,7 +269,8 @@
     // const size = 0i;
     // var<private> a : array<f32, size>;
     GlobalConst("size", Expr(0_i));
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")),
+              type::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array count (0) must be greater than 0");
 }
@@ -274,14 +279,15 @@
     // const size = -10i;
     // var<private> a : array<f32, size>;
     GlobalConst("size", Expr(-10_i));
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")),
+              type::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array count (-10) must be greater than 0");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_FloatLiteral) {
     // var<private> a : array<f32, 10.0>;
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 10_f)), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 10_f)), type::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(
         r()->error(),
@@ -292,7 +298,7 @@
 TEST_F(ResolverTypeValidationTest, ArraySize_IVecLiteral) {
     // var<private> a : array<f32, vec2<i32>(10, 10)>;
     GlobalVar("a", ty.array(ty.f32(), Construct(Source{{12, 34}}, ty.vec2<i32>(), 10_i, 10_i)),
-              ast::AddressSpace::kPrivate);
+              type::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(
         r()->error(),
@@ -304,7 +310,8 @@
     // const size = 10.0;
     // var<private> a : array<f32, size>;
     GlobalConst("size", Expr(10_f));
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")),
+              type::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(
         r()->error(),
@@ -316,7 +323,8 @@
     // const size = vec2<i32>(100, 100);
     // var<private> a : array<f32, size>;
     GlobalConst("size", Construct(ty.vec2<i32>(), 100_i, 100_i));
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")),
+              type::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(
         r()->error(),
@@ -327,14 +335,14 @@
 TEST_F(ResolverTypeValidationTest, ArraySize_UnderElementCountLimit) {
     // var<private> a : array<f32, 65535>;
     GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 65535_a)),
-              ast::AddressSpace::kPrivate);
+              type::AddressSpace::kPrivate);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_OverElementCountLimit) {
     // var<private> a : array<f32, 65536>;
     GlobalVar(Source{{56, 78}}, "a", ty.array(Source{{12, 34}}, ty.f32(), Expr(65536_a)),
-              ast::AddressSpace::kPrivate);
+              type::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), R"(12:34 error: array count (65536) must be less than 65536
 56:78 note: while instantiating 'var' a)");
@@ -342,8 +350,8 @@
 
 TEST_F(ResolverTypeValidationTest, ArraySize_StorageBufferLargeArray) {
     // var<storage> a : array<f32, 65536>;
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 65536_a)), ast::AddressSpace::kStorage,
-              utils::Vector{Binding(0_u), Group(0_u)});
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 65536_a)),
+              type::AddressSpace::kStorage, utils::Vector{Binding(0_u), Group(0_u)});
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
@@ -354,7 +362,7 @@
     // var<storage> a : S;
     Structure("S", utils::Vector{Member(Source{{12, 34}}, "a",
                                         ty.array(Source{{12, 20}}, ty.f32(), 65536_a))});
-    GlobalVar("a", ty.type_name(Source{{12, 30}}, "S"), ast::AddressSpace::kStorage,
+    GlobalVar("a", ty.type_name(Source{{12, 30}}, "S"), type::AddressSpace::kStorage,
               utils::Vector{Binding(0_u), Group(0_u)});
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -367,7 +375,7 @@
     Structure("S", utils::Vector{Member(Source{{12, 34}}, "a", ty.f32(),
                                         utils::Vector{MemberOffset(800000_a)})});
     GlobalVar("a", ty.array(ty.type_name(Source{{12, 30}}, "S"), Expr(Source{{12, 34}}, 65535_a)),
-              ast::AddressSpace::kPrivate);
+              type::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "12:34 error: array byte size (0xc34f7cafc) must not exceed 0xffffffff bytes");
@@ -376,7 +384,7 @@
 TEST_F(ResolverTypeValidationTest, ArraySize_TooBig_ExplicitStride) {
     // var<private> a : @stride(8000000) array<f32, 65535>;
     GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 65535_a), 8000000),
-              ast::AddressSpace::kPrivate);
+              type::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "12:34 error: array byte size (0x7a1185ee00) must not exceed 0xffffffff bytes");
@@ -386,7 +394,7 @@
     // override size = 10i;
     // var<private> a : array<f32, size>;
     Override("size", Expr(10_i));
-    GlobalVar("a", ty.array(Source{{12, 34}}, ty.f32(), "size"), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.array(Source{{12, 34}}, ty.f32(), "size"), type::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "12:34 error: array with an 'override' element count can only be used as the store "
@@ -398,7 +406,7 @@
     // var<workgroup> a : array<array<f32, size>, 4>;
     Override("size", Expr(10_i));
     GlobalVar("a", ty.array(ty.array(Source{{12, 34}}, ty.f32(), "size"), 4_a),
-              ast::AddressSpace::kWorkgroup);
+              type::AddressSpace::kWorkgroup);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "12:34 error: array with an 'override' element count can only be used as the store "
@@ -457,7 +465,7 @@
     //   var a = w;
     // }
     Override("size", Expr(10_i));
-    GlobalVar("w", ty.array(ty.f32(), "size"), ast::AddressSpace::kWorkgroup);
+    GlobalVar("w", ty.array(ty.f32(), "size"), type::AddressSpace::kWorkgroup);
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(Var("a", Expr(Source{{12, 34}}, "w"))),
@@ -475,7 +483,7 @@
     //   let a = w;
     // }
     Override("size", Expr(10_i));
-    GlobalVar("w", ty.array(ty.f32(), "size"), ast::AddressSpace::kWorkgroup);
+    GlobalVar("w", ty.array(ty.f32(), "size"), type::AddressSpace::kWorkgroup);
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(Let("a", Expr(Source{{12, 34}}, "w"))),
@@ -494,8 +502,8 @@
     //   a = b;
     // }
     Override("size", Expr(10_i));
-    GlobalVar("a", ty.array(ty.f32(), Add("size", 1_i)), ast::AddressSpace::kWorkgroup);
-    GlobalVar("b", ty.array(ty.f32(), Add("size", 1_i)), ast::AddressSpace::kWorkgroup);
+    GlobalVar("a", ty.array(ty.f32(), Add("size", 1_i)), type::AddressSpace::kWorkgroup);
+    GlobalVar("b", ty.array(ty.f32(), Add("size", 1_i)), type::AddressSpace::kWorkgroup);
     WrapInFunction(Assign(Source{{12, 34}}, "a", "b"));
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -529,15 +537,16 @@
     // var<workgroup> a : array<f32, size>;
     Override("size", Expr(10_i));
     GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")),
-              ast::AddressSpace::kWorkgroup);
+              type::AddressSpace::kWorkgroup);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_ModuleVar) {
     // var<private> size : i32 = 10i;
     // var<private> a : array<f32, size>;
-    GlobalVar("size", ty.i32(), Expr(10_i), ast::AddressSpace::kPrivate);
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::AddressSpace::kPrivate);
+    GlobalVar("size", ty.i32(), Expr(10_i), type::AddressSpace::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")),
+              type::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               R"(12:34 error: var 'size' cannot be referenced at module-scope
@@ -697,7 +706,7 @@
 
     Structure("Foo", utils::Vector{Member("rt", ty.array<f32>())});
     GlobalVar("v", ty.array(ty.type_name(Source{{12, 34}}, "Foo"), 4_u),
-              ast::AddressSpace::kPrivate);
+              type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve()) << r()->error();
     EXPECT_EQ(r()->error(),
@@ -743,7 +752,7 @@
 
 TEST_F(ResolverTypeValidationTest, RuntimeArrayAsGlobalVariable) {
     GlobalVar(Source{{56, 78}}, "g", ty.array(Source{{12, 34}}, ty.i32()),
-              ast::AddressSpace::kPrivate);
+              type::AddressSpace::kPrivate);
 
     ASSERT_FALSE(r()->Resolve());
 
@@ -792,7 +801,7 @@
     // fn func(a : ptr<workgroup, array<u32>>) {}
 
     auto* param = Param("a", ty.pointer(Source{{56, 78}}, ty.array(Source{{12, 34}}, ty.i32()),
-                                        ast::AddressSpace::kWorkgroup));
+                                        type::AddressSpace::kWorkgroup));
 
     Func("func", utils::Vector{param}, ty.void_(),
          utils::Vector{
@@ -856,8 +865,8 @@
 }
 
 TEST_F(ResolverTypeValidationTest, ArrayOfNonStorableType) {
-    auto* tex_ty = ty.sampled_texture(Source{{12, 34}}, ast::TextureDimension::k2d, ty.f32());
-    GlobalVar("arr", ty.array(tex_ty, 4_i), ast::AddressSpace::kPrivate);
+    auto* tex_ty = ty.sampled_texture(Source{{12, 34}}, type::TextureDimension::k2d, ty.f32());
+    GlobalVar("arr", ty.array(tex_ty, 4_i), type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -865,8 +874,8 @@
 }
 
 TEST_F(ResolverTypeValidationTest, ArrayOfNonStorableTypeWithStride) {
-    auto* ptr_ty = ty.pointer<u32>(Source{{12, 34}}, ast::AddressSpace::kUniform);
-    GlobalVar("arr", ty.array(ptr_ty, 4_i, 16), ast::AddressSpace::kPrivate);
+    auto* ptr_ty = ty.pointer<u32>(Source{{12, 34}}, type::AddressSpace::kUniform);
+    GlobalVar("arr", ty.array(ptr_ty, 4_i, 16), type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -876,8 +885,8 @@
 TEST_F(ResolverTypeValidationTest, VariableAsType) {
     // var<private> a : i32;
     // var<private> b : a;
-    GlobalVar("a", ty.i32(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.type_name("a"), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.i32(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.type_name("a"), type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -889,7 +898,7 @@
     // fn f() {}
     // var<private> v : f;
     Func("f", utils::Empty, ty.void_(), {});
-    GlobalVar("v", ty.type_name("f"), ast::AddressSpace::kPrivate);
+    GlobalVar("v", ty.type_name("f"), type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -899,7 +908,7 @@
 
 TEST_F(ResolverTypeValidationTest, BuiltinAsType) {
     // var<private> v : max;
-    GlobalVar("v", ty.type_name("max"), ast::AddressSpace::kPrivate);
+    GlobalVar("v", ty.type_name("max"), type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "error: cannot use builtin 'max' as type");
@@ -964,7 +973,7 @@
 
 namespace SampledTextureTests {
 struct DimensionParams {
-    ast::TextureDimension dim;
+    type::TextureDimension dim;
     bool is_valid;
 };
 
@@ -979,12 +988,12 @@
 INSTANTIATE_TEST_SUITE_P(ResolverTypeValidationTest,
                          SampledTextureDimensionTest,
                          testing::Values(  //
-                             DimensionParams{ast::TextureDimension::k1d, true},
-                             DimensionParams{ast::TextureDimension::k2d, true},
-                             DimensionParams{ast::TextureDimension::k2dArray, true},
-                             DimensionParams{ast::TextureDimension::k3d, true},
-                             DimensionParams{ast::TextureDimension::kCube, true},
-                             DimensionParams{ast::TextureDimension::kCubeArray, true}));
+                             DimensionParams{type::TextureDimension::k1d, true},
+                             DimensionParams{type::TextureDimension::k2d, true},
+                             DimensionParams{type::TextureDimension::k2dArray, true},
+                             DimensionParams{type::TextureDimension::k3d, true},
+                             DimensionParams{type::TextureDimension::kCube, true},
+                             DimensionParams{type::TextureDimension::kCubeArray, true}));
 
 using MultisampledTextureDimensionTest = ResolverTestWithParam<DimensionParams>;
 TEST_P(MultisampledTextureDimensionTest, All) {
@@ -1002,12 +1011,12 @@
 INSTANTIATE_TEST_SUITE_P(ResolverTypeValidationTest,
                          MultisampledTextureDimensionTest,
                          testing::Values(  //
-                             DimensionParams{ast::TextureDimension::k1d, false},
-                             DimensionParams{ast::TextureDimension::k2d, true},
-                             DimensionParams{ast::TextureDimension::k2dArray, false},
-                             DimensionParams{ast::TextureDimension::k3d, false},
-                             DimensionParams{ast::TextureDimension::kCube, false},
-                             DimensionParams{ast::TextureDimension::kCubeArray, false}));
+                             DimensionParams{type::TextureDimension::k1d, false},
+                             DimensionParams{type::TextureDimension::k2d, true},
+                             DimensionParams{type::TextureDimension::k2dArray, false},
+                             DimensionParams{type::TextureDimension::k3d, false},
+                             DimensionParams{type::TextureDimension::kCube, false},
+                             DimensionParams{type::TextureDimension::kCubeArray, false}));
 
 struct TypeParams {
     builder::ast_type_func_ptr type_func;
@@ -1047,7 +1056,7 @@
     Enable(ast::Extension::kF16);
     GlobalVar(
         "a",
-        ty.sampled_texture(Source{{12, 34}}, ast::TextureDimension::k2d, params.type_func(*this)),
+        ty.sampled_texture(Source{{12, 34}}, type::TextureDimension::k2d, params.type_func(*this)),
         Group(0_a), Binding(0_a));
 
     if (params.is_valid) {
@@ -1066,7 +1075,7 @@
     auto& params = GetParam();
     Enable(ast::Extension::kF16);
     GlobalVar("a",
-              ty.multisampled_texture(Source{{12, 34}}, ast::TextureDimension::k2d,
+              ty.multisampled_texture(Source{{12, 34}}, type::TextureDimension::k2d,
                                       params.type_func(*this)),
               Group(0_a), Binding(0_a));
 
@@ -1086,17 +1095,17 @@
 
 namespace StorageTextureTests {
 struct DimensionParams {
-    ast::TextureDimension dim;
+    type::TextureDimension dim;
     bool is_valid;
 };
 
 static constexpr DimensionParams Dimension_cases[] = {
-    DimensionParams{ast::TextureDimension::k1d, true},
-    DimensionParams{ast::TextureDimension::k2d, true},
-    DimensionParams{ast::TextureDimension::k2dArray, true},
-    DimensionParams{ast::TextureDimension::k3d, true},
-    DimensionParams{ast::TextureDimension::kCube, false},
-    DimensionParams{ast::TextureDimension::kCubeArray, false}};
+    DimensionParams{type::TextureDimension::k1d, true},
+    DimensionParams{type::TextureDimension::k2d, true},
+    DimensionParams{type::TextureDimension::k2dArray, true},
+    DimensionParams{type::TextureDimension::k3d, true},
+    DimensionParams{type::TextureDimension::kCube, false},
+    DimensionParams{type::TextureDimension::kCubeArray, false}};
 
 using StorageTextureDimensionTest = ResolverTestWithParam<DimensionParams>;
 TEST_P(StorageTextureDimensionTest, All) {
@@ -1104,8 +1113,8 @@
     // var a : texture_storage_*<ru32int, write>;
     auto& params = GetParam();
 
-    auto* st = ty.storage_texture(Source{{12, 34}}, params.dim, ast::TexelFormat::kR32Uint,
-                                  ast::Access::kWrite);
+    auto* st = ty.storage_texture(Source{{12, 34}}, params.dim, type::TexelFormat::kR32Uint,
+                                  type::Access::kWrite);
 
     GlobalVar("a", st, Group(0_a), Binding(0_a));
 
@@ -1122,27 +1131,27 @@
                          testing::ValuesIn(Dimension_cases));
 
 struct FormatParams {
-    ast::TexelFormat format;
+    type::TexelFormat format;
     bool is_valid;
 };
 
-static constexpr FormatParams format_cases[] = {FormatParams{ast::TexelFormat::kBgra8Unorm, true},
-                                                FormatParams{ast::TexelFormat::kR32Float, true},
-                                                FormatParams{ast::TexelFormat::kR32Sint, true},
-                                                FormatParams{ast::TexelFormat::kR32Uint, true},
-                                                FormatParams{ast::TexelFormat::kRg32Float, true},
-                                                FormatParams{ast::TexelFormat::kRg32Sint, true},
-                                                FormatParams{ast::TexelFormat::kRg32Uint, true},
-                                                FormatParams{ast::TexelFormat::kRgba16Float, true},
-                                                FormatParams{ast::TexelFormat::kRgba16Sint, true},
-                                                FormatParams{ast::TexelFormat::kRgba16Uint, true},
-                                                FormatParams{ast::TexelFormat::kRgba32Float, true},
-                                                FormatParams{ast::TexelFormat::kRgba32Sint, true},
-                                                FormatParams{ast::TexelFormat::kRgba32Uint, true},
-                                                FormatParams{ast::TexelFormat::kRgba8Sint, true},
-                                                FormatParams{ast::TexelFormat::kRgba8Snorm, true},
-                                                FormatParams{ast::TexelFormat::kRgba8Uint, true},
-                                                FormatParams{ast::TexelFormat::kRgba8Unorm, true}};
+static constexpr FormatParams format_cases[] = {FormatParams{type::TexelFormat::kBgra8Unorm, true},
+                                                FormatParams{type::TexelFormat::kR32Float, true},
+                                                FormatParams{type::TexelFormat::kR32Sint, true},
+                                                FormatParams{type::TexelFormat::kR32Uint, true},
+                                                FormatParams{type::TexelFormat::kRg32Float, true},
+                                                FormatParams{type::TexelFormat::kRg32Sint, true},
+                                                FormatParams{type::TexelFormat::kRg32Uint, true},
+                                                FormatParams{type::TexelFormat::kRgba16Float, true},
+                                                FormatParams{type::TexelFormat::kRgba16Sint, true},
+                                                FormatParams{type::TexelFormat::kRgba16Uint, true},
+                                                FormatParams{type::TexelFormat::kRgba32Float, true},
+                                                FormatParams{type::TexelFormat::kRgba32Sint, true},
+                                                FormatParams{type::TexelFormat::kRgba32Uint, true},
+                                                FormatParams{type::TexelFormat::kRgba8Sint, true},
+                                                FormatParams{type::TexelFormat::kRgba8Snorm, true},
+                                                FormatParams{type::TexelFormat::kRgba8Uint, true},
+                                                FormatParams{type::TexelFormat::kRgba8Unorm, true}};
 
 using StorageTextureFormatTest = ResolverTestWithParam<FormatParams>;
 TEST_P(StorageTextureFormatTest, All) {
@@ -1156,18 +1165,20 @@
     // @group(0) @binding(3)
     // var d : texture_storage_3d<*, write>;
 
-    auto* st_a = ty.storage_texture(Source{{12, 34}}, ast::TextureDimension::k1d, params.format,
-                                    ast::Access::kWrite);
+    auto* st_a = ty.storage_texture(Source{{12, 34}}, type::TextureDimension::k1d, params.format,
+                                    type::Access::kWrite);
     GlobalVar("a", st_a, Group(0_a), Binding(0_a));
 
-    auto* st_b = ty.storage_texture(ast::TextureDimension::k2d, params.format, ast::Access::kWrite);
+    auto* st_b =
+        ty.storage_texture(type::TextureDimension::k2d, params.format, type::Access::kWrite);
     GlobalVar("b", st_b, Group(0_a), Binding(1_a));
 
     auto* st_c =
-        ty.storage_texture(ast::TextureDimension::k2dArray, params.format, ast::Access::kWrite);
+        ty.storage_texture(type::TextureDimension::k2dArray, params.format, type::Access::kWrite);
     GlobalVar("c", st_c, Group(0_a), Binding(2_a));
 
-    auto* st_d = ty.storage_texture(ast::TextureDimension::k3d, params.format, ast::Access::kWrite);
+    auto* st_d =
+        ty.storage_texture(type::TextureDimension::k3d, params.format, type::Access::kWrite);
     GlobalVar("d", st_d, Group(0_a), Binding(3_a));
 
     if (params.is_valid) {
@@ -1189,8 +1200,8 @@
     // @group(0) @binding(0)
     // var a : texture_storage_1d<ru32int>;
 
-    auto* st = ty.storage_texture(Source{{12, 34}}, ast::TextureDimension::k1d,
-                                  ast::TexelFormat::kR32Uint, ast::Access::kUndefined);
+    auto* st = ty.storage_texture(Source{{12, 34}}, type::TextureDimension::k1d,
+                                  type::TexelFormat::kR32Uint, type::Access::kUndefined);
 
     GlobalVar("a", st, Group(0_a), Binding(0_a));
 
@@ -1202,8 +1213,8 @@
     // @group(0) @binding(0)
     // var a : texture_storage_1d<ru32int, read_write>;
 
-    auto* st = ty.storage_texture(Source{{12, 34}}, ast::TextureDimension::k1d,
-                                  ast::TexelFormat::kR32Uint, ast::Access::kReadWrite);
+    auto* st = ty.storage_texture(Source{{12, 34}}, type::TextureDimension::k1d,
+                                  type::TexelFormat::kR32Uint, type::Access::kReadWrite);
 
     GlobalVar("a", st, Group(0_a), Binding(0_a));
 
@@ -1216,8 +1227,8 @@
     // @group(0) @binding(0)
     // var a : texture_storage_1d<ru32int, read>;
 
-    auto* st = ty.storage_texture(Source{{12, 34}}, ast::TextureDimension::k1d,
-                                  ast::TexelFormat::kR32Uint, ast::Access::kRead);
+    auto* st = ty.storage_texture(Source{{12, 34}}, type::TextureDimension::k1d,
+                                  type::TexelFormat::kR32Uint, type::Access::kRead);
 
     GlobalVar("a", st, Group(0_a), Binding(0_a));
 
@@ -1230,8 +1241,8 @@
     // @group(0) @binding(0)
     // var a : texture_storage_1d<ru32int, write>;
 
-    auto* st = ty.storage_texture(ast::TextureDimension::k1d, ast::TexelFormat::kR32Uint,
-                                  ast::Access::kWrite);
+    auto* st = ty.storage_texture(type::TextureDimension::k1d, type::TexelFormat::kR32Uint,
+                                  type::Access::kWrite);
 
     GlobalVar("a", st, Group(0_a), Binding(0_a));
 
@@ -1261,7 +1272,7 @@
     Enable(ast::Extension::kF16);
 
     GlobalVar("a", ty.mat(params.elem_ty(*this), params.columns, params.rows),
-              ast::AddressSpace::kPrivate);
+              type::AddressSpace::kPrivate);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 INSTANTIATE_TEST_SUITE_P(ResolverTypeValidationTest,
@@ -1300,7 +1311,7 @@
     Enable(ast::Extension::kF16);
 
     GlobalVar("a", ty.mat(Source{{12, 34}}, params.elem_ty(*this), params.columns, params.rows),
-              ast::AddressSpace::kPrivate);
+              type::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: matrix element type must be 'f32' or 'f16'");
 }
@@ -1342,7 +1353,7 @@
 
     Enable(ast::Extension::kF16);
 
-    GlobalVar("a", ty.vec(params.elem_ty(*this), params.width), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.vec(params.elem_ty(*this), params.width), type::AddressSpace::kPrivate);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 INSTANTIATE_TEST_SUITE_P(ResolverTypeValidationTest,
@@ -1377,7 +1388,7 @@
     Enable(ast::Extension::kF16);
 
     GlobalVar("a", ty.vec(Source{{12, 34}}, params.elem_ty(*this), params.width),
-              ast::AddressSpace::kPrivate);
+              type::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "12:34 error: vector element type must be 'bool', 'f32', 'f16', 'i32' "
diff --git a/src/tint/resolver/uniformity.cc b/src/tint/resolver/uniformity.cc
index 5fed471..7b297e1 100644
--- a/src/tint/resolver/uniformity.cc
+++ b/src/tint/resolver/uniformity.cc
@@ -1151,7 +1151,7 @@
             [&](const sem::GlobalVariable* global) {
                 // Loads from global read-write variables may be non-uniform.
                 if (global->Declaration()->Is<ast::Var>() &&
-                    global->Access() != ast::Access::kRead && load_rule) {
+                    global->Access() != type::Access::kRead && load_rule) {
                     node->AddEdge(current_function_->may_be_non_uniform);
                 } else {
                     node->AddEdge(cf);
@@ -1168,7 +1168,7 @@
                         // We are loading from the pointer, so add an edge to its contents.
                         auto* root = var_user->RootIdentifier();
                         if (root->Is<sem::GlobalVariable>()) {
-                            if (root->Access() != ast::Access::kRead) {
+                            if (root->Access() != type::Access::kRead) {
                                 // The contents of a mutable global variable is always non-uniform.
                                 node->AddEdge(current_function_->may_be_non_uniform);
                             }
@@ -1420,7 +1420,7 @@
 
                 auto* root = sem_arg->RootIdentifier();
                 if (root->Is<sem::GlobalVariable>()) {
-                    if (root->Access() != ast::Access::kRead) {
+                    if (root->Access() != type::Access::kRead) {
                         // The contents of a mutable global variable is always non-uniform.
                         arg_contents->AddEdge(current_function_->may_be_non_uniform);
                     }
@@ -1688,11 +1688,11 @@
 
         auto var_type = [&](const sem::Variable* var) {
             switch (var->AddressSpace()) {
-                case ast::AddressSpace::kStorage:
+                case type::AddressSpace::kStorage:
                     return "read_write storage buffer ";
-                case ast::AddressSpace::kWorkgroup:
+                case type::AddressSpace::kWorkgroup:
                     return "workgroup storage variable ";
-                case ast::AddressSpace::kPrivate:
+                case type::AddressSpace::kPrivate:
                     return "module-scope private variable ";
                 default:
                     return "";
diff --git a/src/tint/resolver/uniformity_test.cc b/src/tint/resolver/uniformity_test.cc
index 5052a1f..2631976 100644
--- a/src/tint/resolver/uniformity_test.cc
+++ b/src/tint/resolver/uniformity_test.cc
@@ -5305,7 +5305,7 @@
     foo_body.Push(b.Decl(b.Let("rhs", rhs_init)));
     for (int i = 0; i < 255; i++) {
         params.Push(
-            b.Param("p" + std::to_string(i), ty.pointer(ty.i32(), ast::AddressSpace::kFunction)));
+            b.Param("p" + std::to_string(i), ty.pointer(ty.i32(), type::AddressSpace::kFunction)));
         if (i > 0) {
             foo_body.Push(b.Assign(b.Deref("p" + std::to_string(i)), "rhs"));
         }
@@ -5324,7 +5324,7 @@
     //     workgroupBarrier();
     //   }
     // }
-    b.GlobalVar("non_uniform_global", ty.i32(), ast::AddressSpace::kPrivate);
+    b.GlobalVar("non_uniform_global", ty.i32(), type::AddressSpace::kPrivate);
     utils::Vector<const ast::Statement*, 8> main_body;
     utils::Vector<const ast::Expression*, 8> args;
     for (int i = 0; i < 255; i++) {
@@ -7850,7 +7850,7 @@
     //     workgroupBarrier();
     //   }
     // }
-    b.GlobalVar("v0", ty.i32(), ast::AddressSpace::kPrivate, b.Expr(0_i));
+    b.GlobalVar("v0", ty.i32(), type::AddressSpace::kPrivate, b.Expr(0_i));
     utils::Vector<const ast::Statement*, 8> foo_body;
     std::string v_last = "v0";
     for (int i = 1; i < 100000; i++) {
diff --git a/src/tint/resolver/validation_test.cc b/src/tint/resolver/validation_test.cc
index b476602..67a26c7 100644
--- a/src/tint/resolver/validation_test.cc
+++ b/src/tint/resolver/validation_test.cc
@@ -37,6 +37,7 @@
 #include "src/tint/sem/statement.h"
 #include "src/tint/sem/variable.h"
 #include "src/tint/type/sampled_texture.h"
+#include "src/tint/type/texture_dimension.h"
 
 using ::testing::ElementsAre;
 using ::testing::HasSubstr;
@@ -61,8 +62,8 @@
 };
 
 TEST_F(ResolverValidationTest, WorkgroupMemoryUsedInVertexStage) {
-    GlobalVar(Source{{1, 2}}, "wg", ty.vec4<f32>(), ast::AddressSpace::kWorkgroup);
-    GlobalVar("dst", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar(Source{{1, 2}}, "wg", ty.vec4<f32>(), type::AddressSpace::kWorkgroup);
+    GlobalVar("dst", ty.vec4<f32>(), type::AddressSpace::kPrivate);
     auto* stmt = Assign(Expr("dst"), Expr(Source{{3, 4}}, "wg"));
 
     Func(Source{{9, 10}}, "f0", utils::Empty, ty.vec4<f32>(),
@@ -93,8 +94,8 @@
     //  f1();
     //}
 
-    GlobalVar(Source{{1, 2}}, "wg", ty.vec4<f32>(), ast::AddressSpace::kWorkgroup);
-    GlobalVar("dst", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar(Source{{1, 2}}, "wg", ty.vec4<f32>(), type::AddressSpace::kWorkgroup);
+    GlobalVar("dst", ty.vec4<f32>(), type::AddressSpace::kPrivate);
     auto* stmt = Assign(Expr("dst"), Expr(Source{{3, 4}}, "wg"));
 
     Func(Source{{5, 6}}, "f2", utils::Empty, ty.void_(), utils::Vector{stmt});
@@ -233,7 +234,7 @@
     //   return;
     // }
 
-    GlobalVar("global_var", ty.f32(), ast::AddressSpace::kPrivate, Expr(2.1_f));
+    GlobalVar("global_var", ty.f32(), type::AddressSpace::kPrivate, Expr(2.1_f));
 
     Func("my_func", utils::Empty, ty.void_(),
          utils::Vector{
@@ -307,7 +308,7 @@
 }
 
 TEST_F(ResolverValidationTest, AddressSpace_FunctionVariableWorkgroupClass) {
-    auto* var = Var("var", ty.i32(), ast::AddressSpace::kWorkgroup);
+    auto* var = Var("var", ty.i32(), type::AddressSpace::kWorkgroup);
 
     Func("func", utils::Empty, ty.void_(),
          utils::Vector{
@@ -321,7 +322,7 @@
 }
 
 TEST_F(ResolverValidationTest, AddressSpace_FunctionVariableI32) {
-    auto* var = Var("s", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* var = Var("s", ty.i32(), type::AddressSpace::kPrivate);
 
     Func("func", utils::Empty, ty.void_(),
          utils::Vector{
@@ -336,7 +337,7 @@
 
 TEST_F(ResolverValidationTest, AddressSpace_SamplerExplicitAddressSpace) {
     auto* t = ty.sampler(ast::SamplerKind::kSampler);
-    GlobalVar(Source{{12, 34}}, "var", t, ast::AddressSpace::kHandle, Binding(0_a), Group(0_a));
+    GlobalVar(Source{{12, 34}}, "var", t, type::AddressSpace::kHandle, Binding(0_a), Group(0_a));
 
     EXPECT_FALSE(r()->Resolve());
 
@@ -345,8 +346,8 @@
 }
 
 TEST_F(ResolverValidationTest, AddressSpace_TextureExplicitAddressSpace) {
-    auto* t = ty.sampled_texture(ast::TextureDimension::k1d, ty.f32());
-    GlobalVar(Source{{12, 34}}, "var", t, ast::AddressSpace::kHandle, Binding(0_a), Group(0_a));
+    auto* t = ty.sampled_texture(type::TextureDimension::k1d, ty.f32());
+    GlobalVar(Source{{12, 34}}, "var", t, type::AddressSpace::kHandle, Binding(0_a), Group(0_a));
 
     EXPECT_FALSE(r()->Resolve()) << r()->error();
 
@@ -355,7 +356,7 @@
 }
 
 TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_BadChar) {
-    GlobalVar("my_vec", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_vec", ty.vec3<f32>(), type::AddressSpace::kPrivate);
 
     auto* ident = Expr(Source{{{3, 3}, {3, 7}}}, "xyqz");
 
@@ -367,7 +368,7 @@
 }
 
 TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_MixedChars) {
-    GlobalVar("my_vec", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_vec", ty.vec4<f32>(), type::AddressSpace::kPrivate);
 
     auto* ident = Expr(Source{{{3, 3}, {3, 7}}}, "rgyw");
 
@@ -380,7 +381,7 @@
 }
 
 TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_BadLength) {
-    GlobalVar("my_vec", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_vec", ty.vec3<f32>(), type::AddressSpace::kPrivate);
 
     auto* ident = Expr(Source{{{3, 3}, {3, 8}}}, "zzzzz");
     auto* mem = MemberAccessor("my_vec", ident);
@@ -391,7 +392,7 @@
 }
 
 TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_BadIndex) {
-    GlobalVar("my_vec", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_vec", ty.vec2<f32>(), type::AddressSpace::kPrivate);
 
     auto* ident = Expr(Source{{3, 3}}, "z");
     auto* mem = MemberAccessor("my_vec", ident);
@@ -424,7 +425,7 @@
     //     let x: f32 = (*p).z;
     //     return x;
     // }
-    auto* p = Param("p", ty.pointer(ty.vec4<f32>(), ast::AddressSpace::kFunction));
+    auto* p = Param("p", ty.pointer(ty.vec4<f32>(), type::AddressSpace::kFunction));
     auto* star_p = Deref(p);
     auto* z = Expr("z");
     auto* accessor_expr = MemberAccessor(star_p, z);
@@ -442,7 +443,7 @@
     //     let x: f32 = *p.z;
     //     return x;
     // }
-    auto* p = Param("p", ty.pointer(ty.vec4<f32>(), ast::AddressSpace::kFunction));
+    auto* p = Param("p", ty.pointer(ty.vec4<f32>(), type::AddressSpace::kFunction));
     auto* z = Expr(Source{{12, 34}}, "z");
     auto* accessor_expr = MemberAccessor(p, z);
     auto* star_p = Deref(accessor_expr);
@@ -1276,8 +1277,8 @@
 TEST_F(ResolverTest, Expr_Initializer_Cast_Pointer) {
     auto* vf = Var("vf", ty.f32());
     auto* c =
-        Construct(Source{{12, 34}}, ty.pointer<i32>(ast::AddressSpace::kFunction), ExprList(vf));
-    auto* ip = Let("ip", ty.pointer<i32>(ast::AddressSpace::kFunction), c);
+        Construct(Source{{12, 34}}, ty.pointer<i32>(type::AddressSpace::kFunction), ExprList(vf));
+    auto* ip = Let("ip", ty.pointer<i32>(type::AddressSpace::kFunction), c);
     WrapInFunction(Decl(vf), Decl(ip));
 
     EXPECT_FALSE(r()->Resolve());
@@ -1285,21 +1286,21 @@
 }
 
 TEST_F(ResolverTest, I32_Overflow) {
-    GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate, Expr(Source{{12, 24}}, 2147483648_a));
+    GlobalVar("v", ty.i32(), type::AddressSpace::kPrivate, Expr(Source{{12, 24}}, 2147483648_a));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:24 error: value 2147483648 cannot be represented as 'i32'");
 }
 
 TEST_F(ResolverTest, I32_Underflow) {
-    GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate, Expr(Source{{12, 24}}, -2147483649_a));
+    GlobalVar("v", ty.i32(), type::AddressSpace::kPrivate, Expr(Source{{12, 24}}, -2147483649_a));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:24 error: value -2147483649 cannot be represented as 'i32'");
 }
 
 TEST_F(ResolverTest, U32_Overflow) {
-    GlobalVar("v", ty.u32(), ast::AddressSpace::kPrivate, Expr(Source{{12, 24}}, 4294967296_a));
+    GlobalVar("v", ty.u32(), type::AddressSpace::kPrivate, Expr(Source{{12, 24}}, 4294967296_a));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:24 error: value 4294967296 cannot be represented as 'u32'");
diff --git a/src/tint/resolver/validator.cc b/src/tint/resolver/validator.cc
index c25129a..18f53fb 100644
--- a/src/tint/resolver/validator.cc
+++ b/src/tint/resolver/validator.cc
@@ -73,6 +73,7 @@
 #include "src/tint/type/sampled_texture.h"
 #include "src/tint/type/sampler.h"
 #include "src/tint/type/storage_texture.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/utils/defer.h"
 #include "src/tint/utils/map.h"
 #include "src/tint/utils/math.h"
@@ -84,37 +85,37 @@
 namespace tint::resolver {
 namespace {
 
-bool IsValidStorageTextureDimension(ast::TextureDimension dim) {
+bool IsValidStorageTextureDimension(type::TextureDimension dim) {
     switch (dim) {
-        case ast::TextureDimension::k1d:
-        case ast::TextureDimension::k2d:
-        case ast::TextureDimension::k2dArray:
-        case ast::TextureDimension::k3d:
+        case type::TextureDimension::k1d:
+        case type::TextureDimension::k2d:
+        case type::TextureDimension::k2dArray:
+        case type::TextureDimension::k3d:
             return true;
         default:
             return false;
     }
 }
 
-bool IsValidStorageTextureTexelFormat(ast::TexelFormat format) {
+bool IsValidStorageTextureTexelFormat(type::TexelFormat format) {
     switch (format) {
-        case ast::TexelFormat::kBgra8Unorm:
-        case ast::TexelFormat::kR32Uint:
-        case ast::TexelFormat::kR32Sint:
-        case ast::TexelFormat::kR32Float:
-        case ast::TexelFormat::kRg32Uint:
-        case ast::TexelFormat::kRg32Sint:
-        case ast::TexelFormat::kRg32Float:
-        case ast::TexelFormat::kRgba8Unorm:
-        case ast::TexelFormat::kRgba8Snorm:
-        case ast::TexelFormat::kRgba8Uint:
-        case ast::TexelFormat::kRgba8Sint:
-        case ast::TexelFormat::kRgba16Uint:
-        case ast::TexelFormat::kRgba16Sint:
-        case ast::TexelFormat::kRgba16Float:
-        case ast::TexelFormat::kRgba32Uint:
-        case ast::TexelFormat::kRgba32Sint:
-        case ast::TexelFormat::kRgba32Float:
+        case type::TexelFormat::kBgra8Unorm:
+        case type::TexelFormat::kR32Uint:
+        case type::TexelFormat::kR32Sint:
+        case type::TexelFormat::kR32Float:
+        case type::TexelFormat::kRg32Uint:
+        case type::TexelFormat::kRg32Sint:
+        case type::TexelFormat::kRg32Float:
+        case type::TexelFormat::kRgba8Unorm:
+        case type::TexelFormat::kRgba8Snorm:
+        case type::TexelFormat::kRgba8Uint:
+        case type::TexelFormat::kRgba8Sint:
+        case type::TexelFormat::kRgba16Uint:
+        case type::TexelFormat::kRgba16Sint:
+        case type::TexelFormat::kRgba16Float:
+        case type::TexelFormat::kRgba32Uint:
+        case type::TexelFormat::kRgba32Sint:
+        case type::TexelFormat::kRgba32Float:
             return true;
         default:
             return false;
@@ -272,17 +273,17 @@
 }
 
 bool Validator::Pointer(const ast::Pointer* a, const type::Pointer* s) const {
-    if (s->AddressSpace() == ast::AddressSpace::kUndefined) {
+    if (s->AddressSpace() == type::AddressSpace::kUndefined) {
         AddError("ptr missing address space", a->source);
         return false;
     }
 
-    if (a->access != ast::Access::kUndefined) {
+    if (a->access != type::Access::kUndefined) {
         // https://www.w3.org/TR/WGSL/#access-mode-defaults
         // When writing a variable declaration or a pointer type in WGSL source:
         // * For the storage address space, the access mode is optional, and defaults to read.
         // * For other address spaces, the access mode must not be written.
-        if (a->address_space != ast::AddressSpace::kStorage) {
+        if (a->address_space != type::AddressSpace::kStorage) {
             AddError("only pointers in <storage> address space may declare an access mode",
                      a->source);
             return false;
@@ -295,9 +296,9 @@
 
 bool Validator::StorageTexture(const ast::StorageTexture* t) const {
     switch (t->access) {
-        case ast::Access::kWrite:
+        case type::Access::kWrite:
             break;
-        case ast::Access::kUndefined:
+        case type::Access::kUndefined:
             AddError("storage texture missing access control", t->source);
             return false;
         default:
@@ -331,7 +332,7 @@
 
 bool Validator::MultisampledTexture(const type::MultisampledTexture* t,
                                     const Source& source) const {
-    if (t->dim() != ast::TextureDimension::k2d) {
+    if (t->dim() != type::TextureDimension::k2d) {
         AddError("only 2d multisampled textures are supported", source);
         return false;
     }
@@ -357,7 +358,7 @@
 }
 
 bool Validator::VariableInitializer(const ast::Variable* v,
-                                    ast::AddressSpace address_space,
+                                    type::AddressSpace address_space,
                                     const type::Type* storage_ty,
                                     const sem::Expression* initializer) const {
     auto* initializer_ty = initializer->Type();
@@ -374,8 +375,8 @@
 
     if (v->Is<ast::Var>()) {
         switch (address_space) {
-            case ast::AddressSpace::kPrivate:
-            case ast::AddressSpace::kFunction:
+            case type::AddressSpace::kPrivate:
+            case type::AddressSpace::kFunction:
                 break;  // Allowed an initializer
             default:
                 // https://gpuweb.github.io/gpuweb/wgsl/#var-and-let
@@ -393,17 +394,17 @@
 }
 
 bool Validator::AddressSpaceLayout(const type::Type* store_ty,
-                                   ast::AddressSpace address_space,
+                                   type::AddressSpace address_space,
                                    Source source) const {
     // https://gpuweb.github.io/gpuweb/wgsl/#storage-class-layout-constraints
 
     auto is_uniform_struct_or_array = [address_space](const type::Type* ty) {
-        return address_space == ast::AddressSpace::kUniform &&
+        return address_space == type::AddressSpace::kUniform &&
                ty->IsAnyOf<type::Array, sem::Struct>();
     };
 
     auto is_uniform_struct = [address_space](const type::Type* ty) {
-        return address_space == ast::AddressSpace::kUniform && ty->Is<sem::Struct>();
+        return address_space == type::AddressSpace::kUniform && ty->Is<sem::Struct>();
     };
 
     auto required_alignment_of = [&](const type::Type* ty) {
@@ -424,7 +425,7 @@
         return true;
     }
 
-    if (!ast::IsHostShareable(address_space)) {
+    if (!type::IsHostShareable(address_space)) {
         return true;
     }
 
@@ -437,7 +438,7 @@
     // Among three host-shareable address spaces, f16 is supported in "uniform" and
     // "storage" address space, but not "push_constant" address space yet.
     if (Is<type::F16>(type::Type::DeepestElementOf(store_ty)) &&
-        address_space == ast::AddressSpace::kPushConstant) {
+        address_space == type::AddressSpace::kPushConstant) {
         AddError("using f16 types in 'push_constant' address space is not implemented yet", source);
         return false;
     }
@@ -514,7 +515,7 @@
             return false;
         }
 
-        if (address_space == ast::AddressSpace::kUniform) {
+        if (address_space == type::AddressSpace::kUniform) {
             // We already validated that this array member is itself aligned to 16 bytes above, so
             // we only need to validate that stride is a multiple of 16 bytes.
             if (arr->Stride() % 16 != 0) {
@@ -580,7 +581,7 @@
     const sem::GlobalVariable* global,
     const utils::Hashmap<OverrideId, const sem::Variable*, 8>& override_ids) const {
     auto* decl = global->Declaration();
-    if (global->AddressSpace() != ast::AddressSpace::kWorkgroup &&
+    if (global->AddressSpace() != type::AddressSpace::kWorkgroup &&
         IsArrayWithOverrideCount(global->Type())) {
         RaiseArrayWithOverrideCountError(decl->type ? decl->type->source
                                                     : decl->initializer->source);
@@ -596,7 +597,7 @@
                 return false;
             }
 
-            if (global->AddressSpace() == ast::AddressSpace::kNone) {
+            if (global->AddressSpace() == type::AddressSpace::kNone) {
                 AddError("module-scope 'var' declaration must have a address space", decl->source);
                 return false;
             }
@@ -605,8 +606,8 @@
                 bool is_shader_io_attribute =
                     attr->IsAnyOf<ast::BuiltinAttribute, ast::InterpolateAttribute,
                                   ast::InvariantAttribute, ast::LocationAttribute>();
-                bool has_io_address_space = global->AddressSpace() == ast::AddressSpace::kIn ||
-                                            global->AddressSpace() == ast::AddressSpace::kOut;
+                bool has_io_address_space = global->AddressSpace() == type::AddressSpace::kIn ||
+                                            global->AddressSpace() == type::AddressSpace::kOut;
                 if (!attr->IsAnyOf<ast::BindingAttribute, ast::GroupAttribute,
                                    ast::InternalAttribute>() &&
                     (!is_shader_io_attribute || !has_io_address_space)) {
@@ -638,15 +639,15 @@
         return false;
     }
 
-    if (global->AddressSpace() == ast::AddressSpace::kFunction) {
+    if (global->AddressSpace() == type::AddressSpace::kFunction) {
         AddError("module-scope 'var' must not use address space 'function'", decl->source);
         return false;
     }
 
     switch (global->AddressSpace()) {
-        case ast::AddressSpace::kUniform:
-        case ast::AddressSpace::kStorage:
-        case ast::AddressSpace::kHandle: {
+        case type::AddressSpace::kUniform:
+        case type::AddressSpace::kStorage:
+        case type::AddressSpace::kHandle: {
             // https://gpuweb.github.io/gpuweb/wgsl/#resource-interface
             // Each resource variable must be declared with both group and binding attributes.
             if (!decl->HasBindingPoint()) {
@@ -681,7 +682,7 @@
     }
 
     if (store_ty->is_handle()) {
-        if (var->declared_address_space != ast::AddressSpace::kNone) {
+        if (var->declared_address_space != type::AddressSpace::kNone) {
             // https://gpuweb.github.io/gpuweb/wgsl/#module-scope-variables
             // If the store type is a texture type or a sampler type, then the variable declaration
             // must not have a address space attribute. The address space will always be handle.
@@ -692,12 +693,12 @@
         }
     }
 
-    if (var->declared_access != ast::Access::kUndefined) {
+    if (var->declared_access != type::Access::kUndefined) {
         // https://www.w3.org/TR/WGSL/#access-mode-defaults
         // When writing a variable declaration or a pointer type in WGSL source:
         // * For the storage address space, the access mode is optional, and defaults to read.
         // * For other address spaces, the access mode must not be written.
-        if (var->declared_address_space != ast::AddressSpace::kStorage) {
+        if (var->declared_address_space != type::AddressSpace::kStorage) {
             AddError("only variables in <storage> address space may declare an access mode",
                      var->source);
             return false;
@@ -710,8 +711,8 @@
     }
 
     if (IsValidationEnabled(var->attributes, ast::DisabledValidation::kIgnoreAddressSpace) &&
-        (var->declared_address_space == ast::AddressSpace::kIn ||
-         var->declared_address_space == ast::AddressSpace::kOut)) {
+        (var->declared_address_space == type::AddressSpace::kIn ||
+         var->declared_address_space == type::AddressSpace::kOut)) {
         AddError("invalid use of input/output address space", var->source);
         return false;
     }
@@ -805,13 +806,13 @@
 
             auto sc = ref->AddressSpace();
             switch (sc) {
-                case ast::AddressSpace::kFunction:
-                case ast::AddressSpace::kPrivate:
+                case type::AddressSpace::kFunction:
+                case type::AddressSpace::kPrivate:
                     ok = true;
                     break;
-                case ast::AddressSpace::kStorage:
-                case ast::AddressSpace::kUniform:
-                case ast::AddressSpace::kWorkgroup:
+                case type::AddressSpace::kStorage:
+                case type::AddressSpace::kUniform:
+                case type::AddressSpace::kWorkgroup:
                     ok = enabled_extensions_.Contains(
                         ast::Extension::kChromiumExperimentalFullPtrParameters);
                     break;
@@ -1862,7 +1863,7 @@
         auto stage = entry_point->Declaration()->PipelineStage();
         if (stage != ast::PipelineStage::kCompute) {
             for (auto* var : func->DirectlyReferencedGlobals()) {
-                if (var->AddressSpace() == ast::AddressSpace::kWorkgroup) {
+                if (var->AddressSpace() == type::AddressSpace::kWorkgroup) {
                     std::stringstream stage_name;
                     stage_name << stage;
                     for (auto* user : var->Users()) {
@@ -1948,7 +1949,7 @@
 
         auto check_push_constant = [&](const sem::Function* func, const sem::Function* ep) {
             for (auto* var : func->DirectlyReferencedGlobals()) {
-                if (var->AddressSpace() != ast::AddressSpace::kPushConstant ||
+                if (var->AddressSpace() != type::AddressSpace::kPushConstant ||
                     var == push_constant_var) {
                     continue;
                 }
@@ -2352,7 +2353,7 @@
         AddError("storage type of assignment must be constructible", a->source);
         return false;
     }
-    if (lhs_ref->Access() == ast::Access::kRead) {
+    if (lhs_ref->Access() == type::Access::kRead) {
         AddError("cannot store into a read-only type '" + sem_.RawTypeNameOf(lhs_ty) + "'",
                  a->source);
         return false;
@@ -2393,7 +2394,7 @@
         return false;
     }
 
-    if (lhs_ref->Access() == ast::Access::kRead) {
+    if (lhs_ref->Access() == type::Access::kRead) {
         AddError("cannot modify read-only type '" + sem_.RawTypeNameOf(lhs_ty) + "'", inc->source);
         return false;
     }
@@ -2453,15 +2454,15 @@
 
 bool Validator::CheckTypeAccessAddressSpace(
     const type::Type* store_ty,
-    ast::Access access,
-    ast::AddressSpace address_space,
+    type::Access access,
+    type::AddressSpace address_space,
     utils::VectorRef<const tint::ast::Attribute*> attributes,
     const Source& source) const {
     if (!AddressSpaceLayout(store_ty, address_space, source)) {
         return false;
     }
 
-    if (address_space == ast::AddressSpace::kPushConstant &&
+    if (address_space == type::AddressSpace::kPushConstant &&
         !enabled_extensions_.Contains(ast::Extension::kChromiumExperimentalPushConstant) &&
         IsValidationEnabled(attributes, ast::DisabledValidation::kIgnoreAddressSpace)) {
         AddError(
@@ -2471,7 +2472,7 @@
         return false;
     }
 
-    if (address_space == ast::AddressSpace::kStorage && access == ast::Access::kWrite) {
+    if (address_space == type::AddressSpace::kStorage && access == type::Access::kWrite) {
         // The access mode for the storage address space can only be 'read' or
         // 'read_write'.
         AddError("access mode 'write' is not valid for the 'storage' address space", source);
@@ -2479,11 +2480,11 @@
     }
 
     auto atomic_error = [&]() -> const char* {
-        if (address_space != ast::AddressSpace::kStorage &&
-            address_space != ast::AddressSpace::kWorkgroup) {
+        if (address_space != type::AddressSpace::kStorage &&
+            address_space != type::AddressSpace::kWorkgroup) {
             return "atomic variables must have <storage> or <workgroup> address space";
         }
-        if (address_space == ast::AddressSpace::kStorage && access != ast::Access::kReadWrite) {
+        if (address_space == type::AddressSpace::kStorage && access != type::Access::kReadWrite) {
             return "atomic variables in <storage> address space must have read_write access "
                    "mode";
         }
diff --git a/src/tint/resolver/validator.h b/src/tint/resolver/validator.h
index aa6d9b3..891f02d 100644
--- a/src/tint/resolver/validator.h
+++ b/src/tint/resolver/validator.h
@@ -74,7 +74,7 @@
     /// The type
     const type::Type* type;
     /// The address space
-    ast::AddressSpace address_space;
+    type::AddressSpace address_space;
 
     /// Equality operator
     /// @param other the other TypeAndAddressSpace to compare this TypeAndAddressSpace to
@@ -418,7 +418,7 @@
     /// @param initializer the RHS initializer expression
     /// @returns true on succes, false otherwise
     bool VariableInitializer(const ast::Variable* v,
-                             ast::AddressSpace address_space,
+                             type::AddressSpace address_space,
                              const type::Type* storage_type,
                              const sem::Expression* initializer) const;
 
@@ -464,7 +464,7 @@
     /// @param sc the address space
     /// @param source the source of the type
     /// @returns true on success, false otherwise
-    bool AddressSpaceLayout(const type::Type* type, ast::AddressSpace sc, Source source) const;
+    bool AddressSpaceLayout(const type::Type* type, type::AddressSpace sc, Source source) const;
 
     /// @returns true if the attribute list contains a
     /// ast::DisableValidationAttribute with the validation mode equal to
@@ -518,8 +518,8 @@
     /// @param source the source for the error
     /// @returns true on success, false if an error was raised.
     bool CheckTypeAccessAddressSpace(const type::Type* store_ty,
-                                     ast::Access access,
-                                     ast::AddressSpace address_space,
+                                     type::Access access,
+                                     type::AddressSpace address_space,
                                      utils::VectorRef<const tint::ast::Attribute*> attributes,
                                      const Source& source) const;
     SymbolTable& symbols_;
diff --git a/src/tint/resolver/validator_is_storeable_test.cc b/src/tint/resolver/validator_is_storeable_test.cc
index 5bca58e..6c1fce4 100644
--- a/src/tint/resolver/validator_is_storeable_test.cc
+++ b/src/tint/resolver/validator_is_storeable_test.cc
@@ -78,8 +78,8 @@
 }
 
 TEST_F(ValidatorIsStorableTest, Pointer) {
-    auto* ptr = create<type::Pointer>(create<type::I32>(), ast::AddressSpace::kPrivate,
-                                      ast::Access::kReadWrite);
+    auto* ptr = create<type::Pointer>(create<type::I32>(), type::AddressSpace::kPrivate,
+                                      type::Access::kReadWrite);
     EXPECT_FALSE(v()->IsStorable(ptr));
 }
 
diff --git a/src/tint/resolver/variable_test.cc b/src/tint/resolver/variable_test.cc
index 552ad08..b62812a 100644
--- a/src/tint/resolver/variable_test.cc
+++ b/src/tint/resolver/variable_test.cc
@@ -12,11 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#include "gmock/gmock.h"
 #include "src/tint/resolver/resolver.h"
 #include "src/tint/resolver/resolver_test_helper.h"
 #include "src/tint/type/reference.h"
-
-#include "gmock/gmock.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::resolver {
 namespace {
@@ -149,12 +149,12 @@
     ASSERT_TRUE(TypeOf(s)->Is<type::Reference>());
     ASSERT_TRUE(TypeOf(a)->Is<type::Reference>());
 
-    EXPECT_EQ(TypeOf(i)->As<type::Reference>()->Access(), ast::Access::kReadWrite);
-    EXPECT_EQ(TypeOf(u)->As<type::Reference>()->Access(), ast::Access::kReadWrite);
-    EXPECT_EQ(TypeOf(f)->As<type::Reference>()->Access(), ast::Access::kReadWrite);
-    EXPECT_EQ(TypeOf(b)->As<type::Reference>()->Access(), ast::Access::kReadWrite);
-    EXPECT_EQ(TypeOf(s)->As<type::Reference>()->Access(), ast::Access::kReadWrite);
-    EXPECT_EQ(TypeOf(a)->As<type::Reference>()->Access(), ast::Access::kReadWrite);
+    EXPECT_EQ(TypeOf(i)->As<type::Reference>()->Access(), type::Access::kReadWrite);
+    EXPECT_EQ(TypeOf(u)->As<type::Reference>()->Access(), type::Access::kReadWrite);
+    EXPECT_EQ(TypeOf(f)->As<type::Reference>()->Access(), type::Access::kReadWrite);
+    EXPECT_EQ(TypeOf(b)->As<type::Reference>()->Access(), type::Access::kReadWrite);
+    EXPECT_EQ(TypeOf(s)->As<type::Reference>()->Access(), type::Access::kReadWrite);
+    EXPECT_EQ(TypeOf(a)->As<type::Reference>()->Access(), type::Access::kReadWrite);
 
     EXPECT_TRUE(TypeOf(i)->As<type::Reference>()->StoreType()->Is<type::I32>());
     EXPECT_TRUE(TypeOf(u)->As<type::Reference>()->StoreType()->Is<type::U32>());
@@ -238,7 +238,7 @@
     //   var a = a;
     // }
 
-    auto* g = GlobalVar("a", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* g = GlobalVar("a", ty.i32(), type::AddressSpace::kPrivate);
     auto* v = Var("a", Expr("a"));
     Func("F", utils::Empty, ty.void_(), utils::Vector{Decl(v)});
 
@@ -421,7 +421,7 @@
     auto* b = Let("b", ty.bool_(), b_c);
     auto* s = Let("s", ty.Of(S), s_c);
     auto* a = Let("a", ty.Of(A), a_c);
-    auto* p = Let("p", ty.pointer<i32>(ast::AddressSpace::kFunction), p_c);
+    auto* p = Let("p", ty.pointer<i32>(type::AddressSpace::kFunction), p_c);
 
     Func("F", utils::Empty, ty.void_(),
          utils::Vector{
@@ -472,8 +472,8 @@
     // }
     auto* inner = Structure("Inner", utils::Vector{Member("arr", ty.array<i32, 4>())});
     auto* buf = Structure("S", utils::Vector{Member("inner", ty.Of(inner))});
-    auto* storage = GlobalVar("s", ty.Of(buf), ast::AddressSpace::kStorage, ast::Access::kReadWrite,
-                              Binding(0_a), Group(0_a));
+    auto* storage = GlobalVar("s", ty.Of(buf), type::AddressSpace::kStorage,
+                              type::Access::kReadWrite, Binding(0_a), Group(0_a));
 
     auto* expr = IndexAccessor(MemberAccessor(MemberAccessor(storage, "inner"), "arr"), 3_i);
     auto* ptr = Let("p", AddressOf(expr));
@@ -485,8 +485,8 @@
     ASSERT_TRUE(TypeOf(expr)->Is<type::Reference>());
     ASSERT_TRUE(TypeOf(ptr)->Is<type::Pointer>());
 
-    EXPECT_EQ(TypeOf(expr)->As<type::Reference>()->Access(), ast::Access::kReadWrite);
-    EXPECT_EQ(TypeOf(ptr)->As<type::Pointer>()->Access(), ast::Access::kReadWrite);
+    EXPECT_EQ(TypeOf(expr)->As<type::Reference>()->Access(), type::Access::kReadWrite);
+    EXPECT_EQ(TypeOf(ptr)->As<type::Pointer>()->Access(), type::Access::kReadWrite);
 }
 
 TEST_F(ResolverVariableTest, LocalLet_ShadowsAlias) {
@@ -554,7 +554,7 @@
     //   let a = a;
     // }
 
-    auto* g = GlobalVar("a", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* g = GlobalVar("a", ty.i32(), type::AddressSpace::kPrivate);
     auto* l = Let("a", Expr("a"));
     Func("F", utils::Empty, ty.void_(), utils::Vector{Decl(l)});
 
@@ -766,7 +766,7 @@
     //   const a = 1i;
     // }
 
-    auto* g = GlobalVar("a", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* g = GlobalVar("a", ty.i32(), type::AddressSpace::kPrivate);
     auto* c = Const("a", Expr(1_i));
     Func("F", utils::Empty, ty.void_(), utils::Vector{Decl(c)});
 
@@ -1037,14 +1037,14 @@
     // https://gpuweb.github.io/gpuweb/wgsl/#storage-class
 
     auto* buf = Structure("S", utils::Vector{Member("m", ty.i32())});
-    auto* private_ = GlobalVar("p", ty.i32(), ast::AddressSpace::kPrivate);
-    auto* workgroup = GlobalVar("w", ty.i32(), ast::AddressSpace::kWorkgroup);
+    auto* private_ = GlobalVar("p", ty.i32(), type::AddressSpace::kPrivate);
+    auto* workgroup = GlobalVar("w", ty.i32(), type::AddressSpace::kWorkgroup);
     auto* uniform =
-        GlobalVar("ub", ty.Of(buf), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a));
+        GlobalVar("ub", ty.Of(buf), type::AddressSpace::kUniform, Binding(0_a), Group(0_a));
     auto* storage =
-        GlobalVar("sb", ty.Of(buf), ast::AddressSpace::kStorage, Binding(1_a), Group(0_a));
+        GlobalVar("sb", ty.Of(buf), type::AddressSpace::kStorage, Binding(1_a), Group(0_a));
     auto* handle =
-        GlobalVar("h", ty.depth_texture(ast::TextureDimension::k2d), Binding(2_a), Group(0_a));
+        GlobalVar("h", ty.depth_texture(type::TextureDimension::k2d), Binding(2_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 
@@ -1054,25 +1054,25 @@
     ASSERT_TRUE(TypeOf(storage)->Is<type::Reference>());
     ASSERT_TRUE(TypeOf(handle)->Is<type::Reference>());
 
-    EXPECT_EQ(TypeOf(private_)->As<type::Reference>()->Access(), ast::Access::kReadWrite);
-    EXPECT_EQ(TypeOf(workgroup)->As<type::Reference>()->Access(), ast::Access::kReadWrite);
-    EXPECT_EQ(TypeOf(uniform)->As<type::Reference>()->Access(), ast::Access::kRead);
-    EXPECT_EQ(TypeOf(storage)->As<type::Reference>()->Access(), ast::Access::kRead);
-    EXPECT_EQ(TypeOf(handle)->As<type::Reference>()->Access(), ast::Access::kRead);
+    EXPECT_EQ(TypeOf(private_)->As<type::Reference>()->Access(), type::Access::kReadWrite);
+    EXPECT_EQ(TypeOf(workgroup)->As<type::Reference>()->Access(), type::Access::kReadWrite);
+    EXPECT_EQ(TypeOf(uniform)->As<type::Reference>()->Access(), type::Access::kRead);
+    EXPECT_EQ(TypeOf(storage)->As<type::Reference>()->Access(), type::Access::kRead);
+    EXPECT_EQ(TypeOf(handle)->As<type::Reference>()->Access(), type::Access::kRead);
 }
 
 TEST_F(ResolverVariableTest, GlobalVar_ExplicitAddressSpace) {
     // https://gpuweb.github.io/gpuweb/wgsl/#storage-class
 
     auto* buf = Structure("S", utils::Vector{Member("m", ty.i32())});
-    auto* storage = GlobalVar("sb", ty.Of(buf), ast::AddressSpace::kStorage,
-                              ast::Access::kReadWrite, Binding(1_a), Group(0_a));
+    auto* storage = GlobalVar("sb", ty.Of(buf), type::AddressSpace::kStorage,
+                              type::Access::kReadWrite, Binding(1_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 
     ASSERT_TRUE(TypeOf(storage)->Is<type::Reference>());
 
-    EXPECT_EQ(TypeOf(storage)->As<type::Reference>()->Access(), ast::Access::kReadWrite);
+    EXPECT_EQ(TypeOf(storage)->As<type::Reference>()->Access(), type::Access::kReadWrite);
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1222,7 +1222,7 @@
     // fn F(a : bool) {
     // }
 
-    auto* g = GlobalVar("a", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* g = GlobalVar("a", ty.i32(), type::AddressSpace::kPrivate);
     auto* p = Param("a", ty.bool_());
     Func("F", utils::Vector{p}, ty.void_(), utils::Empty);
 
diff --git a/src/tint/resolver/variable_validation_test.cc b/src/tint/resolver/variable_validation_test.cc
index cf35e4c..0906322 100644
--- a/src/tint/resolver/variable_validation_test.cc
+++ b/src/tint/resolver/variable_validation_test.cc
@@ -12,10 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#include "gmock/gmock.h"
 #include "src/tint/resolver/resolver.h"
 #include "src/tint/resolver/resolver_test_helper.h"
-
-#include "gmock/gmock.h"
+#include "src/tint/type/texture_dimension.h"
 
 using namespace tint::number_suffixes;  // NOLINT
 
@@ -61,8 +61,8 @@
 TEST_F(ResolverVariableValidationTest, GlobalVarUsedAtModuleScope) {
     // var<private> a : i32;
     // var<private> b : i32 = a;
-    GlobalVar(Source{{12, 34}}, "a", ty.i32(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.i32(), ast::AddressSpace::kPrivate, Expr(Source{{56, 78}}, "a"));
+    GlobalVar(Source{{12, 34}}, "a", ty.i32(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.i32(), type::AddressSpace::kPrivate, Expr(Source{{56, 78}}, "a"));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), R"(56:78 error: var 'a' cannot be referenced at module-scope
@@ -112,8 +112,8 @@
     // var i : i32;
     // var p : pointer<function, i32> = &v;
     auto* i = Var("i", ty.i32());
-    auto* p = Var("a", ty.pointer<i32>(Source{{56, 78}}, ast::AddressSpace::kFunction),
-                  ast::AddressSpace::kNone, AddressOf(Source{{12, 34}}, "i"));
+    auto* p = Var("a", ty.pointer<i32>(Source{{56, 78}}, type::AddressSpace::kFunction),
+                  type::AddressSpace::kNone, AddressOf(Source{{12, 34}}, "i"));
     WrapInFunction(i, p);
 
     EXPECT_FALSE(r()->Resolve());
@@ -123,8 +123,8 @@
 TEST_F(ResolverVariableValidationTest, LetTypeNotConstructible) {
     // @group(0) @binding(0) var t1 : texture_2d<f32>;
     // let t2 : t1;
-    auto* t1 = GlobalVar("t1", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), Group(0_a),
-                         Binding(0_a));
+    auto* t1 = GlobalVar("t1", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()),
+                         Group(0_a), Binding(0_a));
     auto* t2 = Let(Source{{56, 78}}, "t2", Expr(t1));
     WrapInFunction(t2);
 
@@ -205,7 +205,7 @@
 TEST_F(ResolverVariableValidationTest, LetOfPtrConstructedWithRef) {
     // var a : f32;
     // let b : ptr<function,f32> = a;
-    const auto priv = ast::AddressSpace::kFunction;
+    const auto priv = type::AddressSpace::kFunction;
     auto* var_a = Var("a", ty.f32(), priv);
     auto* var_b = Let(Source{{12, 34}}, "b", ty.pointer<f32>(priv), Expr("a"));
     WrapInFunction(var_a, var_b);
@@ -236,7 +236,7 @@
     //   return 0;
     // }
 
-    GlobalVar("v", ty.f32(), ast::AddressSpace::kPrivate, Expr(2.1_f));
+    GlobalVar("v", ty.f32(), type::AddressSpace::kPrivate, Expr(2.1_f));
 
     WrapInFunction(Var(Source{{12, 34}}, "v", ty.f32(), Expr(2_f)));
 
@@ -295,12 +295,12 @@
                                    Member("inner", ty.Of(inner)),
                                });
     auto* storage =
-        GlobalVar("s", ty.Of(buf), ast::AddressSpace::kStorage, Binding(0_a), Group(0_a));
+        GlobalVar("s", ty.Of(buf), type::AddressSpace::kStorage, Binding(0_a), Group(0_a));
 
     auto* expr = IndexAccessor(MemberAccessor(MemberAccessor(storage, "inner"), "arr"), 2_i);
-    auto* ptr =
-        Let(Source{{12, 34}}, "p",
-            ty.pointer<i32>(ast::AddressSpace::kStorage, ast::Access::kReadWrite), AddressOf(expr));
+    auto* ptr = Let(Source{{12, 34}}, "p",
+                    ty.pointer<i32>(type::AddressSpace::kStorage, type::Access::kReadWrite),
+                    AddressOf(expr));
 
     WrapInFunction(ptr);
 
@@ -359,7 +359,7 @@
 
 TEST_F(ResolverVariableValidationTest, InvalidAddressSpaceForInitializer) {
     // var<workgroup> v : f32 = 1.23;
-    GlobalVar(Source{{12, 34}}, "v", ty.f32(), ast::AddressSpace::kWorkgroup, Expr(1.23_f));
+    GlobalVar(Source{{12, 34}}, "v", ty.f32(), type::AddressSpace::kWorkgroup, Expr(1.23_f));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -490,7 +490,7 @@
     // enable chromium_experimental_push_constant;
     // var<push_constant> a : u32 = 0u;
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
-    GlobalVar(Source{{1u, 2u}}, "a", ty.u32(), ast::AddressSpace::kPushConstant,
+    GlobalVar(Source{{1u, 2u}}, "a", ty.u32(), type::AddressSpace::kPushConstant,
               Expr(Source{{3u, 4u}}, u32(0)));
 
     ASSERT_FALSE(r()->Resolve());
diff --git a/src/tint/sem/function.cc b/src/tint/sem/function.cc
index 6f074a4..dabf1ae 100644
--- a/src/tint/sem/function.cc
+++ b/src/tint/sem/function.cc
@@ -68,7 +68,7 @@
     VariableBindings ret;
 
     for (auto* global : TransitivelyReferencedGlobals()) {
-        if (global->AddressSpace() != ast::AddressSpace::kUniform) {
+        if (global->AddressSpace() != type::AddressSpace::kUniform) {
             continue;
         }
 
@@ -83,7 +83,7 @@
     VariableBindings ret;
 
     for (auto* global : TransitivelyReferencedGlobals()) {
-        if (global->AddressSpace() != ast::AddressSpace::kStorage) {
+        if (global->AddressSpace() != type::AddressSpace::kStorage) {
             continue;
         }
 
diff --git a/src/tint/sem/struct.h b/src/tint/sem/struct.h
index a05a96a..42a1117 100644
--- a/src/tint/sem/struct.h
+++ b/src/tint/sem/struct.h
@@ -17,9 +17,9 @@
 
 #include <optional>
 
-#include "src/tint/ast/address_space.h"
 #include "src/tint/ast/struct.h"
 #include "src/tint/symbol.h"
+#include "src/tint/type/address_space.h"
 #include "src/tint/type/struct.h"
 #include "src/tint/type/type.h"
 #include "src/tint/utils/vector.h"
diff --git a/src/tint/sem/variable.cc b/src/tint/sem/variable.cc
index db5edfe..6dc327d 100644
--- a/src/tint/sem/variable.cc
+++ b/src/tint/sem/variable.cc
@@ -31,8 +31,8 @@
 Variable::Variable(const ast::Variable* declaration,
                    const type::Type* type,
                    EvaluationStage stage,
-                   ast::AddressSpace address_space,
-                   ast::Access access,
+                   type::AddressSpace address_space,
+                   type::Access access,
                    const constant::Value* constant_value)
     : declaration_(declaration),
       type_(type),
@@ -46,8 +46,8 @@
 LocalVariable::LocalVariable(const ast::Variable* declaration,
                              const type::Type* type,
                              EvaluationStage stage,
-                             ast::AddressSpace address_space,
-                             ast::Access access,
+                             type::AddressSpace address_space,
+                             type::Access access,
                              const sem::Statement* statement,
                              const constant::Value* constant_value)
     : Base(declaration, type, stage, address_space, access, constant_value),
@@ -58,8 +58,8 @@
 GlobalVariable::GlobalVariable(const ast::Variable* declaration,
                                const type::Type* type,
                                EvaluationStage stage,
-                               ast::AddressSpace address_space,
-                               ast::Access access,
+                               type::AddressSpace address_space,
+                               type::Access access,
                                const constant::Value* constant_value,
                                sem::BindingPoint binding_point,
                                std::optional<uint32_t> location)
@@ -72,8 +72,8 @@
 Parameter::Parameter(const ast::Parameter* declaration,
                      uint32_t index,
                      const type::Type* type,
-                     ast::AddressSpace address_space,
-                     ast::Access access,
+                     type::AddressSpace address_space,
+                     type::Access access,
                      const ParameterUsage usage /* = ParameterUsage::kNone */,
                      sem::BindingPoint binding_point /* = {} */,
                      std::optional<uint32_t> location /* = std::nullopt */)
diff --git a/src/tint/sem/variable.h b/src/tint/sem/variable.h
index bf2a2d5..cecad1e 100644
--- a/src/tint/sem/variable.h
+++ b/src/tint/sem/variable.h
@@ -21,12 +21,12 @@
 
 #include "tint/override_id.h"
 
-#include "src/tint/ast/access.h"
-#include "src/tint/ast/address_space.h"
 #include "src/tint/ast/parameter.h"
 #include "src/tint/sem/binding_point.h"
 #include "src/tint/sem/expression.h"
 #include "src/tint/sem/parameter_usage.h"
+#include "src/tint/type/access.h"
+#include "src/tint/type/address_space.h"
 #include "src/tint/type/type.h"
 #include "src/tint/utils/unique_vector.h"
 
@@ -57,8 +57,8 @@
     Variable(const ast::Variable* declaration,
              const type::Type* type,
              EvaluationStage stage,
-             ast::AddressSpace address_space,
-             ast::Access access,
+             type::AddressSpace address_space,
+             type::Access access,
              const constant::Value* constant_value);
 
     /// Destructor
@@ -74,10 +74,10 @@
     EvaluationStage Stage() const { return stage_; }
 
     /// @returns the address space for the variable
-    ast::AddressSpace AddressSpace() const { return address_space_; }
+    type::AddressSpace AddressSpace() const { return address_space_; }
 
     /// @returns the access control for the variable
-    ast::Access Access() const { return access_; }
+    type::Access Access() const { return access_; }
 
     /// @return the constant value of this expression
     const constant::Value* ConstantValue() const { return constant_value_; }
@@ -100,8 +100,8 @@
     const ast::Variable* const declaration_;
     const type::Type* const type_;
     const EvaluationStage stage_;
-    const ast::AddressSpace address_space_;
-    const ast::Access access_;
+    const type::AddressSpace address_space_;
+    const type::Access access_;
     const constant::Value* constant_value_;
     const Expression* initializer_ = nullptr;
     std::vector<const VariableUser*> users_;
@@ -121,8 +121,8 @@
     LocalVariable(const ast::Variable* declaration,
                   const type::Type* type,
                   EvaluationStage stage,
-                  ast::AddressSpace address_space,
-                  ast::Access access,
+                  type::AddressSpace address_space,
+                  type::Access access,
                   const sem::Statement* statement,
                   const constant::Value* constant_value);
 
@@ -162,8 +162,8 @@
     GlobalVariable(const ast::Variable* declaration,
                    const type::Type* type,
                    EvaluationStage stage,
-                   ast::AddressSpace address_space,
-                   ast::Access access,
+                   type::AddressSpace address_space,
+                   type::Access access,
                    const constant::Value* constant_value,
                    sem::BindingPoint binding_point = {},
                    std::optional<uint32_t> location = std::nullopt);
@@ -205,8 +205,8 @@
     Parameter(const ast::Parameter* declaration,
               uint32_t index,
               const type::Type* type,
-              ast::AddressSpace address_space,
-              ast::Access access,
+              type::AddressSpace address_space,
+              type::Access access,
               const ParameterUsage usage = ParameterUsage::kNone,
               sem::BindingPoint binding_point = {},
               std::optional<uint32_t> location = std::nullopt);
diff --git a/src/tint/transform/add_block_attribute.cc b/src/tint/transform/add_block_attribute.cc
index c50c2d5..c2d674b 100644
--- a/src/tint/transform/add_block_attribute.cc
+++ b/src/tint/transform/add_block_attribute.cc
@@ -47,7 +47,7 @@
     bool made_changes = false;
     for (auto* global : src->AST().GlobalVariables()) {
         auto* var = sem.Get(global);
-        if (!ast::IsHostShareable(var->AddressSpace())) {
+        if (!type::IsHostShareable(var->AddressSpace())) {
             // Not declared in a host-sharable address space
             continue;
         }
diff --git a/src/tint/transform/array_length_from_uniform.cc b/src/tint/transform/array_length_from_uniform.cc
index 3f470fa..9cbf5f9 100644
--- a/src/tint/transform/array_length_from_uniform.cc
+++ b/src/tint/transform/array_length_from_uniform.cc
@@ -107,7 +107,7 @@
                                                      u32((max_buffer_size_index / 4) + 1))),
                              });
                 buffer_size_ubo =
-                    b.GlobalVar(b.Sym(), b.ty.Of(buffer_size_struct), ast::AddressSpace::kUniform,
+                    b.GlobalVar(b.Sym(), b.ty.Of(buffer_size_struct), type::AddressSpace::kUniform,
                                 b.Group(AInt(cfg->ubo_binding.group)),
                                 b.Binding(AInt(cfg->ubo_binding.binding)));
             }
diff --git a/src/tint/transform/binding_remapper.cc b/src/tint/transform/binding_remapper.cc
index 0781355..5967d84 100644
--- a/src/tint/transform/binding_remapper.cc
+++ b/src/tint/transform/binding_remapper.cc
@@ -122,15 +122,15 @@
             // Replace any access controls.
             auto ac_it = remappings->access_controls.find(from);
             if (ac_it != remappings->access_controls.end()) {
-                ast::Access ac = ac_it->second;
-                if (ac == ast::Access::kUndefined) {
+                type::Access ac = ac_it->second;
+                if (ac == type::Access::kUndefined) {
                     b.Diagnostics().add_error(
                         diag::System::Transform,
                         "invalid access mode (" + std::to_string(static_cast<uint32_t>(ac)) + ")");
                     return Program(std::move(b));
                 }
                 auto* sem = src->Sem().Get(var);
-                if (sem->AddressSpace() != ast::AddressSpace::kStorage) {
+                if (sem->AddressSpace() != type::AddressSpace::kStorage) {
                     b.Diagnostics().add_error(
                         diag::System::Transform,
                         "cannot apply access control to variable with address space " +
diff --git a/src/tint/transform/binding_remapper.h b/src/tint/transform/binding_remapper.h
index b0efe0d..e0f48b3 100644
--- a/src/tint/transform/binding_remapper.h
+++ b/src/tint/transform/binding_remapper.h
@@ -17,9 +17,9 @@
 
 #include <unordered_map>
 
-#include "src/tint/ast/access.h"
 #include "src/tint/sem/binding_point.h"
 #include "src/tint/transform/transform.h"
+#include "src/tint/type/access.h"
 
 namespace tint::transform {
 
@@ -34,7 +34,7 @@
     using BindingPoints = std::unordered_map<BindingPoint, BindingPoint>;
 
     /// AccessControls is a map of old binding point to new access control
-    using AccessControls = std::unordered_map<BindingPoint, ast::Access>;
+    using AccessControls = std::unordered_map<BindingPoint, type::Access>;
 
     /// Remappings is consumed by the BindingRemapper transform.
     /// Data holds information about shader usage and constant buffer offsets.
diff --git a/src/tint/transform/binding_remapper_test.cc b/src/tint/transform/binding_remapper_test.cc
index 5bafb7e..5bed528 100644
--- a/src/tint/transform/binding_remapper_test.cc
+++ b/src/tint/transform/binding_remapper_test.cc
@@ -52,7 +52,7 @@
     DataMap data;
     data.Add<BindingRemapper::Remappings>(BindingRemapper::BindingPoints{},
                                           BindingRemapper::AccessControls{
-                                              {{2, 1}, ast::Access::kWrite},
+                                              {{2, 1}, type::Access::kWrite},
                                           });
 
     EXPECT_TRUE(ShouldRun<BindingRemapper>(src, data));
@@ -162,9 +162,9 @@
     data.Add<BindingRemapper::Remappings>(
         BindingRemapper::BindingPoints{},
         BindingRemapper::AccessControls{
-            {{2, 1}, ast::Access::kReadWrite},  // Modify access control
+            {{2, 1}, type::Access::kReadWrite},  // Modify access control
             // Keep @group(3) @binding(2) as is
-            {{4, 3}, ast::Access::kRead},  // Add access control
+            {{4, 3}, type::Access::kRead},  // Add access control
         });
     auto got = Run<BindingRemapper>(src, data);
 
@@ -207,8 +207,8 @@
             {{3, 2}, {6, 7}},
         },
         BindingRemapper::AccessControls{
-            {{2, 1}, ast::Access::kReadWrite},
-            {{3, 2}, ast::Access::kReadWrite},
+            {{2, 1}, type::Access::kReadWrite},
+            {{3, 2}, type::Access::kReadWrite},
         });
     auto got = Run<BindingRemapper>(src, data);
 
diff --git a/src/tint/transform/builtin_polyfill.cc b/src/tint/transform/builtin_polyfill.cc
index dbd6f6e..4c196af 100644
--- a/src/tint/transform/builtin_polyfill.cc
+++ b/src/tint/transform/builtin_polyfill.cc
@@ -22,6 +22,7 @@
 #include "src/tint/program_builder.h"
 #include "src/tint/sem/builtin.h"
 #include "src/tint/sem/call.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/utils/map.h"
 
 using namespace tint::number_suffixes;  // NOLINT
@@ -638,7 +639,7 @@
         };
         b.Func(name,
                utils::Vector{
-                   b.Param("t", b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32())),
+                   b.Param("t", b.ty.sampled_texture(type::TextureDimension::k2d, b.ty.f32())),
                    b.Param("s", b.ty.sampler(ast::SamplerKind::kSampler)),
                    b.Param("coord", b.ty.vec2<f32>()),
                },
@@ -678,7 +679,7 @@
         auto name = b.Symbols().New("tint_workgroupUniformLoad");
         b.Func(name,
                utils::Vector{
-                   b.Param("p", b.ty.pointer(T(type), ast::AddressSpace::kWorkgroup)),
+                   b.Param("p", b.ty.pointer(T(type), type::AddressSpace::kWorkgroup)),
                },
                T(type),
                utils::Vector{
@@ -945,7 +946,7 @@
                             auto& sig = builtin->Signature();
                             auto* tex = sig.Parameter(sem::ParameterUsage::kTexture);
                             if (auto* stex = tex->Type()->As<type::StorageTexture>()) {
-                                if (stex->texel_format() == ast::TexelFormat::kBgra8Unorm) {
+                                if (stex->texel_format() == type::TexelFormat::kBgra8Unorm) {
                                     size_t value_idx = static_cast<size_t>(
                                         sig.IndexOf(sem::ParameterUsage::kValue));
                                     ctx.Replace(expr, [&ctx, expr, value_idx] {
@@ -1025,9 +1026,9 @@
                 }
             },
             [&](const ast::StorageTexture* tex) {
-                if (polyfill.bgra8unorm && tex->format == ast::TexelFormat::kBgra8Unorm) {
+                if (polyfill.bgra8unorm && tex->format == type::TexelFormat::kBgra8Unorm) {
                     ctx.Replace(tex, [&ctx, tex] {
-                        return ctx.dst->ty.storage_texture(tex->dim, ast::TexelFormat::kRgba8Unorm,
+                        return ctx.dst->ty.storage_texture(tex->dim, type::TexelFormat::kRgba8Unorm,
                                                            tex->access);
                     });
                     made_changes = true;
diff --git a/src/tint/transform/calculate_array_length.cc b/src/tint/transform/calculate_array_length.cc
index 0469dc9..886f839 100644
--- a/src/tint/transform/calculate_array_length.cc
+++ b/src/tint/transform/calculate_array_length.cc
@@ -112,7 +112,7 @@
                     b.Param("buffer",
                             b.ty.pointer(type, buffer_type->AddressSpace(), buffer_type->Access()),
                             utils::Vector{disable_validation}),
-                    b.Param("result", b.ty.pointer(b.ty.u32(), ast::AddressSpace::kFunction)),
+                    b.Param("result", b.ty.pointer(b.ty.u32(), type::AddressSpace::kFunction)),
                 },
                 b.ty.void_(), nullptr,
                 utils::Vector{
diff --git a/src/tint/transform/canonicalize_entry_point_io.cc b/src/tint/transform/canonicalize_entry_point_io.cc
index 1afad12..a662053 100644
--- a/src/tint/transform/canonicalize_entry_point_io.cc
+++ b/src/tint/transform/canonicalize_entry_point_io.cc
@@ -234,7 +234,7 @@
             auto* builtin = ast::GetAttribute<ast::BuiltinAttribute>(attributes);
             if (cfg.shader_style == ShaderStyle::kGlsl && builtin) {
                 name = GLSLBuiltinToString(builtin->builtin, func_ast->PipelineStage(),
-                                           ast::AddressSpace::kIn);
+                                           type::AddressSpace::kIn);
             }
             auto symbol = ctx.dst->Symbols().New(name);
 
@@ -251,7 +251,7 @@
                     value = ctx.dst->IndexAccessor(value, 0_i);
                 }
             }
-            ctx.dst->GlobalVar(symbol, ast_type, ast::AddressSpace::kIn, std::move(attributes));
+            ctx.dst->GlobalVar(symbol, ast_type, type::AddressSpace::kIn, std::move(attributes));
             return value;
         } else if (cfg.shader_style == ShaderStyle::kMsl &&
                    ast::HasAttribute<ast::BuiltinAttribute>(attributes)) {
@@ -300,7 +300,7 @@
         if (cfg.shader_style == ShaderStyle::kGlsl) {
             if (auto* b = ast::GetAttribute<ast::BuiltinAttribute>(attributes)) {
                 name = GLSLBuiltinToString(b->builtin, func_ast->PipelineStage(),
-                                           ast::AddressSpace::kOut);
+                                           type::AddressSpace::kOut);
                 value = ToGLSLBuiltin(b->builtin, value, type);
             }
         }
@@ -530,7 +530,7 @@
                 type = ctx.dst->ty.array(type, 1_u);
                 lhs = ctx.dst->IndexAccessor(lhs, 0_i);
             }
-            ctx.dst->GlobalVar(name, type, ast::AddressSpace::kOut, std::move(attributes));
+            ctx.dst->GlobalVar(name, type, type::AddressSpace::kOut, std::move(attributes));
             wrapper_body.Push(ctx.dst->Assign(lhs, outval.value));
         }
     }
@@ -674,7 +674,7 @@
     /// @returns the gl_ string corresponding to that builtin
     const char* GLSLBuiltinToString(ast::BuiltinValue builtin,
                                     ast::PipelineStage stage,
-                                    ast::AddressSpace address_space) {
+                                    type::AddressSpace address_space) {
         switch (builtin) {
             case ast::BuiltinValue::kPosition:
                 switch (stage) {
@@ -706,7 +706,7 @@
             case ast::BuiltinValue::kSampleIndex:
                 return "gl_SampleID";
             case ast::BuiltinValue::kSampleMask:
-                if (address_space == ast::AddressSpace::kIn) {
+                if (address_space == type::AddressSpace::kIn) {
                     return "gl_SampleMaskIn";
                 } else {
                     return "gl_SampleMask";
diff --git a/src/tint/transform/clamp_frag_depth.cc b/src/tint/transform/clamp_frag_depth.cc
index 94deee5..34a4624 100644
--- a/src/tint/transform/clamp_frag_depth.cc
+++ b/src/tint/transform/clamp_frag_depth.cc
@@ -89,7 +89,7 @@
     // Abort on any use of push constants in the module.
     for (auto* global : src->AST().GlobalVariables()) {
         if (auto* var = global->As<ast::Var>()) {
-            if (TINT_UNLIKELY(var->declared_address_space == ast::AddressSpace::kPushConstant)) {
+            if (TINT_UNLIKELY(var->declared_address_space == type::AddressSpace::kPushConstant)) {
                 TINT_ICE(Transform, b.Diagnostics())
                     << "ClampFragDepth doesn't know how to handle module that already use push "
                        "constants.";
@@ -124,7 +124,7 @@
                 utils::Vector{b.Member("min", b.ty.f32()), b.Member("max", b.ty.f32())});
 
     auto args_sym = b.Symbols().New("frag_depth_clamp_args");
-    b.GlobalVar(args_sym, b.ty.type_name("FragDepthClampArgs"), ast::AddressSpace::kPushConstant);
+    b.GlobalVar(args_sym, b.ty.type_name("FragDepthClampArgs"), type::AddressSpace::kPushConstant);
 
     auto base_fn_sym = b.Symbols().New("clamp_frag_depth");
     b.Func(base_fn_sym, utils::Vector{b.Param("v", b.ty.f32())}, b.ty.f32(),
diff --git a/src/tint/transform/decompose_memory_access.cc b/src/tint/transform/decompose_memory_access.cc
index e760bd2..cbef564 100644
--- a/src/tint/transform/decompose_memory_access.cc
+++ b/src/tint/transform/decompose_memory_access.cc
@@ -50,8 +50,8 @@
 bool ShouldRun(const Program* program) {
     for (auto* decl : program->AST().GlobalDeclarations()) {
         if (auto* var = program->Sem().Get<sem::Variable>(decl)) {
-            if (var->AddressSpace() == ast::AddressSpace::kStorage ||
-                var->AddressSpace() == ast::AddressSpace::kUniform) {
+            if (var->AddressSpace() == type::AddressSpace::kStorage ||
+                var->AddressSpace() == type::AddressSpace::kUniform) {
                 return true;
             }
         }
@@ -109,8 +109,8 @@
 
 /// LoadStoreKey is the unordered map key to a load or store intrinsic.
 struct LoadStoreKey {
-    ast::AddressSpace const address_space;  // buffer address space
-    ast::Access const access;               // buffer access
+    type::AddressSpace const address_space;  // buffer address space
+    type::Access const access;               // buffer access
     type::Type const* buf_ty = nullptr;     // buffer type
     type::Type const* el_ty = nullptr;      // element type
     bool operator==(const LoadStoreKey& rhs) const {
@@ -126,7 +126,7 @@
 
 /// AtomicKey is the unordered map key to an atomic intrinsic.
 struct AtomicKey {
-    ast::Access const access;            // buffer access
+    type::Access const access;           // buffer access
     type::Type const* buf_ty = nullptr;  // buffer type
     type::Type const* el_ty = nullptr;   // element type
     sem::BuiltinType const op;           // atomic op
@@ -223,7 +223,7 @@
 /// @returns a DecomposeMemoryAccess::Intrinsic attribute that can be applied
 /// to a stub function to load the type `ty`.
 DecomposeMemoryAccess::Intrinsic* IntrinsicLoadFor(ProgramBuilder* builder,
-                                                   ast::AddressSpace address_space,
+                                                   type::AddressSpace address_space,
                                                    const type::Type* ty) {
     DecomposeMemoryAccess::Intrinsic::DataType type;
     if (!IntrinsicDataTypeFor(ty, type)) {
@@ -237,7 +237,7 @@
 /// @returns a DecomposeMemoryAccess::Intrinsic attribute that can be applied
 /// to a stub function to store the type `ty`.
 DecomposeMemoryAccess::Intrinsic* IntrinsicStoreFor(ProgramBuilder* builder,
-                                                    ast::AddressSpace address_space,
+                                                    type::AddressSpace address_space,
                                                     const type::Type* ty) {
     DecomposeMemoryAccess::Intrinsic::DataType type;
     if (!IntrinsicDataTypeFor(ty, type)) {
@@ -300,7 +300,7 @@
         return nullptr;
     }
     return builder->ASTNodes().Create<DecomposeMemoryAccess::Intrinsic>(
-        builder->ID(), builder->AllocateNodeID(), op, ast::AddressSpace::kStorage, type);
+        builder->ID(), builder->AllocateNodeID(), op, type::AddressSpace::kStorage, type);
 }
 
 /// BufferAccess describes a single storage or uniform buffer access
@@ -466,8 +466,8 @@
                     const sem::VariableUser* var_user) {
         auto address_space = var_user->Variable()->AddressSpace();
         auto access = var_user->Variable()->Access();
-        if (address_space != ast::AddressSpace::kStorage) {
-            access = ast::Access::kUndefined;
+        if (address_space != type::AddressSpace::kStorage) {
+            access = type::Access::kUndefined;
         }
         return utils::GetOrCreate(
             load_funcs, LoadStoreKey{address_space, access, buf_ty, el_ty}, [&] {
@@ -565,8 +565,8 @@
                      const sem::VariableUser* var_user) {
         auto address_space = var_user->Variable()->AddressSpace();
         auto access = var_user->Variable()->Access();
-        if (address_space != ast::AddressSpace::kStorage) {
-            access = ast::Access::kUndefined;
+        if (address_space != type::AddressSpace::kStorage) {
+            access = type::Access::kUndefined;
         }
         return utils::GetOrCreate(
             store_funcs, LoadStoreKey{address_space, access, buf_ty, el_ty}, [&] {
@@ -678,15 +678,15 @@
         auto op = intrinsic->Type();
         auto address_space = var_user->Variable()->AddressSpace();
         auto access = var_user->Variable()->Access();
-        if (address_space != ast::AddressSpace::kStorage) {
-            access = ast::Access::kUndefined;
+        if (address_space != type::AddressSpace::kStorage) {
+            access = type::Access::kUndefined;
         }
         return utils::GetOrCreate(atomic_funcs, AtomicKey{access, buf_ty, el_ty, op}, [&] {
             // The first parameter to all WGSL atomics is the expression to the
             // atomic. This is replaced with two parameters: the buffer and offset.
             utils::Vector params{
                 b.Param("buffer",
-                        b.ty.pointer(CreateASTTypeFor(ctx, buf_ty), ast::AddressSpace::kStorage,
+                        b.ty.pointer(CreateASTTypeFor(ctx, buf_ty), type::AddressSpace::kStorage,
                                      access),
                         utils::Vector{b.Disable(ast::DisabledValidation::kFunctionParameter)}),
                 b.Param("offset", b.ty.u32()),
@@ -744,7 +744,7 @@
 DecomposeMemoryAccess::Intrinsic::Intrinsic(ProgramID pid,
                                             ast::NodeID nid,
                                             Op o,
-                                            ast::AddressSpace sc,
+                                            type::AddressSpace sc,
                                             DataType ty)
     : Base(pid, nid), op(o), address_space(sc), type(ty) {}
 DecomposeMemoryAccess::Intrinsic::~Intrinsic() = default;
@@ -883,8 +883,8 @@
             // X
             if (auto* sem_ident = sem.Get(ident)) {
                 if (auto* var = sem_ident->UnwrapLoad()->As<sem::VariableUser>()) {
-                    if (var->Variable()->AddressSpace() == ast::AddressSpace::kStorage ||
-                        var->Variable()->AddressSpace() == ast::AddressSpace::kUniform) {
+                    if (var->Variable()->AddressSpace() == type::AddressSpace::kStorage ||
+                        var->Variable()->AddressSpace() == type::AddressSpace::kUniform) {
                         // Variable to a storage or uniform buffer
                         state.AddAccess(ident, {
                                                    var,
diff --git a/src/tint/transform/decompose_memory_access.h b/src/tint/transform/decompose_memory_access.h
index 3c620e0..3a51035 100644
--- a/src/tint/transform/decompose_memory_access.h
+++ b/src/tint/transform/decompose_memory_access.h
@@ -81,7 +81,7 @@
         /// @param o the op of the intrinsic
         /// @param sc the address space of the buffer
         /// @param ty the data type of the intrinsic
-        Intrinsic(ProgramID pid, ast::NodeID nid, Op o, ast::AddressSpace sc, DataType ty);
+        Intrinsic(ProgramID pid, ast::NodeID nid, Op o, type::AddressSpace sc, DataType ty);
         /// Destructor
         ~Intrinsic() override;
 
@@ -101,7 +101,7 @@
         const Op op;
 
         /// The address space of the buffer this intrinsic operates on
-        ast::AddressSpace const address_space;
+        type::AddressSpace const address_space;
 
         /// The type of the intrinsic
         const DataType type;
diff --git a/src/tint/transform/decompose_strided_array_test.cc b/src/tint/transform/decompose_strided_array_test.cc
index 96a95fc..3befa65 100644
--- a/src/tint/transform/decompose_strided_array_test.cc
+++ b/src/tint/transform/decompose_strided_array_test.cc
@@ -39,7 +39,7 @@
     // var<private> arr : array<f32, 4u>
 
     ProgramBuilder b;
-    b.GlobalVar("arr", b.ty.array<f32, 4u>(), ast::AddressSpace::kPrivate);
+    b.GlobalVar("arr", b.ty.array<f32, 4u>(), type::AddressSpace::kPrivate);
     EXPECT_FALSE(ShouldRun<DecomposeStridedArray>(Program(std::move(b))));
 }
 
@@ -47,7 +47,7 @@
     // var<private> arr : @stride(4) array<f32, 4u>
 
     ProgramBuilder b;
-    b.GlobalVar("arr", b.ty.array<f32, 4u>(4), ast::AddressSpace::kPrivate);
+    b.GlobalVar("arr", b.ty.array<f32, 4u>(4), type::AddressSpace::kPrivate);
     EXPECT_TRUE(ShouldRun<DecomposeStridedArray>(Program(std::move(b))));
 }
 
@@ -55,7 +55,7 @@
     // var<private> arr : @stride(16) array<f32, 4u>
 
     ProgramBuilder b;
-    b.GlobalVar("arr", b.ty.array<f32, 4u>(16), ast::AddressSpace::kPrivate);
+    b.GlobalVar("arr", b.ty.array<f32, 4u>(16), type::AddressSpace::kPrivate);
     EXPECT_TRUE(ShouldRun<DecomposeStridedArray>(Program(std::move(b))));
 }
 
@@ -78,7 +78,7 @@
     // }
 
     ProgramBuilder b;
-    b.GlobalVar("arr", b.ty.array<f32, 4u>(4), ast::AddressSpace::kPrivate);
+    b.GlobalVar("arr", b.ty.array<f32, 4u>(4), type::AddressSpace::kPrivate);
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Decl(b.Let("a", b.ty.array<f32, 4u>(4), b.Expr("arr"))),
@@ -114,7 +114,7 @@
     // }
 
     ProgramBuilder b;
-    b.GlobalVar("arr", b.ty.array<f32, 4u>(32), ast::AddressSpace::kPrivate);
+    b.GlobalVar("arr", b.ty.array<f32, 4u>(32), type::AddressSpace::kPrivate);
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Decl(b.Let("a", b.ty.array<f32, 4u>(32), b.Expr("arr"))),
@@ -158,7 +158,7 @@
     // }
     ProgramBuilder b;
     auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.array<f32, 4u>(32))});
-    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kUniform, b.Group(0_a), b.Binding(0_a));
+    b.GlobalVar("s", b.ty.Of(S), type::AddressSpace::kUniform, b.Group(0_a), b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Decl(b.Let("a", b.ty.array<f32, 4u>(32), b.MemberAccessor("s", "a"))),
@@ -206,7 +206,7 @@
     // }
     ProgramBuilder b;
     auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.array(b.ty.vec4<f32>(), 4_u, 16))});
-    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kUniform, b.Group(0_a), b.Binding(0_a));
+    b.GlobalVar("s", b.ty.Of(S), type::AddressSpace::kUniform, b.Group(0_a), b.Binding(0_a));
     b.Func(
         "f", utils::Empty, b.ty.void_(),
         utils::Vector{
@@ -252,7 +252,7 @@
     // }
     ProgramBuilder b;
     auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.array<f32, 4u>(32))});
-    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kStorage, b.Group(0_a), b.Binding(0_a));
+    b.GlobalVar("s", b.ty.Of(S), type::AddressSpace::kStorage, b.Group(0_a), b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Decl(b.Let("a", b.ty.array<f32, 4u>(32), b.MemberAccessor("s", "a"))),
@@ -300,7 +300,7 @@
     // }
     ProgramBuilder b;
     auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.array<f32, 4u>(4))});
-    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kStorage, b.Group(0_a), b.Binding(0_a));
+    b.GlobalVar("s", b.ty.Of(S), type::AddressSpace::kStorage, b.Group(0_a), b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Decl(b.Let("a", b.ty.array<f32, 4u>(4), b.MemberAccessor("s", "a"))),
@@ -344,8 +344,8 @@
     // }
     ProgramBuilder b;
     auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.array<f32, 4u>(32))});
-    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kStorage, ast::Access::kReadWrite, b.Group(0_a),
-                b.Binding(0_a));
+    b.GlobalVar("s", b.ty.Of(S), type::AddressSpace::kStorage, type::Access::kReadWrite,
+                b.Group(0_a), b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Assign(b.MemberAccessor("s", "a"), b.Construct(b.ty.array<f32, 4u>(32))),
@@ -398,8 +398,8 @@
     // }
     ProgramBuilder b;
     auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.array<f32, 4u>(4))});
-    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kStorage, ast::Access::kReadWrite, b.Group(0_a),
-                b.Binding(0_a));
+    b.GlobalVar("s", b.ty.Of(S), type::AddressSpace::kStorage, type::Access::kReadWrite,
+                b.Group(0_a), b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Assign(b.MemberAccessor("s", "a"), b.Construct(b.ty.array<f32, 4u>(4))),
@@ -450,8 +450,8 @@
     // }
     ProgramBuilder b;
     auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.array<f32, 4u>(32))});
-    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kStorage, ast::Access::kReadWrite, b.Group(0_a),
-                b.Binding(0_a));
+    b.GlobalVar("s", b.ty.Of(S), type::AddressSpace::kStorage, type::Access::kReadWrite,
+                b.Group(0_a), b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Decl(b.Let("a", b.AddressOf(b.MemberAccessor("s", "a")))),
@@ -511,8 +511,8 @@
     ProgramBuilder b;
     b.Alias("ARR", b.ty.array<f32, 4u>(32));
     auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.type_name("ARR"))});
-    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kStorage, ast::Access::kReadWrite, b.Group(0_a),
-                b.Binding(0_a));
+    b.GlobalVar("s", b.ty.Of(S), type::AddressSpace::kStorage, type::Access::kReadWrite,
+                b.Group(0_a), b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Decl(b.Let("a", b.ty.type_name("ARR"), b.MemberAccessor("s", "a"))),
@@ -581,8 +581,8 @@
                 b.ty.array(b.ty.type_name("ARR_A"), 3_u, 16),  //
                 4_u, 128));
     auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.type_name("ARR_B"))});
-    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kStorage, ast::Access::kReadWrite, b.Group(0_a),
-                b.Binding(0_a));
+    b.GlobalVar("s", b.ty.Of(S), type::AddressSpace::kStorage, type::Access::kReadWrite,
+                b.Group(0_a), b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Decl(b.Let("a", b.ty.type_name("ARR_B"), b.MemberAccessor("s", "a"))),
diff --git a/src/tint/transform/decompose_strided_matrix.cc b/src/tint/transform/decompose_strided_matrix.cc
index 4f2042a..15cdf62 100644
--- a/src/tint/transform/decompose_strided_matrix.cc
+++ b/src/tint/transform/decompose_strided_matrix.cc
@@ -72,8 +72,8 @@
     for (auto* node : src->ASTNodes().Objects()) {
         if (auto* str = node->As<ast::Struct>()) {
             auto* str_ty = src->Sem().Get(str);
-            if (!str_ty->UsedAs(ast::AddressSpace::kUniform) &&
-                !str_ty->UsedAs(ast::AddressSpace::kStorage)) {
+            if (!str_ty->UsedAs(type::AddressSpace::kUniform) &&
+                !str_ty->UsedAs(type::AddressSpace::kStorage)) {
                 continue;
             }
             for (auto* member : str_ty->Members()) {
diff --git a/src/tint/transform/decompose_strided_matrix_test.cc b/src/tint/transform/decompose_strided_matrix_test.cc
index e3ba4bb..e097acb 100644
--- a/src/tint/transform/decompose_strided_matrix_test.cc
+++ b/src/tint/transform/decompose_strided_matrix_test.cc
@@ -76,7 +76,7 @@
                               b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
                           }),
              });
-    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kUniform, b.Group(0_a), b.Binding(0_a));
+    b.GlobalVar("s", b.ty.Of(S), type::AddressSpace::kUniform, b.Group(0_a), b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Decl(b.Let("x", b.ty.mat2x2<f32>(), b.MemberAccessor("s", "m"))),
@@ -133,7 +133,7 @@
                               b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
                           }),
              });
-    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kUniform, b.Group(0_a), b.Binding(0_a));
+    b.GlobalVar("s", b.ty.Of(S), type::AddressSpace::kUniform, b.Group(0_a), b.Binding(0_a));
     b.Func(
         "f", utils::Empty, b.ty.void_(),
         utils::Vector{
@@ -187,7 +187,7 @@
                               b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
                           }),
              });
-    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kUniform, b.Group(0_a), b.Binding(0_a));
+    b.GlobalVar("s", b.ty.Of(S), type::AddressSpace::kUniform, b.Group(0_a), b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Decl(b.Let("x", b.ty.mat2x2<f32>(), b.MemberAccessor("s", "m"))),
@@ -241,8 +241,8 @@
                               b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
                           }),
              });
-    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kStorage, ast::Access::kReadWrite, b.Group(0_a),
-                b.Binding(0_a));
+    b.GlobalVar("s", b.ty.Of(S), type::AddressSpace::kStorage, type::Access::kReadWrite,
+                b.Group(0_a), b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Decl(b.Let("x", b.ty.mat2x2<f32>(), b.MemberAccessor("s", "m"))),
@@ -299,8 +299,8 @@
                               b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
                           }),
              });
-    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kStorage, ast::Access::kReadWrite, b.Group(0_a),
-                b.Binding(0_a));
+    b.GlobalVar("s", b.ty.Of(S), type::AddressSpace::kStorage, type::Access::kReadWrite,
+                b.Group(0_a), b.Binding(0_a));
     b.Func(
         "f", utils::Empty, b.ty.void_(),
         utils::Vector{
@@ -354,8 +354,8 @@
                               b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
                           }),
              });
-    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kStorage, ast::Access::kReadWrite, b.Group(0_a),
-                b.Binding(0_a));
+    b.GlobalVar("s", b.ty.Of(S), type::AddressSpace::kStorage, type::Access::kReadWrite,
+                b.Group(0_a), b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Assign(b.MemberAccessor("s", "m"),
@@ -413,8 +413,8 @@
                               b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
                           }),
              });
-    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kStorage, ast::Access::kReadWrite, b.Group(0_a),
-                b.Binding(0_a));
+    b.GlobalVar("s", b.ty.Of(S), type::AddressSpace::kStorage, type::Access::kReadWrite,
+                b.Group(0_a), b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Assign(b.IndexAccessor(b.MemberAccessor("s", "m"), 1_i), b.vec2<f32>(1_f, 2_f)),
@@ -473,8 +473,8 @@
                               b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
                           }),
              });
-    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kStorage, ast::Access::kReadWrite, b.Group(0_a),
-                b.Binding(0_a));
+    b.GlobalVar("s", b.ty.Of(S), type::AddressSpace::kStorage, type::Access::kReadWrite,
+                b.Group(0_a), b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Decl(b.Let("a", b.AddressOf(b.MemberAccessor("s", "m")))),
@@ -545,7 +545,7 @@
                               b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
                           }),
              });
-    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kPrivate);
+    b.GlobalVar("s", b.ty.Of(S), type::AddressSpace::kPrivate);
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Decl(b.Let("x", b.ty.mat2x2<f32>(), b.MemberAccessor("s", "m"))),
@@ -599,7 +599,7 @@
                               b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
                           }),
              });
-    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kPrivate);
+    b.GlobalVar("s", b.ty.Of(S), type::AddressSpace::kPrivate);
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Assign(b.MemberAccessor("s", "m"),
diff --git a/src/tint/transform/demote_to_helper.cc b/src/tint/transform/demote_to_helper.cc
index ab86fd9..48a76b7 100644
--- a/src/tint/transform/demote_to_helper.cc
+++ b/src/tint/transform/demote_to_helper.cc
@@ -81,7 +81,7 @@
 
     // Create a module-scope flag that indicates whether the current invocation has been discarded.
     auto flag = b.Symbols().New("tint_discarded");
-    b.GlobalVar(flag, ast::AddressSpace::kPrivate, b.Expr(false));
+    b.GlobalVar(flag, type::AddressSpace::kPrivate, b.Expr(false));
 
     // Replace all discard statements with a statement that marks the invocation as discarded.
     ctx.ReplaceAll([&](const ast::DiscardStatement*) -> const ast::Statement* {
@@ -125,12 +125,12 @@
                 // Skip writes to invocation-private address spaces.
                 auto* ref = sem.Get(assign->lhs)->Type()->As<type::Reference>();
                 switch (ref->AddressSpace()) {
-                    case ast::AddressSpace::kStorage:
+                    case type::AddressSpace::kStorage:
                         // Need to mask these.
                         break;
-                    case ast::AddressSpace::kFunction:
-                    case ast::AddressSpace::kPrivate:
-                    case ast::AddressSpace::kOut:
+                    case type::AddressSpace::kFunction:
+                    case type::AddressSpace::kPrivate:
+                    case type::AddressSpace::kOut:
                         // Skip these.
                         return;
                     default:
diff --git a/src/tint/transform/direct_variable_access.cc b/src/tint/transform/direct_variable_access.cc
index 70479be..a46b384 100644
--- a/src/tint/transform/direct_variable_access.cc
+++ b/src/tint/transform/direct_variable_access.cc
@@ -50,7 +50,7 @@
     /// function-scope variable ('function'), or pointer parameter in the source program.
     tint::sem::Variable const* variable = nullptr;
     /// The address space of the variable or pointer type.
-    tint::ast::AddressSpace address_space = tint::ast::AddressSpace::kUndefined;
+    tint::type::AddressSpace address_space = tint::type::AddressSpace::kUndefined;
 };
 
 /// Inequality operator for AccessRoot
@@ -450,7 +450,7 @@
                 Switch(
                     variable->Declaration(),
                     [&](const ast::Var*) {
-                        if (variable->AddressSpace() != ast::AddressSpace::kHandle) {
+                        if (variable->AddressSpace() != type::AddressSpace::kHandle) {
                             // Start a new access chain for the non-handle 'var' access
                             create_new_chain();
                         }
@@ -749,15 +749,15 @@
 
     /// @returns true if the address space @p address_space requires transforming given the
     /// transform's options.
-    bool AddressSpaceRequiresTransform(ast::AddressSpace address_space) const {
+    bool AddressSpaceRequiresTransform(type::AddressSpace address_space) const {
         switch (address_space) {
-            case ast::AddressSpace::kUniform:
-            case ast::AddressSpace::kStorage:
-            case ast::AddressSpace::kWorkgroup:
+            case type::AddressSpace::kUniform:
+            case type::AddressSpace::kStorage:
+            case type::AddressSpace::kWorkgroup:
                 return true;
-            case ast::AddressSpace::kPrivate:
+            case type::AddressSpace::kPrivate:
                 return opts.transform_private;
-            case ast::AddressSpace::kFunction:
+            case type::AddressSpace::kFunction:
                 return opts.transform_function;
             default:
                 return false;
@@ -1180,9 +1180,9 @@
         for (auto* param : fn->Parameters()) {
             if (auto* ptr = param->Type()->As<type::Pointer>()) {
                 switch (ptr->AddressSpace()) {
-                    case ast::AddressSpace::kUniform:
-                    case ast::AddressSpace::kStorage:
-                    case ast::AddressSpace::kWorkgroup:
+                    case type::AddressSpace::kUniform:
+                    case type::AddressSpace::kStorage:
+                    case type::AddressSpace::kWorkgroup:
                         return true;
                     default:
                         return false;
@@ -1193,8 +1193,8 @@
     }
 
     /// @returns true if the given address space is 'private' or 'function'.
-    static bool IsPrivateOrFunction(const ast::AddressSpace sc) {
-        return sc == ast::AddressSpace::kPrivate || sc == ast::AddressSpace::kFunction;
+    static bool IsPrivateOrFunction(const type::AddressSpace sc) {
+        return sc == type::AddressSpace::kPrivate || sc == type::AddressSpace::kFunction;
     }
 };
 
diff --git a/src/tint/transform/first_index_offset.cc b/src/tint/transform/first_index_offset.cc
index da1587d..2359ae9 100644
--- a/src/tint/transform/first_index_offset.cc
+++ b/src/tint/transform/first_index_offset.cc
@@ -130,7 +130,7 @@
 
         // Create a global to hold the uniform buffer
         Symbol buffer_name = b.Sym();
-        b.GlobalVar(buffer_name, b.ty.Of(struct_), ast::AddressSpace::kUniform,
+        b.GlobalVar(buffer_name, b.ty.Of(struct_), type::AddressSpace::kUniform,
                     utils::Vector{
                         b.Binding(AInt(ub_binding)),
                         b.Group(AInt(ub_group)),
diff --git a/src/tint/transform/localize_struct_array_assignment.cc b/src/tint/transform/localize_struct_array_assignment.cc
index b389b61..6ed16b3 100644
--- a/src/tint/transform/localize_struct_array_assignment.cc
+++ b/src/tint/transform/localize_struct_array_assignment.cc
@@ -60,8 +60,8 @@
                     continue;
                 }
                 auto og = GetOriginatingTypeAndAddressSpace(assign_stmt);
-                if (!(og.first->Is<sem::Struct>() && (og.second == ast::AddressSpace::kFunction ||
-                                                      og.second == ast::AddressSpace::kPrivate))) {
+                if (!(og.first->Is<sem::Struct>() && (og.second == type::AddressSpace::kFunction ||
+                                                      og.second == type::AddressSpace::kPrivate))) {
                     continue;
                 }
 
@@ -184,7 +184,7 @@
     // Returns the type and address space of the originating variable of the lhs
     // of the assignment statement.
     // See https://www.w3.org/TR/WGSL/#originating-variable-section
-    std::pair<const type::Type*, ast::AddressSpace> GetOriginatingTypeAndAddressSpace(
+    std::pair<const type::Type*, type::AddressSpace> GetOriginatingTypeAndAddressSpace(
         const ast::AssignmentStatement* assign_stmt) {
         auto* root_ident = src->Sem().Get(assign_stmt->lhs)->RootIdentifier();
         if (TINT_UNLIKELY(!root_ident)) {
@@ -206,7 +206,7 @@
                 TINT_ICE(Transform, b.Diagnostics())
                     << "Expecting to find variable of type pointer or reference on lhs "
                        "of assignment statement";
-                return std::pair<const type::Type*, ast::AddressSpace>{};
+                return std::pair<const type::Type*, type::AddressSpace>{};
             });
     }
 };
diff --git a/src/tint/transform/module_scope_var_to_entry_point_param.cc b/src/tint/transform/module_scope_var_to_entry_point_param.cc
index c54d586..71d9561 100644
--- a/src/tint/transform/module_scope_var_to_entry_point_param.cc
+++ b/src/tint/transform/module_scope_var_to_entry_point_param.cc
@@ -123,9 +123,9 @@
         // Helper to create an AST node for the store type of the variable.
         auto store_type = [&]() { return CreateASTTypeFor(ctx, ty); };
 
-        ast::AddressSpace sc = var->AddressSpace();
+        type::AddressSpace sc = var->AddressSpace();
         switch (sc) {
-            case ast::AddressSpace::kHandle: {
+            case type::AddressSpace::kHandle: {
                 // For a texture or sampler variable, redeclare it as an entry point parameter.
                 // Disable entry point parameter validation.
                 auto* disable_validation =
@@ -137,8 +137,8 @@
 
                 break;
             }
-            case ast::AddressSpace::kStorage:
-            case ast::AddressSpace::kUniform: {
+            case type::AddressSpace::kStorage:
+            case type::AddressSpace::kUniform: {
                 // Variables into the Storage and Uniform address spaces are redeclared as entry
                 // point parameters with a pointer type.
                 auto attributes = ctx.Clone(var->Declaration()->attributes);
@@ -167,7 +167,7 @@
 
                 break;
             }
-            case ast::AddressSpace::kWorkgroup: {
+            case type::AddressSpace::kWorkgroup: {
                 if (ContainsMatrix(var->Type())) {
                     // Due to a bug in the MSL compiler, we use a threadgroup memory argument for
                     // any workgroup allocation that contains a matrix. See crbug.com/tint/938.
@@ -183,7 +183,7 @@
                         ctx.dst->MemberAccessor(ctx.dst->Deref(workgroup_param()), member));
                     auto* local_var = ctx.dst->Let(
                         new_var_symbol,
-                        ctx.dst->ty.pointer(store_type(), ast::AddressSpace::kWorkgroup),
+                        ctx.dst->ty.pointer(store_type(), type::AddressSpace::kWorkgroup),
                         member_ptr);
                     ctx.InsertFront(func->body->statements, ctx.dst->Decl(local_var));
                     is_pointer = true;
@@ -192,7 +192,7 @@
                 }
                 [[fallthrough]];
             }
-            case ast::AddressSpace::kPrivate: {
+            case type::AddressSpace::kPrivate: {
                 // Variables in the Private and Workgroup address spaces are redeclared at function
                 // scope. Disable address space validation on this variable.
                 auto* disable_validation =
@@ -204,7 +204,7 @@
 
                 break;
             }
-            case ast::AddressSpace::kPushConstant: {
+            case type::AddressSpace::kPushConstant: {
                 ctx.dst->Diagnostics().add_error(
                     diag::System::Transform,
                     "unhandled module-scope address space (" + utils::ToString(sc) + ")");
@@ -233,13 +233,13 @@
         auto* param_type = CreateASTTypeFor(ctx, ty);
         auto sc = var->AddressSpace();
         switch (sc) {
-            case ast::AddressSpace::kPrivate:
-            case ast::AddressSpace::kStorage:
-            case ast::AddressSpace::kUniform:
-            case ast::AddressSpace::kHandle:
-            case ast::AddressSpace::kWorkgroup:
+            case type::AddressSpace::kPrivate:
+            case type::AddressSpace::kStorage:
+            case type::AddressSpace::kUniform:
+            case type::AddressSpace::kHandle:
+            case type::AddressSpace::kWorkgroup:
                 break;
-            case ast::AddressSpace::kPushConstant: {
+            case type::AddressSpace::kPushConstant: {
                 ctx.dst->Diagnostics().add_error(
                     diag::System::Transform,
                     "unhandled module-scope address space (" + utils::ToString(sc) + ")");
@@ -321,7 +321,7 @@
 
             bool needs_processing = false;
             for (auto* var : func_sem->TransitivelyReferencedGlobals()) {
-                if (var->AddressSpace() != ast::AddressSpace::kNone) {
+                if (var->AddressSpace() != type::AddressSpace::kNone) {
                     needs_processing = true;
                     break;
                 }
@@ -378,7 +378,7 @@
 
             // Process and redeclare all variables referenced by the function.
             for (auto* var : func_sem->TransitivelyReferencedGlobals()) {
-                if (var->AddressSpace() == ast::AddressSpace::kNone) {
+                if (var->AddressSpace() == type::AddressSpace::kNone) {
                     continue;
                 }
                 if (local_private_vars_.count(var)) {
@@ -396,7 +396,7 @@
 
                 // Check if this is a private variable that is only referenced by this function.
                 bool local_private = false;
-                if (var->AddressSpace() == ast::AddressSpace::kPrivate) {
+                if (var->AddressSpace() == type::AddressSpace::kPrivate) {
                     local_private = true;
                     for (auto* user : var->Users()) {
                         auto* stmt = user->Stmt();
@@ -414,7 +414,7 @@
                     auto* initializer = ctx.Clone(var->Declaration()->initializer);
                     auto* local_var = ctx.dst->Var(new_var_symbol,
                                                    CreateASTTypeFor(ctx, var->Type()->UnwrapRef()),
-                                                   ast::AddressSpace::kPrivate, initializer,
+                                                   type::AddressSpace::kPrivate, initializer,
                                                    utils::Vector{disable_validation});
                     ctx.InsertFront(func_ast->body->statements, ctx.dst->Decl(local_var));
                     local_private_vars_.insert(var);
@@ -426,7 +426,7 @@
                                                     is_wrapped);
                     } else {
                         ProcessVariableInUserFunction(func_ast, var, new_var_symbol, is_pointer);
-                        if (var->AddressSpace() == ast::AddressSpace::kWorkgroup) {
+                        if (var->AddressSpace() == type::AddressSpace::kWorkgroup) {
                             needs_pointer_aliasing = true;
                         }
                     }
@@ -451,7 +451,7 @@
                 auto* str =
                     ctx.dst->Structure(ctx.dst->Sym(), std::move(workgroup_parameter_members));
                 auto* param_type =
-                    ctx.dst->ty.pointer(ctx.dst->ty.Of(str), ast::AddressSpace::kWorkgroup);
+                    ctx.dst->ty.pointer(ctx.dst->ty.Of(str), type::AddressSpace::kWorkgroup);
                 auto* param = ctx.dst->Param(
                     workgroup_param(), param_type,
                     utils::Vector{
@@ -470,7 +470,7 @@
                 // For entry points, pass non-handle types as pointers.
                 for (auto* target_var : target_sem->TransitivelyReferencedGlobals()) {
                     auto sc = target_var->AddressSpace();
-                    if (sc == ast::AddressSpace::kNone) {
+                    if (sc == type::AddressSpace::kNone) {
                         continue;
                     }
 
@@ -501,7 +501,7 @@
         // Now remove all module-scope variables with these address spaces.
         for (auto* var_ast : ctx.src->AST().GlobalVariables()) {
             auto* var_sem = ctx.src->Sem().Get(var_ast);
-            if (var_sem->AddressSpace() != ast::AddressSpace::kNone) {
+            if (var_sem->AddressSpace() != type::AddressSpace::kNone) {
                 ctx.Remove(ctx.src->AST().GlobalDeclarations(), var_ast);
             }
         }
diff --git a/src/tint/transform/multiplanar_external_texture.cc b/src/tint/transform/multiplanar_external_texture.cc
index d81d186..28fe27b 100644
--- a/src/tint/transform/multiplanar_external_texture.cc
+++ b/src/tint/transform/multiplanar_external_texture.cc
@@ -22,6 +22,7 @@
 #include "src/tint/sem/call.h"
 #include "src/tint/sem/function.h"
 #include "src/tint/sem/variable.h"
+#include "src/tint/type/texture_dimension.h"
 
 TINT_INSTANTIATE_TYPEINFO(tint::transform::MultiplanarExternalTexture);
 TINT_INSTANTIATE_TYPEINFO(tint::transform::MultiplanarExternalTexture::NewBindingPoints);
@@ -140,11 +141,11 @@
             auto& syms = new_binding_symbols[sem_var];
             syms.plane_0 = ctx.Clone(global->symbol);
             syms.plane_1 = b.Symbols().New("ext_tex_plane_1");
-            b.GlobalVar(syms.plane_1, b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32()),
+            b.GlobalVar(syms.plane_1, b.ty.sampled_texture(type::TextureDimension::k2d, b.ty.f32()),
                         b.Group(AInt(bps.plane_1.group)), b.Binding(AInt(bps.plane_1.binding)));
             syms.params = b.Symbols().New("ext_tex_params");
             b.GlobalVar(syms.params, b.ty.type_name("ExternalTextureParams"),
-                        ast::AddressSpace::kUniform, b.Group(AInt(bps.params.group)),
+                        type::AddressSpace::kUniform, b.Group(AInt(bps.params.group)),
                         b.Binding(AInt(bps.params.binding)));
 
             // Replace the original texture_external binding with a texture_2d<f32> binding.
@@ -152,7 +153,7 @@
             const ast::Expression* cloned_initializer = ctx.Clone(global->initializer);
 
             auto* replacement =
-                b.Var(syms.plane_0, b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32()),
+                b.Var(syms.plane_0, b.ty.sampled_texture(type::TextureDimension::k2d, b.ty.f32()),
                       cloned_initializer, cloned_attributes);
             ctx.Replace(global, replacement);
         }
@@ -178,7 +179,7 @@
                     syms.plane_1 = b.Symbols().New("ext_tex_plane_1");
                     syms.params = b.Symbols().New("ext_tex_params");
                     auto tex2d_f32 = [&] {
-                        return b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32());
+                        return b.ty.sampled_texture(type::TextureDimension::k2d, b.ty.f32());
                     };
                     ctx.Replace(param, b.Param(syms.plane_0, tex2d_f32()));
                     ctx.InsertAfter(fn->params, param, b.Param(syms.plane_1, tex2d_f32()));
@@ -419,17 +420,18 @@
             texture_sample_external_sym = b.Symbols().New("textureSampleExternal");
 
             // Emit the textureSampleExternal function.
-            b.Func(
-                texture_sample_external_sym,
-                utils::Vector{
-                    b.Param("plane0", b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32())),
-                    b.Param("plane1", b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32())),
-                    b.Param("smp", b.ty.sampler(ast::SamplerKind::kSampler)),
-                    b.Param("coord", b.ty.vec2(b.ty.f32())),
-                    b.Param("params", b.ty.type_name(params_struct_sym)),
-                },
-                b.ty.vec4(b.ty.f32()),
-                buildTextureBuiltinBody(sem::BuiltinType::kTextureSampleBaseClampToEdge));
+            b.Func(texture_sample_external_sym,
+                   utils::Vector{
+                       b.Param("plane0",
+                               b.ty.sampled_texture(type::TextureDimension::k2d, b.ty.f32())),
+                       b.Param("plane1",
+                               b.ty.sampled_texture(type::TextureDimension::k2d, b.ty.f32())),
+                       b.Param("smp", b.ty.sampler(ast::SamplerKind::kSampler)),
+                       b.Param("coord", b.ty.vec2(b.ty.f32())),
+                       b.Param("params", b.ty.type_name(params_struct_sym)),
+                   },
+                   b.ty.vec4(b.ty.f32()),
+                   buildTextureBuiltinBody(sem::BuiltinType::kTextureSampleBaseClampToEdge));
         }
 
         const ast::IdentifierExpression* exp = b.Expr(texture_sample_external_sym);
@@ -467,16 +469,17 @@
             auto name = b.Symbols().New("textureLoadExternal");
 
             // Emit the textureLoadExternal() function.
-            b.Func(
-                name,
-                utils::Vector{
-                    b.Param("plane0", b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32())),
-                    b.Param("plane1", b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32())),
-                    b.Param("coord", CreateASTTypeFor(ctx, coord_ty)),
-                    b.Param("params", b.ty.type_name(params_struct_sym)),
-                },
-                b.ty.vec4(b.ty.f32()),  //
-                buildTextureBuiltinBody(sem::BuiltinType::kTextureLoad));
+            b.Func(name,
+                   utils::Vector{
+                       b.Param("plane0",
+                               b.ty.sampled_texture(type::TextureDimension::k2d, b.ty.f32())),
+                       b.Param("plane1",
+                               b.ty.sampled_texture(type::TextureDimension::k2d, b.ty.f32())),
+                       b.Param("coord", CreateASTTypeFor(ctx, coord_ty)),
+                       b.Param("params", b.ty.type_name(params_struct_sym)),
+                   },
+                   b.ty.vec4(b.ty.f32()),  //
+                   buildTextureBuiltinBody(sem::BuiltinType::kTextureLoad));
 
             return name;
         });
diff --git a/src/tint/transform/num_workgroups_from_uniform.cc b/src/tint/transform/num_workgroups_from_uniform.cc
index c8f8322..47f4ad1 100644
--- a/src/tint/transform/num_workgroups_from_uniform.cc
+++ b/src/tint/transform/num_workgroups_from_uniform.cc
@@ -159,7 +159,7 @@
             }
 
             num_workgroups_ubo =
-                b.GlobalVar(b.Sym(), b.ty.Of(num_workgroups_struct), ast::AddressSpace::kUniform,
+                b.GlobalVar(b.Sym(), b.ty.Of(num_workgroups_struct), type::AddressSpace::kUniform,
                             b.Group(AInt(group)), b.Binding(AInt(binding)));
         }
         return num_workgroups_ubo;
diff --git a/src/tint/transform/pad_structs.cc b/src/tint/transform/pad_structs.cc
index f34c796..9607851 100644
--- a/src/tint/transform/pad_structs.cc
+++ b/src/tint/transform/pad_structs.cc
@@ -80,7 +80,7 @@
             new_members.Push(b.Member(name, type));
 
             uint32_t size = ty->Size();
-            if (ty->Is<sem::Struct>() && str->UsedAs(ast::AddressSpace::kUniform)) {
+            if (ty->Is<sem::Struct>() && str->UsedAs(type::AddressSpace::kUniform)) {
                 // std140 structs should be padded out to 16 bytes.
                 size = utils::RoundUp(16u, size);
             } else if (auto* array_ty = ty->As<type::Array>()) {
@@ -93,7 +93,7 @@
 
         // Add any required padding after the last member, if it's not a runtime-sized array.
         uint32_t struct_size = str->Size();
-        if (str->UsedAs(ast::AddressSpace::kUniform)) {
+        if (str->UsedAs(type::AddressSpace::kUniform)) {
             struct_size = utils::RoundUp(16u, struct_size);
         }
         if (offset < struct_size && !has_runtime_sized_array) {
diff --git a/src/tint/transform/preserve_padding.cc b/src/tint/transform/preserve_padding.cc
index e2f7e00..0e26d27 100644
--- a/src/tint/transform/preserve_padding.cc
+++ b/src/tint/transform/preserve_padding.cc
@@ -53,7 +53,7 @@
                         // Ignore phony assignment.
                         return;
                     }
-                    if (ty->As<type::Reference>()->AddressSpace() != ast::AddressSpace::kStorage) {
+                    if (ty->As<type::Reference>()->AddressSpace() != type::AddressSpace::kStorage) {
                         // We only care about assignments that write to variables in the storage
                         // address space, as nothing else is host-visible.
                         return;
@@ -120,8 +120,8 @@
                 auto helper_name = b.Symbols().New("assign_and_preserve_padding");
                 utils::Vector<const ast::Parameter*, 2> params = {
                     b.Param(kDestParamName,
-                            b.ty.pointer(CreateASTTypeFor(ctx, ty), ast::AddressSpace::kStorage,
-                                         ast::Access::kReadWrite)),
+                            b.ty.pointer(CreateASTTypeFor(ctx, ty), type::AddressSpace::kStorage,
+                                         type::Access::kReadWrite)),
                     b.Param(kValueParamName, CreateASTTypeFor(ctx, ty)),
                 };
                 b.Func(helper_name, params, b.ty.void_(), body());
diff --git a/src/tint/transform/promote_side_effects_to_decl.cc b/src/tint/transform/promote_side_effects_to_decl.cc
index ff1c18f..d16bf8c 100644
--- a/src/tint/transform/promote_side_effects_to_decl.cc
+++ b/src/tint/transform/promote_side_effects_to_decl.cc
@@ -282,7 +282,7 @@
                             return false;
                         }
                         // Don't hoist read-only variables as they cannot receive side-effects.
-                        if (var_user->Variable()->Access() == ast::Access::kRead) {
+                        if (var_user->Variable()->Access() == type::Access::kRead) {
                             return false;
                         }
                         // Don't hoist textures / samplers as they can't be placed into a let, nor
diff --git a/src/tint/transform/robustness.cc b/src/tint/transform/robustness.cc
index 1ef19c9..1d624df 100644
--- a/src/tint/transform/robustness.cc
+++ b/src/tint/transform/robustness.cc
@@ -38,7 +38,7 @@
     /// Constructor
     /// @param program the source program
     /// @param omitted the omitted address spaces
-    State(const Program* program, std::unordered_set<ast::AddressSpace>&& omitted)
+    State(const Program* program, std::unordered_set<type::AddressSpace>&& omitted)
         : src(program), omitted_address_spaces(std::move(omitted)) {}
 
     /// Runs the transform
@@ -60,7 +60,7 @@
     CloneContext ctx = {&b, src, /* auto_clone_symbols */ true};
 
     /// Set of address spaces to not apply the transform to
-    std::unordered_set<ast::AddressSpace> omitted_address_spaces;
+    std::unordered_set<type::AddressSpace> omitted_address_spaces;
 
     /// Apply bounds clamping to array, vector and matrix indexing
     /// @param expr the array, vector or matrix index expression
@@ -294,14 +294,14 @@
         cfg = *cfg_data;
     }
 
-    std::unordered_set<ast::AddressSpace> omitted_address_spaces;
+    std::unordered_set<type::AddressSpace> omitted_address_spaces;
     for (auto sc : cfg.omitted_address_spaces) {
         switch (sc) {
             case AddressSpace::kUniform:
-                omitted_address_spaces.insert(ast::AddressSpace::kUniform);
+                omitted_address_spaces.insert(type::AddressSpace::kUniform);
                 break;
             case AddressSpace::kStorage:
-                omitted_address_spaces.insert(ast::AddressSpace::kStorage);
+                omitted_address_spaces.insert(type::AddressSpace::kStorage);
                 break;
         }
     }
diff --git a/src/tint/transform/std140.cc b/src/tint/transform/std140.cc
index d8f1610..b1be603 100644
--- a/src/tint/transform/std140.cc
+++ b/src/tint/transform/std140.cc
@@ -144,7 +144,7 @@
         // Scan structures for members that need forking
         for (auto* ty : src->Types()) {
             if (auto* str = ty->As<sem::Struct>()) {
-                if (str->UsedAs(ast::AddressSpace::kUniform)) {
+                if (str->UsedAs(type::AddressSpace::kUniform)) {
                     for (auto* member : str->Members()) {
                         if (needs_fork(member->Type())) {
                             return true;
@@ -157,7 +157,7 @@
         // Scan uniform variables that have types that need forking
         for (auto* decl : src->AST().GlobalVariables()) {
             auto* global = src->Sem().Get(decl);
-            if (global->AddressSpace() == ast::AddressSpace::kUniform) {
+            if (global->AddressSpace() == type::AddressSpace::kUniform) {
                 if (needs_fork(global->Type()->UnwrapRef())) {
                     return true;
                 }
@@ -280,7 +280,7 @@
         for (auto* global : src->Sem().Module()->DependencyOrderedDeclarations()) {
             // Check to see if this is a structure used by a uniform buffer...
             auto* str = sem.Get<sem::Struct>(global);
-            if (str && str->UsedAs(ast::AddressSpace::kUniform)) {
+            if (str && str->UsedAs(type::AddressSpace::kUniform)) {
                 // Should this uniform buffer be forked for std140 usage?
                 bool fork_std140 = false;
                 utils::Vector<const ast::StructMember*, 8> members;
@@ -350,7 +350,7 @@
     void ReplaceUniformVarTypes() {
         for (auto* global : src->AST().GlobalVariables()) {
             if (auto* var = global->As<ast::Var>()) {
-                if (var->declared_address_space == ast::AddressSpace::kUniform) {
+                if (var->declared_address_space == type::AddressSpace::kUniform) {
                     auto* v = sem.Get(var);
                     if (auto* std140_ty = Std140Type(v->Type()->UnwrapRef())) {
                         ctx.Replace(global->type, std140_ty);
diff --git a/src/tint/transform/texture_1d_to_2d.cc b/src/tint/transform/texture_1d_to_2d.cc
index 85cd512..4de6188 100644
--- a/src/tint/transform/texture_1d_to_2d.cc
+++ b/src/tint/transform/texture_1d_to_2d.cc
@@ -19,6 +19,7 @@
 #include "src/tint/program_builder.h"
 #include "src/tint/sem/function.h"
 #include "src/tint/sem/statement.h"
+#include "src/tint/type/texture_dimension.h"
 
 TINT_INSTANTIATE_TYPEINFO(tint::transform::Texture1DTo2D);
 
@@ -36,7 +37,7 @@
                 auto texture = signature.Parameter(sem::ParameterUsage::kTexture);
                 if (texture) {
                     auto* tex = texture->Type()->As<type::Texture>();
-                    if (tex->dim() == ast::TextureDimension::k1d) {
+                    if (tex->dim() == type::TextureDimension::k1d) {
                         return true;
                     }
                 }
@@ -47,10 +48,10 @@
         if (Switch(
                 program->Sem().Get(var->type),
                 [&](const type::SampledTexture* tex) {
-                    return tex->dim() == ast::TextureDimension::k1d;
+                    return tex->dim() == type::TextureDimension::k1d;
                 },
                 [&](const type::StorageTexture* storage_tex) {
-                    return storage_tex->dim() == ast::TextureDimension::k1d;
+                    return storage_tex->dim() == type::TextureDimension::k1d;
                 })) {
             return true;
         }
@@ -94,18 +95,18 @@
             const ast::Variable* r = Switch(
                 sem.Get(v->type),
                 [&](const type::SampledTexture* tex) -> const ast::Variable* {
-                    if (tex->dim() == ast::TextureDimension::k1d) {
+                    if (tex->dim() == type::TextureDimension::k1d) {
                         auto* type = ctx.dst->create<ast::SampledTexture>(
-                            ast::TextureDimension::k2d, CreateASTTypeFor(ctx, tex->type()));
+                            type::TextureDimension::k2d, CreateASTTypeFor(ctx, tex->type()));
                         return create_var(v, type);
                     } else {
                         return nullptr;
                     }
                 },
                 [&](const type::StorageTexture* storage_tex) -> const ast::Variable* {
-                    if (storage_tex->dim() == ast::TextureDimension::k1d) {
+                    if (storage_tex->dim() == type::TextureDimension::k1d) {
                         auto* type = ctx.dst->create<ast::StorageTexture>(
-                            ast::TextureDimension::k2d, storage_tex->texel_format(),
+                            type::TextureDimension::k2d, storage_tex->texel_format(),
                             CreateASTTypeFor(ctx, storage_tex->type()), storage_tex->access());
                         return create_var(v, type);
                     } else {
@@ -131,7 +132,7 @@
                 return nullptr;
             }
             auto* tex = texture->Type()->As<type::Texture>();
-            if (tex->dim() != ast::TextureDimension::k1d) {
+            if (tex->dim() != type::TextureDimension::k1d) {
                 return nullptr;
             }
 
diff --git a/src/tint/transform/vertex_pulling.cc b/src/tint/transform/vertex_pulling.cc
index 42dbbe3..60b02a6 100644
--- a/src/tint/transform/vertex_pulling.cc
+++ b/src/tint/transform/vertex_pulling.cc
@@ -321,8 +321,8 @@
                                         });
         for (uint32_t i = 0; i < cfg.vertex_state.size(); ++i) {
             // The decorated variable with struct type
-            b.GlobalVar(GetVertexBufferName(i), b.ty.Of(struct_type), ast::AddressSpace::kStorage,
-                        ast::Access::kRead, b.Binding(AInt(i)), b.Group(AInt(cfg.pulling_group)));
+            b.GlobalVar(GetVertexBufferName(i), b.ty.Of(struct_type), type::AddressSpace::kStorage,
+                        type::Access::kRead, b.Binding(AInt(i)), b.Group(AInt(cfg.pulling_group)));
         }
     }
 
diff --git a/src/tint/transform/zero_init_workgroup_memory.cc b/src/tint/transform/zero_init_workgroup_memory.cc
index c33834a..61d7a4b 100644
--- a/src/tint/transform/zero_init_workgroup_memory.cc
+++ b/src/tint/transform/zero_init_workgroup_memory.cc
@@ -36,7 +36,7 @@
 bool ShouldRun(const Program* program) {
     for (auto* global : program->AST().GlobalVariables()) {
         if (auto* var = global->As<ast::Var>()) {
-            if (var->declared_address_space == ast::AddressSpace::kWorkgroup) {
+            if (var->declared_address_space == type::AddressSpace::kWorkgroup) {
                 return true;
             }
         }
@@ -139,7 +139,7 @@
         // workgroup storage variables used by `fn`. This will populate #statements.
         auto* func = sem.Get(fn);
         for (auto* var : func->TransitivelyReferencedGlobals()) {
-            if (var->AddressSpace() == ast::AddressSpace::kWorkgroup) {
+            if (var->AddressSpace() == type::AddressSpace::kWorkgroup) {
                 auto get_expr = [&](uint32_t num_values) {
                     auto var_name = ctx.Clone(var->Declaration()->symbol);
                     return Expression{b.Expr(var_name), num_values, ArrayIndices{}};
diff --git a/src/tint/ast/access.cc b/src/tint/type/access.cc
similarity index 93%
rename from src/tint/ast/access.cc
rename to src/tint/type/access.cc
index 7ca9b52..04ccd9d 100644
--- a/src/tint/ast/access.cc
+++ b/src/tint/type/access.cc
@@ -15,14 +15,14 @@
 ////////////////////////////////////////////////////////////////////////////////
 // File generated by tools/src/cmd/gen
 // using the template:
-//   src/tint/ast/access.cc.tmpl
+//   src/tint/type/access.cc.tmpl
 //
 // Do not modify this file directly
 ////////////////////////////////////////////////////////////////////////////////
 
-#include "src/tint/ast/access.h"
+#include "src/tint/type/access.h"
 
-namespace tint::ast {
+namespace tint::type {
 
 /// ParseAccess parses a Access from a string.
 /// @param str the string to parse
@@ -54,4 +54,4 @@
     return out << "<unknown>";
 }
 
-}  // namespace tint::ast
+}  // namespace tint::type
diff --git a/src/tint/ast/access.cc.tmpl b/src/tint/type/access.cc.tmpl
similarity index 87%
rename from src/tint/ast/access.cc.tmpl
rename to src/tint/type/access.cc.tmpl
index bd52a3b..b34ff61 100644
--- a/src/tint/ast/access.cc.tmpl
+++ b/src/tint/type/access.cc.tmpl
@@ -14,12 +14,12 @@
 {{- Import "src/tint/templates/enums.tmpl.inc" -}}
 {{- $enum := (Sem.Enum "access") -}}
 
-#include "src/tint/ast/access.h"
+#include "src/tint/type/access.h"
 
-namespace tint::ast {
+namespace tint::type {
 
 {{ Eval "ParseEnum" $enum}}
 
 {{ Eval "EnumOStream" $enum}}
 
-}  // namespace tint::ast
+}  // namespace tint::type
diff --git a/src/tint/ast/access.h b/src/tint/type/access.h
similarity index 88%
rename from src/tint/ast/access.h
rename to src/tint/type/access.h
index e213691..26f24f6 100644
--- a/src/tint/ast/access.h
+++ b/src/tint/type/access.h
@@ -15,17 +15,17 @@
 ////////////////////////////////////////////////////////////////////////////////
 // File generated by tools/src/cmd/gen
 // using the template:
-//   src/tint/ast/access.h.tmpl
+//   src/tint/type/access.h.tmpl
 //
 // Do not modify this file directly
 ////////////////////////////////////////////////////////////////////////////////
 
-#ifndef SRC_TINT_AST_ACCESS_H_
-#define SRC_TINT_AST_ACCESS_H_
+#ifndef SRC_TINT_TYPE_ACCESS_H_
+#define SRC_TINT_TYPE_ACCESS_H_
 
 #include <ostream>
 
-namespace tint::ast {
+namespace tint::type {
 
 /// Address space of a given pointer.
 enum class Access {
@@ -51,6 +51,6 @@
     "write",
 };
 
-}  // namespace tint::ast
+}  // namespace tint::type
 
-#endif  // SRC_TINT_AST_ACCESS_H_
+#endif  // SRC_TINT_TYPE_ACCESS_H_
diff --git a/src/tint/ast/access.h.tmpl b/src/tint/type/access.h.tmpl
similarity index 80%
rename from src/tint/ast/access.h.tmpl
rename to src/tint/type/access.h.tmpl
index ab14fcf..6d353e5 100644
--- a/src/tint/ast/access.h.tmpl
+++ b/src/tint/type/access.h.tmpl
@@ -14,16 +14,16 @@
 {{- Import "src/tint/templates/enums.tmpl.inc" -}}
 {{- $enum := (Sem.Enum "access") -}}
 
-#ifndef SRC_TINT_AST_ACCESS_H_
-#define SRC_TINT_AST_ACCESS_H_
+#ifndef SRC_TINT_TYPE_ACCESS_H_
+#define SRC_TINT_TYPE_ACCESS_H_
 
 #include <ostream>
 
-namespace tint::ast {
+namespace tint::type {
 
 /// Address space of a given pointer.
 {{ Eval "DeclareEnum" $enum}}
 
-}  // namespace tint::ast
+}  // namespace tint::type
 
-#endif  // SRC_TINT_AST_ACCESS_H_
+#endif  // SRC_TINT_TYPE_ACCESS_H_
diff --git a/src/tint/ast/access_bench.cc b/src/tint/type/access_bench.cc
similarity index 92%
rename from src/tint/ast/access_bench.cc
rename to src/tint/type/access_bench.cc
index 46b4f93..6b16317 100644
--- a/src/tint/ast/access_bench.cc
+++ b/src/tint/type/access_bench.cc
@@ -15,18 +15,18 @@
 ////////////////////////////////////////////////////////////////////////////////
 // File generated by tools/src/cmd/gen
 // using the template:
-//   src/tint/ast/access_bench.cc.tmpl
+//   src/tint/type/access_bench.cc.tmpl
 //
 // Do not modify this file directly
 ////////////////////////////////////////////////////////////////////////////////
 
-#include "src/tint/ast/access.h"
+#include "src/tint/type/access.h"
 
 #include <array>
 
 #include "benchmark/benchmark.h"
 
-namespace tint::ast {
+namespace tint::type {
 namespace {
 
 void AccessParser(::benchmark::State& state) {
@@ -48,4 +48,4 @@
 BENCHMARK(AccessParser);
 
 }  // namespace
-}  // namespace tint::ast
+}  // namespace tint::type
diff --git a/src/tint/ast/access_bench.cc.tmpl b/src/tint/type/access_bench.cc.tmpl
similarity index 88%
rename from src/tint/ast/access_bench.cc.tmpl
rename to src/tint/type/access_bench.cc.tmpl
index e4ef341..420f486 100644
--- a/src/tint/ast/access_bench.cc.tmpl
+++ b/src/tint/type/access_bench.cc.tmpl
@@ -14,16 +14,16 @@
 {{- Import "src/tint/templates/enums.tmpl.inc" -}}
 {{- $enum := (Sem.Enum "access") -}}
 
-#include "src/tint/ast/access.h"
+#include "src/tint/type/access.h"
 
 #include <array>
 
 #include "benchmark/benchmark.h"
 
-namespace tint::ast {
+namespace tint::type {
 namespace {
 
 {{ Eval "BenchmarkParseEnum" $enum }}
 
 }  // namespace
-}  // namespace tint::ast
+}  // namespace tint::type
diff --git a/src/tint/ast/access_test.cc b/src/tint/type/access_test.cc
similarity index 93%
rename from src/tint/ast/access_test.cc
rename to src/tint/type/access_test.cc
index 017915d..77968ef 100644
--- a/src/tint/ast/access_test.cc
+++ b/src/tint/type/access_test.cc
@@ -15,19 +15,19 @@
 ////////////////////////////////////////////////////////////////////////////////
 // File generated by tools/src/cmd/gen
 // using the template:
-//   src/tint/ast/access_test.cc.tmpl
+//   src/tint/type/access_test.cc.tmpl
 //
 // Do not modify this file directly
 ////////////////////////////////////////////////////////////////////////////////
 
-#include "src/tint/ast/access.h"
+#include "src/tint/type/access.h"
 
 #include <string>
 
-#include "src/tint/ast/test_helper.h"
+#include "src/tint/type/test_helper.h"
 #include "src/tint/utils/string.h"
 
-namespace tint::ast {
+namespace tint::type {
 namespace {
 
 namespace parse_print_tests {
@@ -79,4 +79,4 @@
 }  // namespace parse_print_tests
 
 }  // namespace
-}  // namespace tint::ast
+}  // namespace tint::type
diff --git a/src/tint/ast/access_test.cc.tmpl b/src/tint/type/access_test.cc.tmpl
similarity index 84%
rename from src/tint/ast/access_test.cc.tmpl
rename to src/tint/type/access_test.cc.tmpl
index 9b4b71a..dd6ed44 100644
--- a/src/tint/ast/access_test.cc.tmpl
+++ b/src/tint/type/access_test.cc.tmpl
@@ -14,17 +14,17 @@
 {{- Import "src/tint/templates/enums.tmpl.inc" -}}
 {{- $enum := (Sem.Enum "access") -}}
 
-#include "src/tint/ast/access.h"
+#include "src/tint/type/access.h"
 
 #include <string>
 
-#include "src/tint/ast/test_helper.h"
+#include "src/tint/type/test_helper.h"
 #include "src/tint/utils/string.h"
 
-namespace tint::ast {
+namespace tint::type {
 namespace {
 
 {{ Eval "TestParsePrintEnum" $enum}}
 
 }  // namespace
-}  // namespace tint::ast
+}  // namespace tint::type
diff --git a/src/tint/ast/address_space.cc b/src/tint/type/address_space.cc
similarity index 94%
rename from src/tint/ast/address_space.cc
rename to src/tint/type/address_space.cc
index 260f86b..c8d9e82 100644
--- a/src/tint/ast/address_space.cc
+++ b/src/tint/type/address_space.cc
@@ -15,14 +15,14 @@
 ////////////////////////////////////////////////////////////////////////////////
 // File generated by tools/src/cmd/gen
 // using the template:
-//   src/tint/ast/address_space.cc.tmpl
+//   src/tint/type/address_space.cc.tmpl
 //
 // Do not modify this file directly
 ////////////////////////////////////////////////////////////////////////////////
 
-#include "src/tint/ast/address_space.h"
+#include "src/tint/type/address_space.h"
 
-namespace tint::ast {
+namespace tint::type {
 
 /// ParseAddressSpace parses a AddressSpace from a string.
 /// @param str the string to parse
@@ -77,4 +77,4 @@
     return out << "<unknown>";
 }
 
-}  // namespace tint::ast
+}  // namespace tint::type
diff --git a/src/tint/ast/address_space.cc.tmpl b/src/tint/type/address_space.cc.tmpl
similarity index 86%
rename from src/tint/ast/address_space.cc.tmpl
rename to src/tint/type/address_space.cc.tmpl
index 7295f14..f9036b7 100644
--- a/src/tint/ast/address_space.cc.tmpl
+++ b/src/tint/type/address_space.cc.tmpl
@@ -14,12 +14,12 @@
 {{- Import "src/tint/templates/enums.tmpl.inc" -}}
 {{- $enum := (Sem.Enum "address_space") -}}
 
-#include "src/tint/ast/address_space.h"
+#include "src/tint/type/address_space.h"
 
-namespace tint::ast {
+namespace tint::type {
 
 {{ Eval "ParseEnum" $enum}}
 
 {{ Eval "EnumOStream" $enum}}
 
-}  // namespace tint::ast
+}  // namespace tint::type
diff --git a/src/tint/ast/address_space.h b/src/tint/type/address_space.h
similarity index 84%
rename from src/tint/ast/address_space.h
rename to src/tint/type/address_space.h
index d599975..9b70ea5 100644
--- a/src/tint/ast/address_space.h
+++ b/src/tint/type/address_space.h
@@ -15,17 +15,17 @@
 ////////////////////////////////////////////////////////////////////////////////
 // File generated by tools/src/cmd/gen
 // using the template:
-//   src/tint/ast/address_space.h.tmpl
+//   src/tint/type/address_space.h.tmpl
 //
 // Do not modify this file directly
 ////////////////////////////////////////////////////////////////////////////////
 
-#ifndef SRC_TINT_AST_ADDRESS_SPACE_H_
-#define SRC_TINT_AST_ADDRESS_SPACE_H_
+#ifndef SRC_TINT_TYPE_ADDRESS_SPACE_H_
+#define SRC_TINT_TYPE_ADDRESS_SPACE_H_
 
 #include <ostream>
 
-namespace tint::ast {
+namespace tint::type {
 
 /// Address space of a given pointer.
 enum class AddressSpace {
@@ -60,11 +60,10 @@
 /// @param address_space the AddressSpace
 /// @see https://gpuweb.github.io/gpuweb/wgsl.html#host-shareable
 inline bool IsHostShareable(AddressSpace address_space) {
-    return address_space == ast::AddressSpace::kUniform ||
-           address_space == ast::AddressSpace::kStorage ||
-           address_space == ast::AddressSpace::kPushConstant;
+    return address_space == AddressSpace::kUniform || address_space == AddressSpace::kStorage ||
+           address_space == AddressSpace::kPushConstant;
 }
 
-}  // namespace tint::ast
+}  // namespace tint::type
 
-#endif  // SRC_TINT_AST_ADDRESS_SPACE_H_
+#endif  // SRC_TINT_TYPE_ADDRESS_SPACE_H_
diff --git a/src/tint/ast/address_space.h.tmpl b/src/tint/type/address_space.h.tmpl
similarity index 71%
rename from src/tint/ast/address_space.h.tmpl
rename to src/tint/type/address_space.h.tmpl
index 0726ef3..70e308a 100644
--- a/src/tint/ast/address_space.h.tmpl
+++ b/src/tint/type/address_space.h.tmpl
@@ -14,12 +14,12 @@
 {{- Import "src/tint/templates/enums.tmpl.inc" -}}
 {{- $enum := (Sem.Enum "address_space") -}}
 
-#ifndef SRC_TINT_AST_ADDRESS_SPACE_H_
-#define SRC_TINT_AST_ADDRESS_SPACE_H_
+#ifndef SRC_TINT_TYPE_ADDRESS_SPACE_H_
+#define SRC_TINT_TYPE_ADDRESS_SPACE_H_
 
 #include <ostream>
 
-namespace tint::ast {
+namespace tint::type {
 
 /// Address space of a given pointer.
 {{ Eval "DeclareEnum" $enum}}
@@ -28,10 +28,11 @@
 /// @param address_space the AddressSpace
 /// @see https://gpuweb.github.io/gpuweb/wgsl.html#host-shareable
 inline bool IsHostShareable(AddressSpace address_space) {
-    return address_space == ast::AddressSpace::kUniform || address_space == ast::AddressSpace::kStorage ||
-           address_space == ast::AddressSpace::kPushConstant;
+    return address_space == AddressSpace::kUniform ||
+           address_space == AddressSpace::kStorage ||
+           address_space == AddressSpace::kPushConstant;
 }
 
-}  // namespace tint::ast
+}  // namespace tint::type
 
-#endif  // SRC_TINT_AST_ADDRESS_SPACE_H_
+#endif  // SRC_TINT_TYPE_ADDRESS_SPACE_H_
diff --git a/src/tint/ast/address_space_bench.cc b/src/tint/type/address_space_bench.cc
similarity index 93%
rename from src/tint/ast/address_space_bench.cc
rename to src/tint/type/address_space_bench.cc
index fb3b0a5..6a6e4c8 100644
--- a/src/tint/ast/address_space_bench.cc
+++ b/src/tint/type/address_space_bench.cc
@@ -15,18 +15,18 @@
 ////////////////////////////////////////////////////////////////////////////////
 // File generated by tools/src/cmd/gen
 // using the template:
-//   src/tint/ast/address_space_bench.cc.tmpl
+//   src/tint/type/address_space_bench.cc.tmpl
 //
 // Do not modify this file directly
 ////////////////////////////////////////////////////////////////////////////////
 
-#include "src/tint/ast/address_space.h"
+#include "src/tint/type/address_space.h"
 
 #include <array>
 
 #include "benchmark/benchmark.h"
 
-namespace tint::ast {
+namespace tint::type {
 namespace {
 
 void AddressSpaceParser(::benchmark::State& state) {
@@ -52,4 +52,4 @@
 BENCHMARK(AddressSpaceParser);
 
 }  // namespace
-}  // namespace tint::ast
+}  // namespace tint::type
diff --git a/src/tint/ast/address_space_bench.cc.tmpl b/src/tint/type/address_space_bench.cc.tmpl
similarity index 87%
rename from src/tint/ast/address_space_bench.cc.tmpl
rename to src/tint/type/address_space_bench.cc.tmpl
index 4644944..554b2b2 100644
--- a/src/tint/ast/address_space_bench.cc.tmpl
+++ b/src/tint/type/address_space_bench.cc.tmpl
@@ -14,16 +14,16 @@
 {{- Import "src/tint/templates/enums.tmpl.inc" -}}
 {{- $enum := (Sem.Enum "address_space") -}}
 
-#include "src/tint/ast/address_space.h"
+#include "src/tint/type/address_space.h"
 
 #include <array>
 
 #include "benchmark/benchmark.h"
 
-namespace tint::ast {
+namespace tint::type {
 namespace {
 
 {{ Eval "BenchmarkParseEnum" $enum }}
 
 }  // namespace
-}  // namespace tint::ast
+}  // namespace tint::type
diff --git a/src/tint/ast/address_space_test.cc b/src/tint/type/address_space_test.cc
similarity index 94%
rename from src/tint/ast/address_space_test.cc
rename to src/tint/type/address_space_test.cc
index 83646be..8b2af5c 100644
--- a/src/tint/ast/address_space_test.cc
+++ b/src/tint/type/address_space_test.cc
@@ -15,19 +15,19 @@
 ////////////////////////////////////////////////////////////////////////////////
 // File generated by tools/src/cmd/gen
 // using the template:
-//   src/tint/ast/address_space_test.cc.tmpl
+//   src/tint/type/address_space_test.cc.tmpl
 //
 // Do not modify this file directly
 ////////////////////////////////////////////////////////////////////////////////
 
-#include "src/tint/ast/address_space.h"
+#include "src/tint/type/address_space.h"
 
 #include <string>
 
-#include "src/tint/ast/test_helper.h"
+#include "src/tint/type/test_helper.h"
 #include "src/tint/utils/string.h"
 
-namespace tint::ast {
+namespace tint::type {
 namespace {
 
 namespace parse_print_tests {
@@ -86,4 +86,4 @@
 }  // namespace parse_print_tests
 
 }  // namespace
-}  // namespace tint::ast
+}  // namespace tint::type
diff --git a/src/tint/ast/address_space_test.cc.tmpl b/src/tint/type/address_space_test.cc.tmpl
similarity index 83%
rename from src/tint/ast/address_space_test.cc.tmpl
rename to src/tint/type/address_space_test.cc.tmpl
index 2967f73..75f16f2 100644
--- a/src/tint/ast/address_space_test.cc.tmpl
+++ b/src/tint/type/address_space_test.cc.tmpl
@@ -14,17 +14,17 @@
 {{- Import "src/tint/templates/enums.tmpl.inc" -}}
 {{- $enum := (Sem.Enum "address_space") -}}
 
-#include "src/tint/ast/address_space.h"
+#include "src/tint/type/address_space.h"
 
 #include <string>
 
-#include "src/tint/ast/test_helper.h"
+#include "src/tint/type/test_helper.h"
 #include "src/tint/utils/string.h"
 
-namespace tint::ast {
+namespace tint::type {
 namespace {
 
 {{ Eval "TestParsePrintEnum" $enum}}
 
 }  // namespace
-}  // namespace tint::ast
+}  // namespace tint::type
diff --git a/src/tint/type/array.cc b/src/tint/type/array.cc
index 6e1d297..dedf986 100644
--- a/src/tint/type/array.cc
+++ b/src/tint/type/array.cc
@@ -16,10 +16,10 @@
 
 #include <string>
 
-#include "src/tint/ast/variable.h"
 #include "src/tint/debug.h"
 #include "src/tint/symbol_table.h"
 #include "src/tint/type/manager.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/utils/hash.h"
 
 TINT_INSTANTIATE_TYPEINFO(tint::type::Array);
diff --git a/src/tint/type/depth_multisampled_texture.cc b/src/tint/type/depth_multisampled_texture.cc
index 7e80eb1..43d30a8 100644
--- a/src/tint/type/depth_multisampled_texture.cc
+++ b/src/tint/type/depth_multisampled_texture.cc
@@ -15,6 +15,7 @@
 #include "src/tint/type/depth_multisampled_texture.h"
 
 #include "src/tint/program_builder.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/utils/hash.h"
 
 TINT_INSTANTIATE_TYPEINFO(tint::type::DepthMultisampledTexture);
@@ -22,13 +23,13 @@
 namespace tint::type {
 namespace {
 
-bool IsValidDepthDimension(ast::TextureDimension dim) {
-    return dim == ast::TextureDimension::k2d;
+bool IsValidDepthDimension(TextureDimension dim) {
+    return dim == TextureDimension::k2d;
 }
 
 }  // namespace
 
-DepthMultisampledTexture::DepthMultisampledTexture(ast::TextureDimension dim)
+DepthMultisampledTexture::DepthMultisampledTexture(TextureDimension dim)
     : Base(utils::Hash(TypeInfo::Of<DepthMultisampledTexture>().full_hashcode, dim), dim) {
     TINT_ASSERT(Type, IsValidDepthDimension(dim));
 }
diff --git a/src/tint/type/depth_multisampled_texture.h b/src/tint/type/depth_multisampled_texture.h
index d91b463..31efaeb 100644
--- a/src/tint/type/depth_multisampled_texture.h
+++ b/src/tint/type/depth_multisampled_texture.h
@@ -18,6 +18,7 @@
 #include <string>
 
 #include "src/tint/type/texture.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::type {
 
@@ -26,7 +27,7 @@
   public:
     /// Constructor
     /// @param dim the dimensionality of the texture
-    explicit DepthMultisampledTexture(ast::TextureDimension dim);
+    explicit DepthMultisampledTexture(TextureDimension dim);
 
     /// Destructor
     ~DepthMultisampledTexture() override;
diff --git a/src/tint/type/depth_multisampled_texture_test.cc b/src/tint/type/depth_multisampled_texture_test.cc
index fa94d93..c0830c6 100644
--- a/src/tint/type/depth_multisampled_texture_test.cc
+++ b/src/tint/type/depth_multisampled_texture_test.cc
@@ -18,6 +18,7 @@
 #include "src/tint/type/sampled_texture.h"
 #include "src/tint/type/storage_texture.h"
 #include "src/tint/type/test_helper.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::type {
 namespace {
@@ -25,22 +26,22 @@
 using DepthMultisampledTextureTest = TestHelper;
 
 TEST_F(DepthMultisampledTextureTest, Creation) {
-    auto* a = create<DepthMultisampledTexture>(ast::TextureDimension::k2d);
-    auto* b = create<DepthMultisampledTexture>(ast::TextureDimension::k2d);
+    auto* a = create<DepthMultisampledTexture>(TextureDimension::k2d);
+    auto* b = create<DepthMultisampledTexture>(TextureDimension::k2d);
 
     EXPECT_EQ(a, b);
 }
 
 TEST_F(DepthMultisampledTextureTest, Hash) {
-    auto* a = create<DepthMultisampledTexture>(ast::TextureDimension::k2d);
-    auto* b = create<DepthMultisampledTexture>(ast::TextureDimension::k2d);
+    auto* a = create<DepthMultisampledTexture>(TextureDimension::k2d);
+    auto* b = create<DepthMultisampledTexture>(TextureDimension::k2d);
 
     EXPECT_EQ(a->unique_hash, b->unique_hash);
 }
 
 TEST_F(DepthMultisampledTextureTest, Equals) {
-    auto* a = create<DepthMultisampledTexture>(ast::TextureDimension::k2d);
-    auto* b = create<DepthMultisampledTexture>(ast::TextureDimension::k2d);
+    auto* a = create<DepthMultisampledTexture>(TextureDimension::k2d);
+    auto* b = create<DepthMultisampledTexture>(TextureDimension::k2d);
 
     EXPECT_TRUE(a->Equals(*a));
     EXPECT_TRUE(a->Equals(*b));
@@ -48,23 +49,23 @@
 }
 
 TEST_F(DepthMultisampledTextureTest, Dim) {
-    DepthMultisampledTexture d(ast::TextureDimension::k2d);
-    EXPECT_EQ(d.dim(), ast::TextureDimension::k2d);
+    DepthMultisampledTexture d(TextureDimension::k2d);
+    EXPECT_EQ(d.dim(), TextureDimension::k2d);
 }
 
 TEST_F(DepthMultisampledTextureTest, FriendlyName) {
-    DepthMultisampledTexture d(ast::TextureDimension::k2d);
+    DepthMultisampledTexture d(TextureDimension::k2d);
     EXPECT_EQ(d.FriendlyName(Symbols()), "texture_depth_multisampled_2d");
 }
 
 TEST_F(DepthMultisampledTextureTest, Clone) {
-    auto* a = create<DepthMultisampledTexture>(ast::TextureDimension::k2d);
+    auto* a = create<DepthMultisampledTexture>(TextureDimension::k2d);
 
     type::Manager mgr;
     type::CloneContext ctx{{nullptr}, {nullptr, &mgr}};
 
     auto* dt = a->Clone(ctx);
-    EXPECT_EQ(dt->dim(), ast::TextureDimension::k2d);
+    EXPECT_EQ(dt->dim(), TextureDimension::k2d);
 }
 
 }  // namespace
diff --git a/src/tint/type/depth_texture.cc b/src/tint/type/depth_texture.cc
index 2295b39..214b407 100644
--- a/src/tint/type/depth_texture.cc
+++ b/src/tint/type/depth_texture.cc
@@ -15,6 +15,7 @@
 #include "src/tint/type/depth_texture.h"
 
 #include "src/tint/program_builder.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/utils/hash.h"
 
 TINT_INSTANTIATE_TYPEINFO(tint::type::DepthTexture);
@@ -22,14 +23,14 @@
 namespace tint::type {
 namespace {
 
-bool IsValidDepthDimension(ast::TextureDimension dim) {
-    return dim == ast::TextureDimension::k2d || dim == ast::TextureDimension::k2dArray ||
-           dim == ast::TextureDimension::kCube || dim == ast::TextureDimension::kCubeArray;
+bool IsValidDepthDimension(TextureDimension dim) {
+    return dim == TextureDimension::k2d || dim == TextureDimension::k2dArray ||
+           dim == TextureDimension::kCube || dim == TextureDimension::kCubeArray;
 }
 
 }  // namespace
 
-DepthTexture::DepthTexture(ast::TextureDimension dim)
+DepthTexture::DepthTexture(TextureDimension dim)
     : Base(utils::Hash(TypeInfo::Of<DepthTexture>().full_hashcode, dim), dim) {
     TINT_ASSERT(Type, IsValidDepthDimension(dim));
 }
diff --git a/src/tint/type/depth_texture.h b/src/tint/type/depth_texture.h
index 21cd780..70a0b73 100644
--- a/src/tint/type/depth_texture.h
+++ b/src/tint/type/depth_texture.h
@@ -18,6 +18,7 @@
 #include <string>
 
 #include "src/tint/type/texture.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::type {
 
@@ -26,7 +27,7 @@
   public:
     /// Constructor
     /// @param dim the dimensionality of the texture
-    explicit DepthTexture(ast::TextureDimension dim);
+    explicit DepthTexture(TextureDimension dim);
 
     /// Destructor
     ~DepthTexture() override;
diff --git a/src/tint/type/depth_texture_test.cc b/src/tint/type/depth_texture_test.cc
index 18dda3d..4ff970a 100644
--- a/src/tint/type/depth_texture_test.cc
+++ b/src/tint/type/depth_texture_test.cc
@@ -18,6 +18,7 @@
 #include "src/tint/type/sampled_texture.h"
 #include "src/tint/type/storage_texture.h"
 #include "src/tint/type/test_helper.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::type {
 namespace {
@@ -25,25 +26,25 @@
 using DepthTextureTest = TestHelper;
 
 TEST_F(DepthTextureTest, Creation) {
-    auto* a = create<DepthTexture>(ast::TextureDimension::k2d);
-    auto* b = create<DepthTexture>(ast::TextureDimension::k2d);
-    auto* c = create<DepthTexture>(ast::TextureDimension::k2dArray);
+    auto* a = create<DepthTexture>(TextureDimension::k2d);
+    auto* b = create<DepthTexture>(TextureDimension::k2d);
+    auto* c = create<DepthTexture>(TextureDimension::k2dArray);
 
     EXPECT_EQ(a, b);
     EXPECT_NE(a, c);
 }
 
 TEST_F(DepthTextureTest, Hash) {
-    auto* a = create<DepthTexture>(ast::TextureDimension::k2d);
-    auto* b = create<DepthTexture>(ast::TextureDimension::k2d);
+    auto* a = create<DepthTexture>(TextureDimension::k2d);
+    auto* b = create<DepthTexture>(TextureDimension::k2d);
 
     EXPECT_EQ(a->unique_hash, b->unique_hash);
 }
 
 TEST_F(DepthTextureTest, Equals) {
-    auto* a = create<DepthTexture>(ast::TextureDimension::k2d);
-    auto* b = create<DepthTexture>(ast::TextureDimension::k2d);
-    auto* c = create<DepthTexture>(ast::TextureDimension::k2dArray);
+    auto* a = create<DepthTexture>(TextureDimension::k2d);
+    auto* b = create<DepthTexture>(TextureDimension::k2d);
+    auto* c = create<DepthTexture>(TextureDimension::k2dArray);
 
     EXPECT_TRUE(a->Equals(*b));
     EXPECT_FALSE(a->Equals(*c));
@@ -51,7 +52,7 @@
 }
 
 TEST_F(DepthTextureTest, IsTexture) {
-    DepthTexture d(ast::TextureDimension::kCube);
+    DepthTexture d(TextureDimension::kCube);
     Texture* ty = &d;
     EXPECT_TRUE(ty->Is<DepthTexture>());
     EXPECT_FALSE(ty->Is<ExternalTexture>());
@@ -60,23 +61,23 @@
 }
 
 TEST_F(DepthTextureTest, Dim) {
-    DepthTexture d(ast::TextureDimension::kCube);
-    EXPECT_EQ(d.dim(), ast::TextureDimension::kCube);
+    DepthTexture d(TextureDimension::kCube);
+    EXPECT_EQ(d.dim(), TextureDimension::kCube);
 }
 
 TEST_F(DepthTextureTest, FriendlyName) {
-    DepthTexture d(ast::TextureDimension::kCube);
+    DepthTexture d(TextureDimension::kCube);
     EXPECT_EQ(d.FriendlyName(Symbols()), "texture_depth_cube");
 }
 
 TEST_F(DepthTextureTest, Clone) {
-    auto* a = create<DepthTexture>(ast::TextureDimension::k2d);
+    auto* a = create<DepthTexture>(TextureDimension::k2d);
 
     type::Manager mgr;
     type::CloneContext ctx{{nullptr}, {nullptr, &mgr}};
 
     auto* dt = a->Clone(ctx);
-    EXPECT_EQ(dt->dim(), ast::TextureDimension::k2d);
+    EXPECT_EQ(dt->dim(), TextureDimension::k2d);
 }
 
 }  // namespace
diff --git a/src/tint/type/external_texture.cc b/src/tint/type/external_texture.cc
index 77ac5ba..bfd2edc 100644
--- a/src/tint/type/external_texture.cc
+++ b/src/tint/type/external_texture.cc
@@ -15,6 +15,7 @@
 #include "src/tint/type/external_texture.h"
 
 #include "src/tint/program_builder.h"
+#include "src/tint/type/texture_dimension.h"
 
 TINT_INSTANTIATE_TYPEINFO(tint::type::ExternalTexture);
 
@@ -22,7 +23,7 @@
 
 ExternalTexture::ExternalTexture()
     : Base(static_cast<size_t>(TypeInfo::Of<ExternalTexture>().full_hashcode),
-           ast::TextureDimension::k2d) {}
+           TextureDimension::k2d) {}
 
 ExternalTexture::~ExternalTexture() = default;
 
diff --git a/src/tint/type/external_texture_test.cc b/src/tint/type/external_texture_test.cc
index e9ea95d..0752590 100644
--- a/src/tint/type/external_texture_test.cc
+++ b/src/tint/type/external_texture_test.cc
@@ -19,6 +19,7 @@
 #include "src/tint/type/sampled_texture.h"
 #include "src/tint/type/storage_texture.h"
 #include "src/tint/type/test_helper.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::type {
 namespace {
@@ -58,7 +59,7 @@
 TEST_F(ExternalTextureTest, Dim) {
     F32 f32;
     ExternalTexture s;
-    EXPECT_EQ(s.dim(), ast::TextureDimension::k2d);
+    EXPECT_EQ(s.dim(), TextureDimension::k2d);
 }
 
 TEST_F(ExternalTextureTest, FriendlyName) {
diff --git a/src/tint/type/multisampled_texture.cc b/src/tint/type/multisampled_texture.cc
index 47d3e21..801a891 100644
--- a/src/tint/type/multisampled_texture.cc
+++ b/src/tint/type/multisampled_texture.cc
@@ -15,13 +15,14 @@
 #include "src/tint/type/multisampled_texture.h"
 
 #include "src/tint/program_builder.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/utils/hash.h"
 
 TINT_INSTANTIATE_TYPEINFO(tint::type::MultisampledTexture);
 
 namespace tint::type {
 
-MultisampledTexture::MultisampledTexture(ast::TextureDimension dim, const Type* type)
+MultisampledTexture::MultisampledTexture(TextureDimension dim, const Type* type)
     : Base(utils::Hash(TypeInfo::Of<MultisampledTexture>().full_hashcode, dim, type), dim),
       type_(type) {
     TINT_ASSERT(Type, type_);
diff --git a/src/tint/type/multisampled_texture.h b/src/tint/type/multisampled_texture.h
index 3048590..c5e66d7 100644
--- a/src/tint/type/multisampled_texture.h
+++ b/src/tint/type/multisampled_texture.h
@@ -18,6 +18,7 @@
 #include <string>
 
 #include "src/tint/type/texture.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::type {
 
@@ -27,7 +28,7 @@
     /// Constructor
     /// @param dim the dimensionality of the texture
     /// @param type the data type of the multisampled texture
-    MultisampledTexture(ast::TextureDimension dim, const Type* type);
+    MultisampledTexture(TextureDimension dim, const Type* type);
 
     /// Destructor
     ~MultisampledTexture() override;
diff --git a/src/tint/type/multisampled_texture_test.cc b/src/tint/type/multisampled_texture_test.cc
index b3b671a..1a4c2b0 100644
--- a/src/tint/type/multisampled_texture_test.cc
+++ b/src/tint/type/multisampled_texture_test.cc
@@ -19,6 +19,7 @@
 #include "src/tint/type/sampled_texture.h"
 #include "src/tint/type/storage_texture.h"
 #include "src/tint/type/test_helper.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::type {
 namespace {
@@ -26,26 +27,26 @@
 using MultisampledTextureTest = TestHelper;
 
 TEST_F(MultisampledTextureTest, Creation) {
-    auto* a = create<MultisampledTexture>(ast::TextureDimension::k2d, create<F32>());
-    auto* b = create<MultisampledTexture>(ast::TextureDimension::k2d, create<F32>());
-    auto* c = create<MultisampledTexture>(ast::TextureDimension::k3d, create<F32>());
-    auto* d = create<MultisampledTexture>(ast::TextureDimension::k2d, create<I32>());
+    auto* a = create<MultisampledTexture>(TextureDimension::k2d, create<F32>());
+    auto* b = create<MultisampledTexture>(TextureDimension::k2d, create<F32>());
+    auto* c = create<MultisampledTexture>(TextureDimension::k3d, create<F32>());
+    auto* d = create<MultisampledTexture>(TextureDimension::k2d, create<I32>());
     EXPECT_EQ(a, b);
     EXPECT_NE(a, c);
     EXPECT_NE(a, d);
 }
 
 TEST_F(MultisampledTextureTest, Hash) {
-    auto* a = create<MultisampledTexture>(ast::TextureDimension::k2d, create<F32>());
-    auto* b = create<MultisampledTexture>(ast::TextureDimension::k2d, create<F32>());
+    auto* a = create<MultisampledTexture>(TextureDimension::k2d, create<F32>());
+    auto* b = create<MultisampledTexture>(TextureDimension::k2d, create<F32>());
     EXPECT_EQ(a->unique_hash, b->unique_hash);
 }
 
 TEST_F(MultisampledTextureTest, Equals) {
-    auto* a = create<MultisampledTexture>(ast::TextureDimension::k2d, create<F32>());
-    auto* b = create<MultisampledTexture>(ast::TextureDimension::k2d, create<F32>());
-    auto* c = create<MultisampledTexture>(ast::TextureDimension::k3d, create<F32>());
-    auto* d = create<MultisampledTexture>(ast::TextureDimension::k2d, create<I32>());
+    auto* a = create<MultisampledTexture>(TextureDimension::k2d, create<F32>());
+    auto* b = create<MultisampledTexture>(TextureDimension::k2d, create<F32>());
+    auto* c = create<MultisampledTexture>(TextureDimension::k3d, create<F32>());
+    auto* d = create<MultisampledTexture>(TextureDimension::k2d, create<I32>());
     EXPECT_TRUE(a->Equals(*b));
     EXPECT_FALSE(a->Equals(*c));
     EXPECT_FALSE(a->Equals(*d));
@@ -54,7 +55,7 @@
 
 TEST_F(MultisampledTextureTest, IsTexture) {
     F32 f32;
-    MultisampledTexture s(ast::TextureDimension::kCube, &f32);
+    MultisampledTexture s(TextureDimension::kCube, &f32);
     Texture* ty = &s;
     EXPECT_FALSE(ty->Is<DepthTexture>());
     EXPECT_FALSE(ty->Is<ExternalTexture>());
@@ -65,30 +66,30 @@
 
 TEST_F(MultisampledTextureTest, Dim) {
     F32 f32;
-    MultisampledTexture s(ast::TextureDimension::k3d, &f32);
-    EXPECT_EQ(s.dim(), ast::TextureDimension::k3d);
+    MultisampledTexture s(TextureDimension::k3d, &f32);
+    EXPECT_EQ(s.dim(), TextureDimension::k3d);
 }
 
 TEST_F(MultisampledTextureTest, Type) {
     F32 f32;
-    MultisampledTexture s(ast::TextureDimension::k3d, &f32);
+    MultisampledTexture s(TextureDimension::k3d, &f32);
     EXPECT_EQ(s.type(), &f32);
 }
 
 TEST_F(MultisampledTextureTest, FriendlyName) {
     F32 f32;
-    MultisampledTexture s(ast::TextureDimension::k3d, &f32);
+    MultisampledTexture s(TextureDimension::k3d, &f32);
     EXPECT_EQ(s.FriendlyName(Symbols()), "texture_multisampled_3d<f32>");
 }
 
 TEST_F(MultisampledTextureTest, Clone) {
-    auto* a = create<MultisampledTexture>(ast::TextureDimension::k2d, create<F32>());
+    auto* a = create<MultisampledTexture>(TextureDimension::k2d, create<F32>());
 
     type::Manager mgr;
     type::CloneContext ctx{{nullptr}, {nullptr, &mgr}};
 
     auto* mt = a->Clone(ctx);
-    EXPECT_EQ(mt->dim(), ast::TextureDimension::k2d);
+    EXPECT_EQ(mt->dim(), TextureDimension::k2d);
     EXPECT_TRUE(mt->type()->Is<F32>());
 }
 
diff --git a/src/tint/type/pointer.cc b/src/tint/type/pointer.cc
index 8716b92..f00f4fb 100644
--- a/src/tint/type/pointer.cc
+++ b/src/tint/type/pointer.cc
@@ -22,14 +22,14 @@
 
 namespace tint::type {
 
-Pointer::Pointer(const Type* subtype, ast::AddressSpace address_space, ast::Access access)
+Pointer::Pointer(const Type* subtype, type::AddressSpace address_space, type::Access access)
     : Base(utils::Hash(TypeInfo::Of<Pointer>().full_hashcode, address_space, subtype, access),
            type::Flags{}),
       subtype_(subtype),
       address_space_(address_space),
       access_(access) {
     TINT_ASSERT(Type, !subtype->Is<Reference>());
-    TINT_ASSERT(Type, access != ast::Access::kUndefined);
+    TINT_ASSERT(Type, access != type::Access::kUndefined);
 }
 
 bool Pointer::Equals(const UniqueNode& other) const {
@@ -43,7 +43,7 @@
 std::string Pointer::FriendlyName(const SymbolTable& symbols) const {
     std::ostringstream out;
     out << "ptr<";
-    if (address_space_ != ast::AddressSpace::kNone) {
+    if (address_space_ != AddressSpace::kNone) {
         out << address_space_ << ", ";
     }
     out << subtype_->FriendlyName(symbols) << ", " << access_;
diff --git a/src/tint/type/pointer.h b/src/tint/type/pointer.h
index 083647e..61eab76 100644
--- a/src/tint/type/pointer.h
+++ b/src/tint/type/pointer.h
@@ -17,8 +17,8 @@
 
 #include <string>
 
-#include "src/tint/ast/access.h"
-#include "src/tint/ast/address_space.h"
+#include "src/tint/type/access.h"
+#include "src/tint/type/address_space.h"
 #include "src/tint/type/type.h"
 
 namespace tint::type {
@@ -30,7 +30,7 @@
     /// @param subtype the pointee type
     /// @param address_space the address space of the pointer
     /// @param access the resolved access control of the reference
-    Pointer(const Type* subtype, ast::AddressSpace address_space, ast::Access access);
+    Pointer(const Type* subtype, type::AddressSpace address_space, type::Access access);
 
     /// Destructor
     ~Pointer() override;
@@ -43,10 +43,10 @@
     const Type* StoreType() const { return subtype_; }
 
     /// @returns the address space of the pointer
-    ast::AddressSpace AddressSpace() const { return address_space_; }
+    type::AddressSpace AddressSpace() const { return address_space_; }
 
     /// @returns the access control of the reference
-    ast::Access Access() const { return access_; }
+    type::Access Access() const { return access_; }
 
     /// @param symbols the program's symbol table
     /// @returns the name for this type that closely resembles how it would be
@@ -59,8 +59,8 @@
 
   private:
     Type const* const subtype_;
-    ast::AddressSpace const address_space_;
-    ast::Access const access_;
+    type::AddressSpace const address_space_;
+    type::Access const access_;
 };
 
 }  // namespace tint::type
diff --git a/src/tint/type/pointer_test.cc b/src/tint/type/pointer_test.cc
index 85fcab7..aa8d14e 100644
--- a/src/tint/type/pointer_test.cc
+++ b/src/tint/type/pointer_test.cc
@@ -21,15 +21,15 @@
 using PointerTest = TestHelper;
 
 TEST_F(PointerTest, Creation) {
-    auto* a = create<Pointer>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
-    auto* b = create<Pointer>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
-    auto* c = create<Pointer>(create<F32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
-    auto* d = create<Pointer>(create<I32>(), ast::AddressSpace::kPrivate, ast::Access::kReadWrite);
-    auto* e = create<Pointer>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kRead);
+    auto* a = create<Pointer>(create<I32>(), AddressSpace::kStorage, type::Access::kReadWrite);
+    auto* b = create<Pointer>(create<I32>(), AddressSpace::kStorage, type::Access::kReadWrite);
+    auto* c = create<Pointer>(create<F32>(), AddressSpace::kStorage, type::Access::kReadWrite);
+    auto* d = create<Pointer>(create<I32>(), AddressSpace::kPrivate, type::Access::kReadWrite);
+    auto* e = create<Pointer>(create<I32>(), AddressSpace::kStorage, type::Access::kRead);
 
     EXPECT_TRUE(a->StoreType()->Is<I32>());
-    EXPECT_EQ(a->AddressSpace(), ast::AddressSpace::kStorage);
-    EXPECT_EQ(a->Access(), ast::Access::kReadWrite);
+    EXPECT_EQ(a->AddressSpace(), AddressSpace::kStorage);
+    EXPECT_EQ(a->Access(), type::Access::kReadWrite);
 
     EXPECT_EQ(a, b);
     EXPECT_NE(a, c);
@@ -38,18 +38,18 @@
 }
 
 TEST_F(PointerTest, Hash) {
-    auto* a = create<Pointer>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
-    auto* b = create<Pointer>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
+    auto* a = create<Pointer>(create<I32>(), AddressSpace::kStorage, type::Access::kReadWrite);
+    auto* b = create<Pointer>(create<I32>(), AddressSpace::kStorage, type::Access::kReadWrite);
 
     EXPECT_EQ(a->unique_hash, b->unique_hash);
 }
 
 TEST_F(PointerTest, Equals) {
-    auto* a = create<Pointer>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
-    auto* b = create<Pointer>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
-    auto* c = create<Pointer>(create<F32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
-    auto* d = create<Pointer>(create<I32>(), ast::AddressSpace::kPrivate, ast::Access::kReadWrite);
-    auto* e = create<Pointer>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kRead);
+    auto* a = create<Pointer>(create<I32>(), AddressSpace::kStorage, type::Access::kReadWrite);
+    auto* b = create<Pointer>(create<I32>(), AddressSpace::kStorage, type::Access::kReadWrite);
+    auto* c = create<Pointer>(create<F32>(), AddressSpace::kStorage, type::Access::kReadWrite);
+    auto* d = create<Pointer>(create<I32>(), AddressSpace::kPrivate, type::Access::kReadWrite);
+    auto* e = create<Pointer>(create<I32>(), AddressSpace::kStorage, type::Access::kRead);
 
     EXPECT_TRUE(a->Equals(*b));
     EXPECT_FALSE(a->Equals(*c));
@@ -59,25 +59,25 @@
 }
 
 TEST_F(PointerTest, FriendlyName) {
-    auto* r = create<Pointer>(create<I32>(), ast::AddressSpace::kNone, ast::Access::kRead);
+    auto* r = create<Pointer>(create<I32>(), AddressSpace::kNone, type::Access::kRead);
     EXPECT_EQ(r->FriendlyName(Symbols()), "ptr<i32, read>");
 }
 
 TEST_F(PointerTest, FriendlyNameWithAddressSpace) {
-    auto* r = create<Pointer>(create<I32>(), ast::AddressSpace::kWorkgroup, ast::Access::kRead);
+    auto* r = create<Pointer>(create<I32>(), AddressSpace::kWorkgroup, type::Access::kRead);
     EXPECT_EQ(r->FriendlyName(Symbols()), "ptr<workgroup, i32, read>");
 }
 
 TEST_F(PointerTest, Clone) {
-    auto* a = create<Pointer>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
+    auto* a = create<Pointer>(create<I32>(), AddressSpace::kStorage, type::Access::kReadWrite);
 
     type::Manager mgr;
     type::CloneContext ctx{{nullptr}, {nullptr, &mgr}};
 
     auto* ptr = a->Clone(ctx);
     EXPECT_TRUE(ptr->StoreType()->Is<I32>());
-    EXPECT_EQ(ptr->AddressSpace(), ast::AddressSpace::kStorage);
-    EXPECT_EQ(ptr->Access(), ast::Access::kReadWrite);
+    EXPECT_EQ(ptr->AddressSpace(), AddressSpace::kStorage);
+    EXPECT_EQ(ptr->Access(), type::Access::kReadWrite);
 }
 
 }  // namespace
diff --git a/src/tint/type/reference.cc b/src/tint/type/reference.cc
index 36915fc..090d8d7 100644
--- a/src/tint/type/reference.cc
+++ b/src/tint/type/reference.cc
@@ -21,14 +21,14 @@
 
 namespace tint::type {
 
-Reference::Reference(const Type* subtype, ast::AddressSpace address_space, ast::Access access)
+Reference::Reference(const Type* subtype, type::AddressSpace address_space, type::Access access)
     : Base(utils::Hash(TypeInfo::Of<Reference>().full_hashcode, address_space, subtype, access),
            type::Flags{}),
       subtype_(subtype),
       address_space_(address_space),
       access_(access) {
     TINT_ASSERT(Type, !subtype->Is<Reference>());
-    TINT_ASSERT(Type, access != ast::Access::kUndefined);
+    TINT_ASSERT(Type, access != type::Access::kUndefined);
 }
 
 bool Reference::Equals(const UniqueNode& other) const {
@@ -42,7 +42,7 @@
 std::string Reference::FriendlyName(const SymbolTable& symbols) const {
     std::ostringstream out;
     out << "ref<";
-    if (address_space_ != ast::AddressSpace::kNone) {
+    if (address_space_ != AddressSpace::kNone) {
         out << address_space_ << ", ";
     }
     out << subtype_->FriendlyName(symbols) << ", " << access_;
diff --git a/src/tint/type/reference.h b/src/tint/type/reference.h
index d4235c1..1999880 100644
--- a/src/tint/type/reference.h
+++ b/src/tint/type/reference.h
@@ -17,8 +17,8 @@
 
 #include <string>
 
-#include "src/tint/ast/access.h"
-#include "src/tint/ast/address_space.h"
+#include "src/tint/type/access.h"
+#include "src/tint/type/address_space.h"
 #include "src/tint/type/type.h"
 
 namespace tint::type {
@@ -30,7 +30,7 @@
     /// @param subtype the pointee type
     /// @param address_space the address space of the reference
     /// @param access the resolved access control of the reference
-    Reference(const Type* subtype, ast::AddressSpace address_space, ast::Access access);
+    Reference(const Type* subtype, type::AddressSpace address_space, type::Access access);
 
     /// Destructor
     ~Reference() override;
@@ -43,10 +43,10 @@
     const Type* StoreType() const { return subtype_; }
 
     /// @returns the address space of the reference
-    ast::AddressSpace AddressSpace() const { return address_space_; }
+    type::AddressSpace AddressSpace() const { return address_space_; }
 
     /// @returns the resolved access control of the reference.
-    ast::Access Access() const { return access_; }
+    type::Access Access() const { return access_; }
 
     /// @param symbols the program's symbol table
     /// @returns the name for this type that closely resembles how it would be
@@ -59,8 +59,8 @@
 
   private:
     Type const* const subtype_;
-    ast::AddressSpace const address_space_;
-    ast::Access const access_;
+    type::AddressSpace const address_space_;
+    type::Access const access_;
 };
 
 }  // namespace tint::type
diff --git a/src/tint/type/reference_test.cc b/src/tint/type/reference_test.cc
index 93e42ad..8b3ae18 100644
--- a/src/tint/type/reference_test.cc
+++ b/src/tint/type/reference_test.cc
@@ -21,19 +21,15 @@
 using ReferenceTest = TestHelper;
 
 TEST_F(ReferenceTest, Creation) {
-    auto* a =
-        create<Reference>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
-    auto* b =
-        create<Reference>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
-    auto* c =
-        create<Reference>(create<F32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
-    auto* d =
-        create<Reference>(create<I32>(), ast::AddressSpace::kPrivate, ast::Access::kReadWrite);
-    auto* e = create<Reference>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kRead);
+    auto* a = create<Reference>(create<I32>(), AddressSpace::kStorage, type::Access::kReadWrite);
+    auto* b = create<Reference>(create<I32>(), AddressSpace::kStorage, type::Access::kReadWrite);
+    auto* c = create<Reference>(create<F32>(), AddressSpace::kStorage, type::Access::kReadWrite);
+    auto* d = create<Reference>(create<I32>(), AddressSpace::kPrivate, type::Access::kReadWrite);
+    auto* e = create<Reference>(create<I32>(), AddressSpace::kStorage, type::Access::kRead);
 
     EXPECT_TRUE(a->StoreType()->Is<I32>());
-    EXPECT_EQ(a->AddressSpace(), ast::AddressSpace::kStorage);
-    EXPECT_EQ(a->Access(), ast::Access::kReadWrite);
+    EXPECT_EQ(a->AddressSpace(), AddressSpace::kStorage);
+    EXPECT_EQ(a->Access(), type::Access::kReadWrite);
 
     EXPECT_EQ(a, b);
     EXPECT_NE(a, c);
@@ -42,24 +38,18 @@
 }
 
 TEST_F(ReferenceTest, Hash) {
-    auto* a =
-        create<Reference>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
-    auto* b =
-        create<Reference>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
+    auto* a = create<Reference>(create<I32>(), AddressSpace::kStorage, type::Access::kReadWrite);
+    auto* b = create<Reference>(create<I32>(), AddressSpace::kStorage, type::Access::kReadWrite);
 
     EXPECT_EQ(a->unique_hash, b->unique_hash);
 }
 
 TEST_F(ReferenceTest, Equals) {
-    auto* a =
-        create<Reference>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
-    auto* b =
-        create<Reference>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
-    auto* c =
-        create<Reference>(create<F32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
-    auto* d =
-        create<Reference>(create<I32>(), ast::AddressSpace::kPrivate, ast::Access::kReadWrite);
-    auto* e = create<Reference>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kRead);
+    auto* a = create<Reference>(create<I32>(), AddressSpace::kStorage, type::Access::kReadWrite);
+    auto* b = create<Reference>(create<I32>(), AddressSpace::kStorage, type::Access::kReadWrite);
+    auto* c = create<Reference>(create<F32>(), AddressSpace::kStorage, type::Access::kReadWrite);
+    auto* d = create<Reference>(create<I32>(), AddressSpace::kPrivate, type::Access::kReadWrite);
+    auto* e = create<Reference>(create<I32>(), AddressSpace::kStorage, type::Access::kRead);
 
     EXPECT_TRUE(a->Equals(*b));
     EXPECT_FALSE(a->Equals(*c));
@@ -69,26 +59,25 @@
 }
 
 TEST_F(ReferenceTest, FriendlyName) {
-    auto* r = create<Reference>(create<I32>(), ast::AddressSpace::kNone, ast::Access::kRead);
+    auto* r = create<Reference>(create<I32>(), AddressSpace::kNone, type::Access::kRead);
     EXPECT_EQ(r->FriendlyName(Symbols()), "ref<i32, read>");
 }
 
 TEST_F(ReferenceTest, FriendlyNameWithAddressSpace) {
-    auto* r = create<Reference>(create<I32>(), ast::AddressSpace::kWorkgroup, ast::Access::kRead);
+    auto* r = create<Reference>(create<I32>(), AddressSpace::kWorkgroup, type::Access::kRead);
     EXPECT_EQ(r->FriendlyName(Symbols()), "ref<workgroup, i32, read>");
 }
 
 TEST_F(ReferenceTest, Clone) {
-    auto* a =
-        create<Reference>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
+    auto* a = create<Reference>(create<I32>(), AddressSpace::kStorage, type::Access::kReadWrite);
 
     type::Manager mgr;
     type::CloneContext ctx{{nullptr}, {nullptr, &mgr}};
 
     auto* ref = a->Clone(ctx);
     EXPECT_TRUE(ref->StoreType()->Is<I32>());
-    EXPECT_EQ(ref->AddressSpace(), ast::AddressSpace::kStorage);
-    EXPECT_EQ(ref->Access(), ast::Access::kReadWrite);
+    EXPECT_EQ(ref->AddressSpace(), AddressSpace::kStorage);
+    EXPECT_EQ(ref->Access(), type::Access::kReadWrite);
 }
 
 }  // namespace
diff --git a/src/tint/type/sampled_texture.cc b/src/tint/type/sampled_texture.cc
index 7651b410..323aaa4 100644
--- a/src/tint/type/sampled_texture.cc
+++ b/src/tint/type/sampled_texture.cc
@@ -15,13 +15,14 @@
 #include "src/tint/type/sampled_texture.h"
 
 #include "src/tint/program_builder.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/utils/hash.h"
 
 TINT_INSTANTIATE_TYPEINFO(tint::type::SampledTexture);
 
 namespace tint::type {
 
-SampledTexture::SampledTexture(ast::TextureDimension dim, const Type* type)
+SampledTexture::SampledTexture(TextureDimension dim, const Type* type)
     : Base(utils::Hash(TypeInfo::Of<SampledTexture>().full_hashcode, dim, type), dim), type_(type) {
     TINT_ASSERT(Type, type_);
 }
diff --git a/src/tint/type/sampled_texture.h b/src/tint/type/sampled_texture.h
index 1f37790..1a83165 100644
--- a/src/tint/type/sampled_texture.h
+++ b/src/tint/type/sampled_texture.h
@@ -18,6 +18,7 @@
 #include <string>
 
 #include "src/tint/type/texture.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::type {
 
@@ -27,7 +28,7 @@
     /// Constructor
     /// @param dim the dimensionality of the texture
     /// @param type the data type of the sampled texture
-    SampledTexture(ast::TextureDimension dim, const Type* type);
+    SampledTexture(TextureDimension dim, const Type* type);
 
     /// Destructor
     ~SampledTexture() override;
diff --git a/src/tint/type/sampled_texture_test.cc b/src/tint/type/sampled_texture_test.cc
index 78ab2d3..2363541 100644
--- a/src/tint/type/sampled_texture_test.cc
+++ b/src/tint/type/sampled_texture_test.cc
@@ -18,6 +18,7 @@
 #include "src/tint/type/external_texture.h"
 #include "src/tint/type/storage_texture.h"
 #include "src/tint/type/test_helper.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::type {
 namespace {
@@ -25,13 +26,13 @@
 using SampledTextureTest = TestHelper;
 
 TEST_F(SampledTextureTest, Creation) {
-    auto* a = create<SampledTexture>(ast::TextureDimension::kCube, create<F32>());
-    auto* b = create<SampledTexture>(ast::TextureDimension::kCube, create<F32>());
-    auto* c = create<SampledTexture>(ast::TextureDimension::k2d, create<F32>());
-    auto* d = create<SampledTexture>(ast::TextureDimension::kCube, create<I32>());
+    auto* a = create<SampledTexture>(TextureDimension::kCube, create<F32>());
+    auto* b = create<SampledTexture>(TextureDimension::kCube, create<F32>());
+    auto* c = create<SampledTexture>(TextureDimension::k2d, create<F32>());
+    auto* d = create<SampledTexture>(TextureDimension::kCube, create<I32>());
 
     EXPECT_TRUE(a->type()->Is<F32>());
-    EXPECT_EQ(a->dim(), ast::TextureDimension::kCube);
+    EXPECT_EQ(a->dim(), TextureDimension::kCube);
 
     EXPECT_EQ(a, b);
     EXPECT_NE(a, c);
@@ -39,17 +40,17 @@
 }
 
 TEST_F(SampledTextureTest, Hash) {
-    auto* a = create<SampledTexture>(ast::TextureDimension::kCube, create<F32>());
-    auto* b = create<SampledTexture>(ast::TextureDimension::kCube, create<F32>());
+    auto* a = create<SampledTexture>(TextureDimension::kCube, create<F32>());
+    auto* b = create<SampledTexture>(TextureDimension::kCube, create<F32>());
 
     EXPECT_EQ(a->unique_hash, b->unique_hash);
 }
 
 TEST_F(SampledTextureTest, Equals) {
-    auto* a = create<SampledTexture>(ast::TextureDimension::kCube, create<F32>());
-    auto* b = create<SampledTexture>(ast::TextureDimension::kCube, create<F32>());
-    auto* c = create<SampledTexture>(ast::TextureDimension::k2d, create<F32>());
-    auto* d = create<SampledTexture>(ast::TextureDimension::kCube, create<I32>());
+    auto* a = create<SampledTexture>(TextureDimension::kCube, create<F32>());
+    auto* b = create<SampledTexture>(TextureDimension::kCube, create<F32>());
+    auto* c = create<SampledTexture>(TextureDimension::k2d, create<F32>());
+    auto* d = create<SampledTexture>(TextureDimension::kCube, create<I32>());
 
     EXPECT_TRUE(a->Equals(*b));
     EXPECT_FALSE(a->Equals(*c));
@@ -59,7 +60,7 @@
 
 TEST_F(SampledTextureTest, IsTexture) {
     F32 f32;
-    SampledTexture s(ast::TextureDimension::kCube, &f32);
+    SampledTexture s(TextureDimension::kCube, &f32);
     Texture* ty = &s;
     EXPECT_FALSE(ty->Is<DepthTexture>());
     EXPECT_FALSE(ty->Is<ExternalTexture>());
@@ -69,30 +70,30 @@
 
 TEST_F(SampledTextureTest, Dim) {
     F32 f32;
-    SampledTexture s(ast::TextureDimension::k3d, &f32);
-    EXPECT_EQ(s.dim(), ast::TextureDimension::k3d);
+    SampledTexture s(TextureDimension::k3d, &f32);
+    EXPECT_EQ(s.dim(), TextureDimension::k3d);
 }
 
 TEST_F(SampledTextureTest, Type) {
     F32 f32;
-    SampledTexture s(ast::TextureDimension::k3d, &f32);
+    SampledTexture s(TextureDimension::k3d, &f32);
     EXPECT_EQ(s.type(), &f32);
 }
 
 TEST_F(SampledTextureTest, FriendlyName) {
     F32 f32;
-    SampledTexture s(ast::TextureDimension::k3d, &f32);
+    SampledTexture s(TextureDimension::k3d, &f32);
     EXPECT_EQ(s.FriendlyName(Symbols()), "texture_3d<f32>");
 }
 
 TEST_F(SampledTextureTest, Clone) {
-    auto* a = create<SampledTexture>(ast::TextureDimension::kCube, create<F32>());
+    auto* a = create<SampledTexture>(TextureDimension::kCube, create<F32>());
 
     type::Manager mgr;
     type::CloneContext ctx{{nullptr}, {nullptr, &mgr}};
 
     auto* mt = a->Clone(ctx);
-    EXPECT_EQ(mt->dim(), ast::TextureDimension::kCube);
+    EXPECT_EQ(mt->dim(), TextureDimension::kCube);
     EXPECT_TRUE(mt->type()->Is<F32>());
 }
 
diff --git a/src/tint/type/storage_texture.cc b/src/tint/type/storage_texture.cc
index a47b094..427a063 100644
--- a/src/tint/type/storage_texture.cc
+++ b/src/tint/type/storage_texture.cc
@@ -21,9 +21,9 @@
 
 namespace tint::type {
 
-StorageTexture::StorageTexture(ast::TextureDimension dim,
-                               ast::TexelFormat format,
-                               ast::Access access,
+StorageTexture::StorageTexture(TextureDimension dim,
+                               type::TexelFormat format,
+                               type::Access access,
                                Type* subtype)
     : Base(utils::Hash(TypeInfo::Of<StorageTexture>().full_hashcode, dim, format, access), dim),
       texel_format_(format),
@@ -45,35 +45,35 @@
     return out.str();
 }
 
-Type* StorageTexture::SubtypeFor(ast::TexelFormat format, Manager& type_mgr) {
+Type* StorageTexture::SubtypeFor(type::TexelFormat format, Manager& type_mgr) {
     switch (format) {
-        case ast::TexelFormat::kR32Uint:
-        case ast::TexelFormat::kRgba8Uint:
-        case ast::TexelFormat::kRg32Uint:
-        case ast::TexelFormat::kRgba16Uint:
-        case ast::TexelFormat::kRgba32Uint: {
+        case type::TexelFormat::kR32Uint:
+        case type::TexelFormat::kRgba8Uint:
+        case type::TexelFormat::kRg32Uint:
+        case type::TexelFormat::kRgba16Uint:
+        case type::TexelFormat::kRgba32Uint: {
             return type_mgr.Get<U32>();
         }
 
-        case ast::TexelFormat::kR32Sint:
-        case ast::TexelFormat::kRgba8Sint:
-        case ast::TexelFormat::kRg32Sint:
-        case ast::TexelFormat::kRgba16Sint:
-        case ast::TexelFormat::kRgba32Sint: {
+        case type::TexelFormat::kR32Sint:
+        case type::TexelFormat::kRgba8Sint:
+        case type::TexelFormat::kRg32Sint:
+        case type::TexelFormat::kRgba16Sint:
+        case type::TexelFormat::kRgba32Sint: {
             return type_mgr.Get<I32>();
         }
 
-        case ast::TexelFormat::kBgra8Unorm:
-        case ast::TexelFormat::kRgba8Unorm:
-        case ast::TexelFormat::kRgba8Snorm:
-        case ast::TexelFormat::kR32Float:
-        case ast::TexelFormat::kRg32Float:
-        case ast::TexelFormat::kRgba16Float:
-        case ast::TexelFormat::kRgba32Float: {
+        case type::TexelFormat::kBgra8Unorm:
+        case type::TexelFormat::kRgba8Unorm:
+        case type::TexelFormat::kRgba8Snorm:
+        case type::TexelFormat::kR32Float:
+        case type::TexelFormat::kRg32Float:
+        case type::TexelFormat::kRgba16Float:
+        case type::TexelFormat::kRgba32Float: {
             return type_mgr.Get<F32>();
         }
 
-        case ast::TexelFormat::kUndefined:
+        case type::TexelFormat::kUndefined:
             break;
     }
 
diff --git a/src/tint/type/storage_texture.h b/src/tint/type/storage_texture.h
index 276e045..6e96907 100644
--- a/src/tint/type/storage_texture.h
+++ b/src/tint/type/storage_texture.h
@@ -17,9 +17,10 @@
 
 #include <string>
 
-#include "src/tint/ast/access.h"
-#include "src/tint/ast/storage_texture.h"
+#include "src/tint/type/access.h"
+#include "src/tint/type/texel_format.h"
 #include "src/tint/type/texture.h"
+#include "src/tint/type/texture_dimension.h"
 
 // Forward declarations
 namespace tint::type {
@@ -36,9 +37,9 @@
     /// @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.
-    StorageTexture(ast::TextureDimension dim,
-                   ast::TexelFormat format,
-                   ast::Access access,
+    StorageTexture(TextureDimension dim,
+                   type::TexelFormat format,
+                   type::Access access,
                    Type* subtype);
 
     /// Destructor
@@ -52,10 +53,10 @@
     Type* type() const { return subtype_; }
 
     /// @returns the texel format
-    ast::TexelFormat texel_format() const { return texel_format_; }
+    type::TexelFormat texel_format() const { return texel_format_; }
 
     /// @returns the access control
-    ast::Access access() const { return access_; }
+    type::Access access() const { return access_; }
 
     /// @param symbols the program's symbol table
     /// @returns the name for this type that closely resembles how it would be
@@ -65,15 +66,15 @@
     /// @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* SubtypeFor(ast::TexelFormat format, Manager& type_mgr);
+    static Type* SubtypeFor(type::TexelFormat format, Manager& type_mgr);
 
     /// @param ctx the clone context
     /// @returns a clone of this type
     StorageTexture* Clone(CloneContext& ctx) const override;
 
   private:
-    ast::TexelFormat const texel_format_;
-    ast::Access const access_;
+    type::TexelFormat const texel_format_;
+    type::Access const access_;
     Type* const subtype_;
 };
 
diff --git a/src/tint/type/storage_texture_test.cc b/src/tint/type/storage_texture_test.cc
index ad8a975..ad5ad6e 100644
--- a/src/tint/type/storage_texture_test.cc
+++ b/src/tint/type/storage_texture_test.cc
@@ -18,31 +18,31 @@
 #include "src/tint/type/external_texture.h"
 #include "src/tint/type/sampled_texture.h"
 #include "src/tint/type/test_helper.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::type {
 namespace {
 
 struct StorageTextureTest : public TestHelper {
-    StorageTexture* Create(ast::TextureDimension dims, ast::TexelFormat fmt, ast::Access access) {
+    StorageTexture* Create(TextureDimension dims, type::TexelFormat fmt, type::Access access) {
         auto* subtype = StorageTexture::SubtypeFor(fmt, Types());
         return create<StorageTexture>(dims, fmt, access, subtype);
     }
 };
 
 TEST_F(StorageTextureTest, Creation) {
-    auto* a = Create(ast::TextureDimension::kCube, ast::TexelFormat::kRgba32Float,
-                     ast::Access::kReadWrite);
-    auto* b = Create(ast::TextureDimension::kCube, ast::TexelFormat::kRgba32Float,
-                     ast::Access::kReadWrite);
+    auto* a =
+        Create(TextureDimension::kCube, type::TexelFormat::kRgba32Float, type::Access::kReadWrite);
+    auto* b =
+        Create(TextureDimension::kCube, type::TexelFormat::kRgba32Float, type::Access::kReadWrite);
     auto* c =
-        Create(ast::TextureDimension::k2d, ast::TexelFormat::kRgba32Float, ast::Access::kReadWrite);
+        Create(TextureDimension::k2d, type::TexelFormat::kRgba32Float, type::Access::kReadWrite);
     auto* d =
-        Create(ast::TextureDimension::kCube, ast::TexelFormat::kR32Float, ast::Access::kReadWrite);
-    auto* e =
-        Create(ast::TextureDimension::kCube, ast::TexelFormat::kRgba32Float, ast::Access::kRead);
+        Create(TextureDimension::kCube, type::TexelFormat::kR32Float, type::Access::kReadWrite);
+    auto* e = Create(TextureDimension::kCube, type::TexelFormat::kRgba32Float, type::Access::kRead);
 
     EXPECT_TRUE(a->type()->Is<F32>());
-    EXPECT_EQ(a->dim(), ast::TextureDimension::kCube);
+    EXPECT_EQ(a->dim(), TextureDimension::kCube);
 
     EXPECT_EQ(a, b);
     EXPECT_NE(a, c);
@@ -51,25 +51,24 @@
 }
 
 TEST_F(StorageTextureTest, Hash) {
-    auto* a = Create(ast::TextureDimension::kCube, ast::TexelFormat::kRgba32Float,
-                     ast::Access::kReadWrite);
-    auto* b = Create(ast::TextureDimension::kCube, ast::TexelFormat::kRgba32Float,
-                     ast::Access::kReadWrite);
+    auto* a =
+        Create(TextureDimension::kCube, type::TexelFormat::kRgba32Float, type::Access::kReadWrite);
+    auto* b =
+        Create(TextureDimension::kCube, type::TexelFormat::kRgba32Float, type::Access::kReadWrite);
 
     EXPECT_EQ(a->unique_hash, b->unique_hash);
 }
 
 TEST_F(StorageTextureTest, Equals) {
-    auto* a = Create(ast::TextureDimension::kCube, ast::TexelFormat::kRgba32Float,
-                     ast::Access::kReadWrite);
-    auto* b = Create(ast::TextureDimension::kCube, ast::TexelFormat::kRgba32Float,
-                     ast::Access::kReadWrite);
+    auto* a =
+        Create(TextureDimension::kCube, type::TexelFormat::kRgba32Float, type::Access::kReadWrite);
+    auto* b =
+        Create(TextureDimension::kCube, type::TexelFormat::kRgba32Float, type::Access::kReadWrite);
     auto* c =
-        Create(ast::TextureDimension::k2d, ast::TexelFormat::kRgba32Float, ast::Access::kReadWrite);
+        Create(TextureDimension::k2d, type::TexelFormat::kRgba32Float, type::Access::kReadWrite);
     auto* d =
-        Create(ast::TextureDimension::kCube, ast::TexelFormat::kR32Float, ast::Access::kReadWrite);
-    auto* e =
-        Create(ast::TextureDimension::kCube, ast::TexelFormat::kRgba32Float, ast::Access::kRead);
+        Create(TextureDimension::kCube, type::TexelFormat::kR32Float, type::Access::kReadWrite);
+    auto* e = Create(TextureDimension::kCube, type::TexelFormat::kRgba32Float, type::Access::kRead);
 
     EXPECT_TRUE(a->Equals(*b));
     EXPECT_FALSE(a->Equals(*c));
@@ -79,26 +78,26 @@
 }
 
 TEST_F(StorageTextureTest, Dim) {
-    auto* s = Create(ast::TextureDimension::k2dArray, ast::TexelFormat::kRgba32Float,
-                     ast::Access::kReadWrite);
-    EXPECT_EQ(s->dim(), ast::TextureDimension::k2dArray);
+    auto* s = Create(TextureDimension::k2dArray, type::TexelFormat::kRgba32Float,
+                     type::Access::kReadWrite);
+    EXPECT_EQ(s->dim(), TextureDimension::k2dArray);
 }
 
 TEST_F(StorageTextureTest, Format) {
-    auto* s = Create(ast::TextureDimension::k2dArray, ast::TexelFormat::kRgba32Float,
-                     ast::Access::kReadWrite);
-    EXPECT_EQ(s->texel_format(), ast::TexelFormat::kRgba32Float);
+    auto* s = Create(TextureDimension::k2dArray, type::TexelFormat::kRgba32Float,
+                     type::Access::kReadWrite);
+    EXPECT_EQ(s->texel_format(), type::TexelFormat::kRgba32Float);
 }
 
 TEST_F(StorageTextureTest, FriendlyName) {
-    auto* s = Create(ast::TextureDimension::k2dArray, ast::TexelFormat::kRgba32Float,
-                     ast::Access::kReadWrite);
+    auto* s = Create(TextureDimension::k2dArray, type::TexelFormat::kRgba32Float,
+                     type::Access::kReadWrite);
     EXPECT_EQ(s->FriendlyName(Symbols()), "texture_storage_2d_array<rgba32float, read_write>");
 }
 
 TEST_F(StorageTextureTest, F32) {
-    Type* s = Create(ast::TextureDimension::k2dArray, ast::TexelFormat::kRgba32Float,
-                     ast::Access::kReadWrite);
+    Type* s = Create(TextureDimension::k2dArray, type::TexelFormat::kRgba32Float,
+                     type::Access::kReadWrite);
 
     auto program = Build();
 
@@ -109,9 +108,9 @@
 }
 
 TEST_F(StorageTextureTest, U32) {
-    auto* subtype = StorageTexture::SubtypeFor(ast::TexelFormat::kRg32Uint, Types());
-    Type* s = create<StorageTexture>(ast::TextureDimension::k2dArray, ast::TexelFormat::kRg32Uint,
-                                     ast::Access::kReadWrite, subtype);
+    auto* subtype = StorageTexture::SubtypeFor(type::TexelFormat::kRg32Uint, Types());
+    Type* s = create<StorageTexture>(TextureDimension::k2dArray, type::TexelFormat::kRg32Uint,
+                                     type::Access::kReadWrite, subtype);
 
     auto program = Build();
 
@@ -122,9 +121,9 @@
 }
 
 TEST_F(StorageTextureTest, I32) {
-    auto* subtype = StorageTexture::SubtypeFor(ast::TexelFormat::kRgba32Sint, Types());
-    Type* s = create<StorageTexture>(ast::TextureDimension::k2dArray, ast::TexelFormat::kRgba32Sint,
-                                     ast::Access::kReadWrite, subtype);
+    auto* subtype = StorageTexture::SubtypeFor(type::TexelFormat::kRgba32Sint, Types());
+    Type* s = create<StorageTexture>(TextureDimension::k2dArray, type::TexelFormat::kRgba32Sint,
+                                     type::Access::kReadWrite, subtype);
 
     auto program = Build();
 
@@ -135,15 +134,15 @@
 }
 
 TEST_F(StorageTextureTest, Clone) {
-    auto* a = Create(ast::TextureDimension::kCube, ast::TexelFormat::kRgba32Float,
-                     ast::Access::kReadWrite);
+    auto* a =
+        Create(TextureDimension::kCube, type::TexelFormat::kRgba32Float, type::Access::kReadWrite);
 
     type::Manager mgr;
     type::CloneContext ctx{{nullptr}, {nullptr, &mgr}};
 
     auto* mt = a->Clone(ctx);
-    EXPECT_EQ(mt->dim(), ast::TextureDimension::kCube);
-    EXPECT_EQ(mt->texel_format(), ast::TexelFormat::kRgba32Float);
+    EXPECT_EQ(mt->dim(), TextureDimension::kCube);
+    EXPECT_EQ(mt->texel_format(), type::TexelFormat::kRgba32Float);
     EXPECT_TRUE(mt->type()->Is<F32>());
 }
 
diff --git a/src/tint/type/struct.h b/src/tint/type/struct.h
index cd545e5..e80dcc1 100644
--- a/src/tint/type/struct.h
+++ b/src/tint/type/struct.h
@@ -21,8 +21,8 @@
 #include <string>
 #include <unordered_set>
 
-#include "src/tint/ast/address_space.h"
 #include "src/tint/symbol.h"
+#include "src/tint/type/address_space.h"
 #include "src/tint/type/node.h"
 #include "src/tint/type/type.h"
 #include "src/tint/utils/vector.h"
@@ -100,22 +100,22 @@
 
     /// Adds the AddressSpace usage to the structure.
     /// @param usage the storage usage
-    void AddUsage(ast::AddressSpace usage) { address_space_usage_.emplace(usage); }
+    void AddUsage(AddressSpace usage) { address_space_usage_.emplace(usage); }
 
     /// @returns the set of address space uses of this structure
-    const std::unordered_set<ast::AddressSpace>& AddressSpaceUsage() const {
+    const std::unordered_set<AddressSpace>& AddressSpaceUsage() const {
         return address_space_usage_;
     }
 
-    /// @param usage the ast::AddressSpace usage type to query
+    /// @param usage the AddressSpace usage type to query
     /// @returns true iff this structure has been used as the given address space
-    bool UsedAs(ast::AddressSpace usage) const { return address_space_usage_.count(usage) > 0; }
+    bool UsedAs(AddressSpace usage) const { return address_space_usage_.count(usage) > 0; }
 
     /// @returns true iff this structure has been used by address space that's
     /// host-shareable.
     bool IsHostShareable() const {
         for (auto sc : address_space_usage_) {
-            if (ast::IsHostShareable(sc)) {
+            if (type::IsHostShareable(sc)) {
                 return true;
             }
         }
@@ -160,7 +160,7 @@
     const uint32_t align_;
     const uint32_t size_;
     const uint32_t size_no_padding_;
-    std::unordered_set<ast::AddressSpace> address_space_usage_;
+    std::unordered_set<AddressSpace> address_space_usage_;
     std::unordered_set<PipelineStageUsage> pipeline_stage_uses_;
     utils::Vector<const Struct*, 2> concrete_types_;
 };
diff --git a/src/tint/ast/texel_format.cc b/src/tint/type/texel_format.cc
similarity index 96%
rename from src/tint/ast/texel_format.cc
rename to src/tint/type/texel_format.cc
index c14c06c..ebf2fc0 100644
--- a/src/tint/ast/texel_format.cc
+++ b/src/tint/type/texel_format.cc
@@ -15,14 +15,14 @@
 ////////////////////////////////////////////////////////////////////////////////
 // File generated by tools/src/cmd/gen
 // using the template:
-//   src/tint/ast/texel_format.cc.tmpl
+//   src/tint/type/texel_format.cc.tmpl
 //
 // Do not modify this file directly
 ////////////////////////////////////////////////////////////////////////////////
 
-#include "src/tint/ast/texel_format.h"
+#include "src/tint/type/texel_format.h"
 
-namespace tint::ast {
+namespace tint::type {
 
 /// ParseTexelFormat parses a TexelFormat from a string.
 /// @param str the string to parse
@@ -124,4 +124,4 @@
     return out << "<unknown>";
 }
 
-}  // namespace tint::ast
+}  // namespace tint::type
diff --git a/src/tint/ast/texel_format.cc.tmpl b/src/tint/type/texel_format.cc.tmpl
similarity index 85%
rename from src/tint/ast/texel_format.cc.tmpl
rename to src/tint/type/texel_format.cc.tmpl
index cc9f769..716ff69 100644
--- a/src/tint/ast/texel_format.cc.tmpl
+++ b/src/tint/type/texel_format.cc.tmpl
@@ -11,12 +11,12 @@
 {{- Import "src/tint/templates/enums.tmpl.inc" -}}
 {{- $enum := (Sem.Enum "texel_format") -}}
 
-#include "src/tint/ast/texel_format.h"
+#include "src/tint/type/texel_format.h"
 
-namespace tint::ast {
+namespace tint::type {
 
 {{ Eval "ParseEnum" $enum}}
 
 {{ Eval "EnumOStream" $enum}}
 
-}  // namespace tint::ast
+}  // namespace tint::type
diff --git a/src/tint/ast/texel_format.h b/src/tint/type/texel_format.h
similarity index 90%
rename from src/tint/ast/texel_format.h
rename to src/tint/type/texel_format.h
index 48d05ad..a4c8e92 100644
--- a/src/tint/ast/texel_format.h
+++ b/src/tint/type/texel_format.h
@@ -15,17 +15,17 @@
 ////////////////////////////////////////////////////////////////////////////////
 // File generated by tools/src/cmd/gen
 // using the template:
-//   src/tint/ast/texel_format.h.tmpl
+//   src/tint/type/texel_format.h.tmpl
 //
 // Do not modify this file directly
 ////////////////////////////////////////////////////////////////////////////////
 
-#ifndef SRC_TINT_AST_TEXEL_FORMAT_H_
-#define SRC_TINT_AST_TEXEL_FORMAT_H_
+#ifndef SRC_TINT_TYPE_TEXEL_FORMAT_H_
+#define SRC_TINT_TYPE_TEXEL_FORMAT_H_
 
 #include <ostream>
 
-namespace tint::ast {
+namespace tint::type {
 
 /// Enumerator of texel formats
 enum class TexelFormat {
@@ -65,6 +65,6 @@
     "rgba32uint", "rgba8sint",   "rgba8snorm", "rgba8uint",  "rgba8unorm",
 };
 
-}  // namespace tint::ast
+}  // namespace tint::type
 
-#endif  // SRC_TINT_AST_TEXEL_FORMAT_H_
+#endif  // SRC_TINT_TYPE_TEXEL_FORMAT_H_
diff --git a/src/tint/ast/texel_format.h.tmpl b/src/tint/type/texel_format.h.tmpl
similarity index 77%
rename from src/tint/ast/texel_format.h.tmpl
rename to src/tint/type/texel_format.h.tmpl
index e7454a0..837c226 100644
--- a/src/tint/ast/texel_format.h.tmpl
+++ b/src/tint/type/texel_format.h.tmpl
@@ -11,16 +11,16 @@
 {{- Import "src/tint/templates/enums.tmpl.inc" -}}
 {{- $enum := (Sem.Enum "texel_format") -}}
 
-#ifndef SRC_TINT_AST_TEXEL_FORMAT_H_
-#define SRC_TINT_AST_TEXEL_FORMAT_H_
+#ifndef SRC_TINT_TYPE_TEXEL_FORMAT_H_
+#define SRC_TINT_TYPE_TEXEL_FORMAT_H_
 
 #include <ostream>
 
-namespace tint::ast {
+namespace tint::type {
 
 /// Enumerator of texel formats
 {{ Eval "DeclareEnum" $enum}}
 
-}  // namespace tint::ast
+}  // namespace tint::type
 
-#endif  // SRC_TINT_AST_TEXEL_FORMAT_H_
+#endif  // SRC_TINT_TYPE_TEXEL_FORMAT_H_
diff --git a/src/tint/ast/texel_format_bench.cc b/src/tint/type/texel_format_bench.cc
similarity index 95%
rename from src/tint/ast/texel_format_bench.cc
rename to src/tint/type/texel_format_bench.cc
index 0b1b18e..8cf7a73 100644
--- a/src/tint/ast/texel_format_bench.cc
+++ b/src/tint/type/texel_format_bench.cc
@@ -15,18 +15,18 @@
 ////////////////////////////////////////////////////////////////////////////////
 // File generated by tools/src/cmd/gen
 // using the template:
-//   src/tint/ast/texel_format_bench.cc.tmpl
+//   src/tint/type/texel_format_bench.cc.tmpl
 //
 // Do not modify this file directly
 ////////////////////////////////////////////////////////////////////////////////
 
-#include "src/tint/ast/texel_format.h"
+#include "src/tint/type/texel_format.h"
 
 #include <array>
 
 #include "benchmark/benchmark.h"
 
-namespace tint::ast {
+namespace tint::type {
 namespace {
 
 void TexelFormatParser(::benchmark::State& state) {
@@ -67,4 +67,4 @@
 BENCHMARK(TexelFormatParser);
 
 }  // namespace
-}  // namespace tint::ast
+}  // namespace tint::type
diff --git a/src/tint/ast/texel_format_bench.cc.tmpl b/src/tint/type/texel_format_bench.cc.tmpl
similarity index 87%
rename from src/tint/ast/texel_format_bench.cc.tmpl
rename to src/tint/type/texel_format_bench.cc.tmpl
index 4df62b4..2561dac 100644
--- a/src/tint/ast/texel_format_bench.cc.tmpl
+++ b/src/tint/type/texel_format_bench.cc.tmpl
@@ -11,16 +11,16 @@
 {{- Import "src/tint/templates/enums.tmpl.inc" -}}
 {{- $enum := (Sem.Enum "texel_format") -}}
 
-#include "src/tint/ast/texel_format.h"
+#include "src/tint/type/texel_format.h"
 
 #include <array>
 
 #include "benchmark/benchmark.h"
 
-namespace tint::ast {
+namespace tint::type {
 namespace {
 
 {{ Eval "BenchmarkParseEnum" $enum }}
 
 }  // namespace
-}  // namespace tint::ast
+}  // namespace tint::type
diff --git a/src/tint/ast/texel_format_test.cc b/src/tint/type/texel_format_test.cc
similarity index 96%
rename from src/tint/ast/texel_format_test.cc
rename to src/tint/type/texel_format_test.cc
index 2caee4a..c7bc0e4 100644
--- a/src/tint/ast/texel_format_test.cc
+++ b/src/tint/type/texel_format_test.cc
@@ -15,19 +15,19 @@
 ////////////////////////////////////////////////////////////////////////////////
 // File generated by tools/src/cmd/gen
 // using the template:
-//   src/tint/ast/texel_format_test.cc.tmpl
+//   src/tint/type/texel_format_test.cc.tmpl
 //
 // Do not modify this file directly
 ////////////////////////////////////////////////////////////////////////////////
 
-#include "src/tint/ast/texel_format.h"
+#include "src/tint/type/texel_format.h"
 
 #include <string>
 
-#include "src/tint/ast/test_helper.h"
+#include "src/tint/type/test_helper.h"
 #include "src/tint/utils/string.h"
 
-namespace tint::ast {
+namespace tint::type {
 namespace {
 
 namespace parse_print_tests {
@@ -106,4 +106,4 @@
 }  // namespace parse_print_tests
 
 }  // namespace
-}  // namespace tint::ast
+}  // namespace tint::type
diff --git a/src/tint/ast/texel_format_test.cc.tmpl b/src/tint/type/texel_format_test.cc.tmpl
similarity index 82%
rename from src/tint/ast/texel_format_test.cc.tmpl
rename to src/tint/type/texel_format_test.cc.tmpl
index 304cfeb..e7a0e59 100644
--- a/src/tint/ast/texel_format_test.cc.tmpl
+++ b/src/tint/type/texel_format_test.cc.tmpl
@@ -11,17 +11,17 @@
 {{- Import "src/tint/templates/enums.tmpl.inc" -}}
 {{- $enum := (Sem.Enum "texel_format") -}}
 
-#include "src/tint/ast/texel_format.h"
+#include "src/tint/type/texel_format.h"
 
 #include <string>
 
-#include "src/tint/ast/test_helper.h"
+#include "src/tint/type/test_helper.h"
 #include "src/tint/utils/string.h"
 
-namespace tint::ast {
+namespace tint::type {
 namespace {
 
 {{ Eval "TestParsePrintEnum" $enum}}
 
 }  // namespace
-}  // namespace tint::ast
+}  // namespace tint::type
diff --git a/src/tint/type/texture.cc b/src/tint/type/texture.cc
index 57ce265..717d63a 100644
--- a/src/tint/type/texture.cc
+++ b/src/tint/type/texture.cc
@@ -18,7 +18,7 @@
 
 namespace tint::type {
 
-Texture::Texture(size_t hash, ast::TextureDimension dim) : Base(hash, type::Flags{}), dim_(dim) {}
+Texture::Texture(size_t hash, TextureDimension dim) : Base(hash, type::Flags{}), dim_(dim) {}
 
 Texture::~Texture() = default;
 
diff --git a/src/tint/type/texture.h b/src/tint/type/texture.h
index fc0f72d..4fab761 100644
--- a/src/tint/type/texture.h
+++ b/src/tint/type/texture.h
@@ -15,7 +15,7 @@
 #ifndef SRC_TINT_TYPE_TEXTURE_H_
 #define SRC_TINT_TYPE_TEXTURE_H_
 
-#include "src/tint/ast/texture.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/type/type.h"
 
 namespace tint::type {
@@ -26,15 +26,15 @@
     /// Constructor
     /// @param hash the unique hash of the node
     /// @param dim the dimensionality of the texture
-    Texture(size_t hash, ast::TextureDimension dim);
+    Texture(size_t hash, TextureDimension dim);
     /// Destructor
     ~Texture() override;
 
     /// @returns the texture dimension
-    ast::TextureDimension dim() const { return dim_; }
+    TextureDimension dim() const { return dim_; }
 
   private:
-    ast::TextureDimension const dim_;
+    TextureDimension const dim_;
 };
 
 }  // namespace tint::type
diff --git a/src/tint/type/texture_dimension.cc b/src/tint/type/texture_dimension.cc
new file mode 100644
index 0000000..4b4fea9
--- /dev/null
+++ b/src/tint/type/texture_dimension.cc
@@ -0,0 +1,46 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/type/texture_dimension.h"
+
+namespace tint::type {
+
+std::ostream& operator<<(std::ostream& out, type::TextureDimension dim) {
+    switch (dim) {
+        case type::TextureDimension::kNone:
+            out << "None";
+            break;
+        case type::TextureDimension::k1d:
+            out << "1d";
+            break;
+        case type::TextureDimension::k2d:
+            out << "2d";
+            break;
+        case type::TextureDimension::k2dArray:
+            out << "2d_array";
+            break;
+        case type::TextureDimension::k3d:
+            out << "3d";
+            break;
+        case type::TextureDimension::kCube:
+            out << "cube";
+            break;
+        case type::TextureDimension::kCubeArray:
+            out << "cube_array";
+            break;
+    }
+    return out;
+}
+
+}  // namespace tint::type
diff --git a/src/tint/type/texture_dimension.h b/src/tint/type/texture_dimension.h
new file mode 100644
index 0000000..0da2b05
--- /dev/null
+++ b/src/tint/type/texture_dimension.h
@@ -0,0 +1,47 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SRC_TINT_TYPE_TEXTURE_DIMENSION_H_
+#define SRC_TINT_TYPE_TEXTURE_DIMENSION_H_
+
+#include <ostream>
+
+namespace tint::type {
+
+/// The dimensionality of the texture
+enum class TextureDimension {
+    /// Invalid texture
+    kNone = -1,
+    /// 1 dimensional texture
+    k1d,
+    /// 2 dimensional texture
+    k2d,
+    /// 2 dimensional array texture
+    k2dArray,
+    /// 3 dimensional texture
+    k3d,
+    /// cube texture
+    kCube,
+    /// cube array texture
+    kCubeArray,
+};
+
+/// @param out the std::ostream to write to
+/// @param dim the type::TextureDimension
+/// @return the std::ostream so calls can be chained
+std::ostream& operator<<(std::ostream& out, type::TextureDimension dim);
+
+}  // namespace tint::type
+
+#endif  // SRC_TINT_TYPE_TEXTURE_DIMENSION_H_
diff --git a/src/tint/type/texture_test.cc b/src/tint/type/texture_test.cc
index ae223a1..607fd4a 100644
--- a/src/tint/type/texture_test.cc
+++ b/src/tint/type/texture_test.cc
@@ -20,7 +20,7 @@
 namespace tint::type {
 namespace {
 
-using TextureTypeDimTest = TestParamHelper<ast::TextureDimension>;
+using TextureTypeDimTest = TestParamHelper<TextureDimension>;
 
 TEST_P(TextureTypeDimTest, DimMustMatch) {
     // Check that the dim() query returns the right dimensionality.
@@ -33,12 +33,12 @@
 
 INSTANTIATE_TEST_SUITE_P(Dimensions,
                          TextureTypeDimTest,
-                         ::testing::Values(ast::TextureDimension::k1d,
-                                           ast::TextureDimension::k2d,
-                                           ast::TextureDimension::k2dArray,
-                                           ast::TextureDimension::k3d,
-                                           ast::TextureDimension::kCube,
-                                           ast::TextureDimension::kCubeArray));
+                         ::testing::Values(TextureDimension::k1d,
+                                           TextureDimension::k2d,
+                                           TextureDimension::k2dArray,
+                                           TextureDimension::k3d,
+                                           TextureDimension::kCube,
+                                           TextureDimension::kCubeArray));
 
 }  // namespace
 }  // namespace tint::type
diff --git a/src/tint/type/type_test.cc b/src/tint/type/type_test.cc
index 48b44dd..62ec706 100644
--- a/src/tint/type/type_test.cc
+++ b/src/tint/type/type_test.cc
@@ -44,7 +44,7 @@
     const Matrix* mat4x3_f16 = create<Matrix>(vec3_f16, 4u);
     const Matrix* mat4x3_af = create<Matrix>(vec3_af, 4u);
     const Reference* ref_u32 =
-        create<Reference>(u32, ast::AddressSpace::kPrivate, ast::Access::kReadWrite);
+        create<Reference>(u32, AddressSpace::kPrivate, type::Access::kReadWrite);
     const Struct* str_f32 = create<Struct>(Source{},
                                            Sym("str_f32"),
                                            utils::Vector{
diff --git a/src/tint/writer/append_vector.cc b/src/tint/writer/append_vector.cc
index 4503041..ab0ab70 100644
--- a/src/tint/writer/append_vector.cc
+++ b/src/tint/writer/append_vector.cc
@@ -137,7 +137,7 @@
         auto* scalar_cast_target = b->create<sem::TypeConversion>(
             packed_el_sem_ty,
             b->create<sem::Parameter>(nullptr, 0u, scalar_sem->Type()->UnwrapRef(),
-                                      ast::AddressSpace::kNone, ast::Access::kUndefined),
+                                      type::AddressSpace::kNone, type::Access::kUndefined),
             sem::EvaluationStage::kRuntime);
         auto* scalar_cast_sem = b->create<sem::Call>(
             scalar_cast_ast, scalar_cast_target, sem::EvaluationStage::kRuntime,
@@ -158,7 +158,7 @@
                          [&](const tint::sem::Expression* arg, size_t i) -> const sem::Parameter* {
                              return b->create<sem::Parameter>(
                                  nullptr, static_cast<uint32_t>(i), arg->Type()->UnwrapRef(),
-                                 ast::AddressSpace::kNone, ast::Access::kUndefined);
+                                 type::AddressSpace::kNone, type::Access::kUndefined);
                          }),
         sem::EvaluationStage::kRuntime);
     auto* initializer_sem =
diff --git a/src/tint/writer/append_vector_test.cc b/src/tint/writer/append_vector_test.cc
index e13ed3d..c030db4 100644
--- a/src/tint/writer/append_vector_test.cc
+++ b/src/tint/writer/append_vector_test.cc
@@ -250,7 +250,7 @@
 
 // AppendVector(vec_12, 3) -> vec3<i32>(vec_12, 3)
 TEST_F(AppendVectorTest, Vec2i32Var_i32) {
-    GlobalVar("vec_12", ty.vec2<i32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("vec_12", ty.vec2<i32>(), type::AddressSpace::kPrivate);
     auto* vec_12 = Expr("vec_12");
     auto* scalar_3 = Expr(3_i);
     WrapInFunction(vec_12, scalar_3);
@@ -286,7 +286,7 @@
 
 // AppendVector(1, 2, scalar_3) -> vec3<i32>(1, 2, scalar_3)
 TEST_F(AppendVectorTest, Vec2i32_i32Var) {
-    GlobalVar("scalar_3", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("scalar_3", ty.i32(), type::AddressSpace::kPrivate);
     auto* scalar_1 = Expr(1_i);
     auto* scalar_2 = Expr(2_i);
     auto* scalar_3 = Expr("scalar_3");
@@ -327,8 +327,8 @@
 
 // AppendVector(vec_12, scalar_3) -> vec3<i32>(vec_12, scalar_3)
 TEST_F(AppendVectorTest, Vec2i32Var_i32Var) {
-    GlobalVar("vec_12", ty.vec2<i32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("scalar_3", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("vec_12", ty.vec2<i32>(), type::AddressSpace::kPrivate);
+    GlobalVar("scalar_3", ty.i32(), type::AddressSpace::kPrivate);
     auto* vec_12 = Expr("vec_12");
     auto* scalar_3 = Expr("scalar_3");
     WrapInFunction(vec_12, scalar_3);
@@ -364,8 +364,8 @@
 
 // AppendVector(vec_12, scalar_3) -> vec3<i32>(vec_12, i32(scalar_3))
 TEST_F(AppendVectorTest, Vec2i32Var_f32Var) {
-    GlobalVar("vec_12", ty.vec2<i32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("scalar_3", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("vec_12", ty.vec2<i32>(), type::AddressSpace::kPrivate);
+    GlobalVar("scalar_3", ty.f32(), type::AddressSpace::kPrivate);
     auto* vec_12 = Expr("vec_12");
     auto* scalar_3 = Expr("scalar_3");
     WrapInFunction(vec_12, scalar_3);
@@ -405,8 +405,8 @@
 
 // AppendVector(vec_12, scalar_3) -> vec3<bool>(vec_12, scalar_3)
 TEST_F(AppendVectorTest, Vec2boolVar_boolVar) {
-    GlobalVar("vec_12", ty.vec2<bool>(), ast::AddressSpace::kPrivate);
-    GlobalVar("scalar_3", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("vec_12", ty.vec2<bool>(), type::AddressSpace::kPrivate);
+    GlobalVar("scalar_3", ty.bool_(), type::AddressSpace::kPrivate);
     auto* vec_12 = Expr("vec_12");
     auto* scalar_3 = Expr("scalar_3");
     WrapInFunction(vec_12, scalar_3);
diff --git a/src/tint/writer/flatten_bindings_test.cc b/src/tint/writer/flatten_bindings_test.cc
index 48d765f..ff16ed8 100644
--- a/src/tint/writer/flatten_bindings_test.cc
+++ b/src/tint/writer/flatten_bindings_test.cc
@@ -19,6 +19,7 @@
 #include "gtest/gtest.h"
 #include "src/tint/program_builder.h"
 #include "src/tint/sem/variable.h"
+#include "src/tint/type/texture_dimension.h"
 
 namespace tint::writer {
 namespace {
@@ -38,9 +39,9 @@
 
 TEST_F(FlattenBindingsTest, AlreadyFlat) {
     ProgramBuilder b;
-    b.GlobalVar("a", b.ty.i32(), ast::AddressSpace::kUniform, b.Group(0_a), b.Binding(0_a));
-    b.GlobalVar("b", b.ty.i32(), ast::AddressSpace::kUniform, b.Group(0_a), b.Binding(1_a));
-    b.GlobalVar("c", b.ty.i32(), ast::AddressSpace::kUniform, b.Group(0_a), b.Binding(2_a));
+    b.GlobalVar("a", b.ty.i32(), type::AddressSpace::kUniform, b.Group(0_a), b.Binding(0_a));
+    b.GlobalVar("b", b.ty.i32(), type::AddressSpace::kUniform, b.Group(0_a), b.Binding(1_a));
+    b.GlobalVar("c", b.ty.i32(), type::AddressSpace::kUniform, b.Group(0_a), b.Binding(2_a));
 
     Program program(std::move(b));
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
@@ -51,9 +52,9 @@
 
 TEST_F(FlattenBindingsTest, NotFlat_SingleNamespace) {
     ProgramBuilder b;
-    b.GlobalVar("a", b.ty.i32(), ast::AddressSpace::kUniform, b.Group(0_a), b.Binding(0_a));
-    b.GlobalVar("b", b.ty.i32(), ast::AddressSpace::kUniform, b.Group(1_a), b.Binding(1_a));
-    b.GlobalVar("c", b.ty.i32(), ast::AddressSpace::kUniform, b.Group(2_a), b.Binding(2_a));
+    b.GlobalVar("a", b.ty.i32(), type::AddressSpace::kUniform, b.Group(0_a), b.Binding(0_a));
+    b.GlobalVar("b", b.ty.i32(), type::AddressSpace::kUniform, b.Group(1_a), b.Binding(1_a));
+    b.GlobalVar("c", b.ty.i32(), type::AddressSpace::kUniform, b.Group(2_a), b.Binding(2_a));
     b.WrapInFunction(b.Expr("a"), b.Expr("b"), b.Expr("c"));
 
     Program program(std::move(b));
@@ -84,9 +85,9 @@
     ProgramBuilder b;
 
     const size_t num_buffers = 3;
-    b.GlobalVar("buffer1", b.ty.i32(), ast::AddressSpace::kUniform, b.Group(0_a), b.Binding(0_a));
-    b.GlobalVar("buffer2", b.ty.i32(), ast::AddressSpace::kStorage, b.Group(1_a), b.Binding(1_a));
-    b.GlobalVar("buffer3", b.ty.i32(), ast::AddressSpace::kStorage, ast::Access::kRead,
+    b.GlobalVar("buffer1", b.ty.i32(), type::AddressSpace::kUniform, b.Group(0_a), b.Binding(0_a));
+    b.GlobalVar("buffer2", b.ty.i32(), type::AddressSpace::kStorage, b.Group(1_a), b.Binding(1_a));
+    b.GlobalVar("buffer3", b.ty.i32(), type::AddressSpace::kStorage, type::Access::kRead,
                 b.Group(2_a), b.Binding(2_a));
 
     const size_t num_samplers = 2;
@@ -95,17 +96,17 @@
                 b.Binding(4_a));
 
     const size_t num_textures = 6;
-    b.GlobalVar("texture1", b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32()),
+    b.GlobalVar("texture1", b.ty.sampled_texture(type::TextureDimension::k2d, b.ty.f32()),
                 b.Group(5_a), b.Binding(5_a));
-    b.GlobalVar("texture2", b.ty.multisampled_texture(ast::TextureDimension::k2d, b.ty.f32()),
+    b.GlobalVar("texture2", b.ty.multisampled_texture(type::TextureDimension::k2d, b.ty.f32()),
                 b.Group(6_a), b.Binding(6_a));
     b.GlobalVar("texture3",
-                b.ty.storage_texture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Float,
-                                     ast::Access::kWrite),
+                b.ty.storage_texture(type::TextureDimension::k2d, type::TexelFormat::kR32Float,
+                                     type::Access::kWrite),
                 b.Group(7_a), b.Binding(7_a));
-    b.GlobalVar("texture4", b.ty.depth_texture(ast::TextureDimension::k2d), b.Group(8_a),
+    b.GlobalVar("texture4", b.ty.depth_texture(type::TextureDimension::k2d), b.Group(8_a),
                 b.Binding(8_a));
-    b.GlobalVar("texture5", b.ty.depth_multisampled_texture(ast::TextureDimension::k2d),
+    b.GlobalVar("texture5", b.ty.depth_multisampled_texture(type::TextureDimension::k2d),
                 b.Group(9_a), b.Binding(9_a));
     b.GlobalVar("texture6", b.ty.external_texture(), b.Group(10_a), b.Binding(10_a));
 
diff --git a/src/tint/writer/generate_external_texture_bindings_test.cc b/src/tint/writer/generate_external_texture_bindings_test.cc
index 4fc1934..e441517 100644
--- a/src/tint/writer/generate_external_texture_bindings_test.cc
+++ b/src/tint/writer/generate_external_texture_bindings_test.cc
@@ -23,7 +23,7 @@
 
 using namespace tint::number_suffixes;  // NOLINT
 
-constexpr auto kUniform = ast::AddressSpace::kUniform;
+constexpr auto kUniform = type::AddressSpace::kUniform;
 
 class GenerateExternalTextureBindingsTest : public ::testing::Test {};
 
diff --git a/src/tint/writer/glsl/generator.h b/src/tint/writer/glsl/generator.h
index d48b0bc..60d5aa1 100644
--- a/src/tint/writer/glsl/generator.h
+++ b/src/tint/writer/glsl/generator.h
@@ -21,10 +21,10 @@
 #include <utility>
 #include <vector>
 
-#include "src/tint/ast/access.h"
 #include "src/tint/ast/pipeline_stage.h"
 #include "src/tint/sem/binding_point.h"
 #include "src/tint/sem/sampler_texture_pair.h"
+#include "src/tint/type/access.h"
 #include "src/tint/writer/glsl/version.h"
 #include "src/tint/writer/text.h"
 
@@ -61,7 +61,7 @@
 
     /// A map of old binding point to new access control for the BindingRemapper
     /// transform
-    std::unordered_map<sem::BindingPoint, ast::Access> access_controls;
+    std::unordered_map<sem::BindingPoint, type::Access> access_controls;
 
     /// If true, then validation will be disabled for binding point collisions
     /// generated by the BindingRemapper transform
diff --git a/src/tint/writer/glsl/generator_impl.cc b/src/tint/writer/glsl/generator_impl.cc
index 720423c..8bd4033 100644
--- a/src/tint/writer/glsl/generator_impl.cc
+++ b/src/tint/writer/glsl/generator_impl.cc
@@ -70,6 +70,7 @@
 #include "src/tint/type/multisampled_texture.h"
 #include "src/tint/type/sampled_texture.h"
 #include "src/tint/type/storage_texture.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/utils/defer.h"
 #include "src/tint/utils/map.h"
 #include "src/tint/utils/scoped_assignment.h"
@@ -373,7 +374,7 @@
                dst_type->is_float_scalar_or_vector()) {
         out << "uintBitsToFloat";
     } else {
-        if (!EmitType(out, dst_type, ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
+        if (!EmitType(out, dst_type, type::AddressSpace::kNone, type::Access::kReadWrite, "")) {
             return false;
         }
     }
@@ -436,12 +437,12 @@
     auto* uint_type = BoolTypeToUint(bool_type);
 
     // Cast result to bool scalar or vector type.
-    if (!EmitType(out, bool_type, ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
+    if (!EmitType(out, bool_type, type::AddressSpace::kNone, type::Access::kReadWrite, "")) {
         return false;
     }
     ScopedParen outerCastParen(out);
     // Cast LHS to uint scalar or vector type.
-    if (!EmitType(out, uint_type, ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
+    if (!EmitType(out, uint_type, type::AddressSpace::kNone, type::Access::kReadWrite, "")) {
         return false;
     }
     {
@@ -461,7 +462,7 @@
         return false;
     }
     // Cast RHS to uint scalar or vector type.
-    if (!EmitType(out, uint_type, ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
+    if (!EmitType(out, uint_type, type::AddressSpace::kNone, type::Access::kReadWrite, "")) {
         return false;
     }
     {
@@ -488,21 +489,21 @@
                                 std::vector<std::string> parameter_names;
                                 {
                                     auto decl = line(&b);
-                                    if (!EmitTypeAndName(decl, ret_ty, ast::AddressSpace::kNone,
-                                                         ast::Access::kUndefined, fn_name)) {
+                                    if (!EmitTypeAndName(decl, ret_ty, type::AddressSpace::kNone,
+                                                         type::Access::kUndefined, fn_name)) {
                                         return "";
                                     }
                                     {
                                         ScopedParen sp(decl);
                                         const auto* ty = TypeOf(expr->lhs)->UnwrapRef();
-                                        if (!EmitTypeAndName(decl, ty, ast::AddressSpace::kNone,
-                                                             ast::Access::kUndefined, "lhs")) {
+                                        if (!EmitTypeAndName(decl, ty, type::AddressSpace::kNone,
+                                                             type::Access::kUndefined, "lhs")) {
                                             return "";
                                         }
                                         decl << ", ";
                                         ty = TypeOf(expr->rhs)->UnwrapRef();
-                                        if (!EmitTypeAndName(decl, ty, ast::AddressSpace::kNone,
-                                                             ast::Access::kUndefined, "rhs")) {
+                                        if (!EmitTypeAndName(decl, ty, type::AddressSpace::kNone,
+                                                             type::Access::kUndefined, "rhs")) {
                                             return "";
                                         }
                                     }
@@ -827,7 +828,7 @@
 bool GeneratorImpl::EmitTypeConversion(std::ostream& out,
                                        const sem::Call* call,
                                        const sem::TypeConversion* conv) {
-    if (!EmitType(out, conv->Target(), ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
+    if (!EmitType(out, conv->Target(), type::AddressSpace::kNone, type::Access::kReadWrite, "")) {
         return false;
     }
     ScopedParen sp(out);
@@ -850,7 +851,7 @@
         return EmitZeroValue(out, type);
     }
 
-    if (!EmitType(out, type, ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
+    if (!EmitType(out, type, type::AddressSpace::kNone, type::Access::kReadWrite, "")) {
         return false;
     }
     ScopedParen sp(out);
@@ -920,8 +921,8 @@
 
             {
                 auto pre = line();
-                if (!EmitTypeAndName(pre, builtin->ReturnType(), ast::AddressSpace::kNone,
-                                     ast::Access::kUndefined, result)) {
+                if (!EmitTypeAndName(pre, builtin->ReturnType(), type::AddressSpace::kNone,
+                                     type::Access::kUndefined, result)) {
                     return false;
                 }
                 pre << ";";
@@ -1058,8 +1059,8 @@
 bool GeneratorImpl::EmitCountOneBitsCall(std::ostream& out, const ast::CallExpression* expr) {
     // GLSL's bitCount returns an integer type, so cast it to the appropriate
     // unsigned type.
-    if (!EmitType(out, TypeOf(expr)->UnwrapRef(), ast::AddressSpace::kNone, ast::Access::kReadWrite,
-                  "")) {
+    if (!EmitType(out, TypeOf(expr)->UnwrapRef(), type::AddressSpace::kNone,
+                  type::Access::kReadWrite, "")) {
         return false;
     }
     out << "(bitCount(";
@@ -1130,7 +1131,7 @@
             std::string v;
             {
                 std::stringstream s;
-                if (!EmitType(s, vec_ty->type(), ast::AddressSpace::kNone, ast::Access::kRead,
+                if (!EmitType(s, vec_ty->type(), type::AddressSpace::kNone, type::Access::kRead,
                               "")) {
                     return "";
                 }
@@ -1138,16 +1139,16 @@
             }
             {  // (u)int tint_int_dot([i|u]vecN a, [i|u]vecN b) {
                 auto l = line(&b);
-                if (!EmitType(l, vec_ty->type(), ast::AddressSpace::kNone, ast::Access::kRead,
+                if (!EmitType(l, vec_ty->type(), type::AddressSpace::kNone, type::Access::kRead,
                               "")) {
                     return "";
                 }
                 l << " " << fn_name << "(";
-                if (!EmitType(l, vec_ty, ast::AddressSpace::kNone, ast::Access::kRead, "")) {
+                if (!EmitType(l, vec_ty, type::AddressSpace::kNone, type::Access::kRead, "")) {
                     return "";
                 }
                 l << " a, ";
-                if (!EmitType(l, vec_ty, ast::AddressSpace::kNone, ast::Access::kRead, "")) {
+                if (!EmitType(l, vec_ty, type::AddressSpace::kNone, type::Access::kRead, "")) {
                     return "";
                 }
                 l << " b) {";
@@ -1198,8 +1199,8 @@
 
             {
                 auto l = line(b);
-                if (!EmitType(l, builtin->ReturnType(), ast::AddressSpace::kNone,
-                              ast::Access::kUndefined, "")) {
+                if (!EmitType(l, builtin->ReturnType(), type::AddressSpace::kNone,
+                              type::Access::kUndefined, "")) {
                     return false;
                 }
                 l << " result;";
@@ -1224,8 +1225,8 @@
 
             {
                 auto l = line(b);
-                if (!EmitType(l, builtin->ReturnType(), ast::AddressSpace::kNone,
-                              ast::Access::kUndefined, "")) {
+                if (!EmitType(l, builtin->ReturnType(), type::AddressSpace::kNone,
+                              type::Access::kUndefined, "")) {
                     return false;
                 }
                 l << " result;";
@@ -1406,8 +1407,8 @@
             out << ")";
             // textureSize() on array samplers returns the array size in the
             // final component, so strip it out.
-            if (texture_type->dim() == ast::TextureDimension::k2dArray ||
-                texture_type->dim() == ast::TextureDimension::kCubeArray) {
+            if (texture_type->dim() == type::TextureDimension::k2dArray ||
+                texture_type->dim() == type::TextureDimension::kCubeArray) {
                 out << ".xy";
             }
             return true;
@@ -1548,7 +1549,7 @@
     // GLSL requires Dref to be appended to the coordinates, *unless* it's
     // samplerCubeArrayShadow, in which case it will be handled as a separate
     // parameter.
-    if (texture_type->dim() == ast::TextureDimension::kCubeArray) {
+    if (texture_type->dim() == type::TextureDimension::kCubeArray) {
         append_depth_ref_to_coords = false;
     }
 
@@ -1882,7 +1883,7 @@
     {
         auto out = line();
         auto name = builder_.Symbols().NameFor(func->symbol);
-        if (!EmitType(out, sem->ReturnType(), ast::AddressSpace::kNone, ast::Access::kReadWrite,
+        if (!EmitType(out, sem->ReturnType(), type::AddressSpace::kNone, type::Access::kReadWrite,
                       "")) {
             return false;
         }
@@ -1938,20 +1939,20 @@
         [&](const ast::Var* var) {
             auto* sem = builder_.Sem().Get<sem::GlobalVariable>(global);
             switch (sem->AddressSpace()) {
-                case ast::AddressSpace::kUniform:
+                case type::AddressSpace::kUniform:
                     return EmitUniformVariable(var, sem);
-                case ast::AddressSpace::kStorage:
+                case type::AddressSpace::kStorage:
                     return EmitStorageVariable(var, sem);
-                case ast::AddressSpace::kHandle:
+                case type::AddressSpace::kHandle:
                     return EmitHandleVariable(var, sem);
-                case ast::AddressSpace::kPrivate:
+                case type::AddressSpace::kPrivate:
                     return EmitPrivateVariable(sem);
-                case ast::AddressSpace::kWorkgroup:
+                case type::AddressSpace::kWorkgroup:
                     return EmitWorkgroupVariable(sem);
-                case ast::AddressSpace::kIn:
-                case ast::AddressSpace::kOut:
+                case type::AddressSpace::kIn:
+                case type::AddressSpace::kOut:
                     return EmitIOVariable(sem);
-                case ast::AddressSpace::kPushConstant:
+                case type::AddressSpace::kPushConstant:
                     diagnostics_.add_error(
                         diag::System::Writer,
                         "unhandled address space " + utils::ToString(sem->AddressSpace()));
@@ -2032,59 +2033,59 @@
     if (auto* storage = type->As<type::StorageTexture>()) {
         out << "layout(";
         switch (storage->texel_format()) {
-            case ast::TexelFormat::kBgra8Unorm:
+            case type::TexelFormat::kBgra8Unorm:
                 TINT_ICE(Writer, diagnostics_)
                     << "bgra8unorm should have been polyfilled to rgba8unorm";
                 break;
-            case ast::TexelFormat::kR32Uint:
+            case type::TexelFormat::kR32Uint:
                 out << "r32ui";
                 break;
-            case ast::TexelFormat::kR32Sint:
+            case type::TexelFormat::kR32Sint:
                 out << "r32i";
                 break;
-            case ast::TexelFormat::kR32Float:
+            case type::TexelFormat::kR32Float:
                 out << "r32f";
                 break;
-            case ast::TexelFormat::kRgba8Unorm:
+            case type::TexelFormat::kRgba8Unorm:
                 out << "rgba8";
                 break;
-            case ast::TexelFormat::kRgba8Snorm:
+            case type::TexelFormat::kRgba8Snorm:
                 out << "rgba8_snorm";
                 break;
-            case ast::TexelFormat::kRgba8Uint:
+            case type::TexelFormat::kRgba8Uint:
                 out << "rgba8ui";
                 break;
-            case ast::TexelFormat::kRgba8Sint:
+            case type::TexelFormat::kRgba8Sint:
                 out << "rgba8i";
                 break;
-            case ast::TexelFormat::kRg32Uint:
+            case type::TexelFormat::kRg32Uint:
                 out << "rg32ui";
                 break;
-            case ast::TexelFormat::kRg32Sint:
+            case type::TexelFormat::kRg32Sint:
                 out << "rg32i";
                 break;
-            case ast::TexelFormat::kRg32Float:
+            case type::TexelFormat::kRg32Float:
                 out << "rg32f";
                 break;
-            case ast::TexelFormat::kRgba16Uint:
+            case type::TexelFormat::kRgba16Uint:
                 out << "rgba16ui";
                 break;
-            case ast::TexelFormat::kRgba16Sint:
+            case type::TexelFormat::kRgba16Sint:
                 out << "rgba16i";
                 break;
-            case ast::TexelFormat::kRgba16Float:
+            case type::TexelFormat::kRgba16Float:
                 out << "rgba16f";
                 break;
-            case ast::TexelFormat::kRgba32Uint:
+            case type::TexelFormat::kRgba32Uint:
                 out << "rgba32ui";
                 break;
-            case ast::TexelFormat::kRgba32Sint:
+            case type::TexelFormat::kRgba32Sint:
                 out << "rgba32i";
                 break;
-            case ast::TexelFormat::kRgba32Float:
+            case type::TexelFormat::kRgba32Float:
                 out << "rgba32f";
                 break;
-            case ast::TexelFormat::kUndefined:
+            case type::TexelFormat::kUndefined:
                 TINT_ICE(Writer, diagnostics_) << "invalid texel format";
                 return false;
         }
@@ -2336,7 +2337,7 @@
             return true;
         },
         [&](const type::Vector* v) {
-            if (!EmitType(out, v, ast::AddressSpace::kNone, ast::Access::kUndefined, "")) {
+            if (!EmitType(out, v, type::AddressSpace::kNone, type::Access::kUndefined, "")) {
                 return false;
             }
 
@@ -2357,7 +2358,7 @@
             return true;
         },
         [&](const type::Matrix* m) {
-            if (!EmitType(out, m, ast::AddressSpace::kNone, ast::Access::kUndefined, "")) {
+            if (!EmitType(out, m, type::AddressSpace::kNone, type::Access::kUndefined, "")) {
                 return false;
             }
 
@@ -2374,7 +2375,7 @@
             return true;
         },
         [&](const type::Array* a) {
-            if (!EmitType(out, a, ast::AddressSpace::kNone, ast::Access::kUndefined, "")) {
+            if (!EmitType(out, a, type::AddressSpace::kNone, type::Access::kUndefined, "")) {
                 return false;
             }
 
@@ -2466,7 +2467,7 @@
     } else if (type->Is<type::U32>()) {
         out << "0u";
     } else if (auto* vec = type->As<type::Vector>()) {
-        if (!EmitType(out, type, ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
+        if (!EmitType(out, type, type::AddressSpace::kNone, type::Access::kReadWrite, "")) {
             return false;
         }
         ScopedParen sp(out);
@@ -2479,7 +2480,7 @@
             }
         }
     } else if (auto* mat = type->As<type::Matrix>()) {
-        if (!EmitType(out, type, ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
+        if (!EmitType(out, type, type::AddressSpace::kNone, type::Access::kReadWrite, "")) {
             return false;
         }
         ScopedParen sp(out);
@@ -2492,7 +2493,7 @@
             }
         }
     } else if (auto* str = type->As<sem::Struct>()) {
-        if (!EmitType(out, type, ast::AddressSpace::kNone, ast::Access::kUndefined, "")) {
+        if (!EmitType(out, type, type::AddressSpace::kNone, type::Access::kUndefined, "")) {
             return false;
         }
         bool first = true;
@@ -2506,7 +2507,7 @@
             EmitZeroValue(out, member->Type());
         }
     } else if (auto* arr = type->As<type::Array>()) {
-        if (!EmitType(out, type, ast::AddressSpace::kNone, ast::Access::kUndefined, "")) {
+        if (!EmitType(out, type, type::AddressSpace::kNone, type::Access::kUndefined, "")) {
             return false;
         }
         ScopedParen sp(out);
@@ -2831,24 +2832,24 @@
 
 bool GeneratorImpl::EmitType(std::ostream& out,
                              const type::Type* type,
-                             ast::AddressSpace address_space,
-                             ast::Access access,
+                             type::AddressSpace address_space,
+                             type::Access access,
                              const std::string& name,
                              bool* name_printed /* = nullptr */) {
     if (name_printed) {
         *name_printed = false;
     }
     switch (address_space) {
-        case ast::AddressSpace::kIn: {
+        case type::AddressSpace::kIn: {
             out << "in ";
             break;
         }
-        case ast::AddressSpace::kOut: {
+        case type::AddressSpace::kOut: {
             out << "out ";
             break;
         }
-        case ast::AddressSpace::kUniform:
-        case ast::AddressSpace::kHandle: {
+        case type::AddressSpace::kUniform:
+        case type::AddressSpace::kHandle: {
             out << "uniform ";
             break;
         }
@@ -2929,7 +2930,7 @@
 
         out << "highp ";
 
-        if (storage && storage->access() != ast::Access::kRead) {
+        if (storage && storage->access() != type::Access::kRead) {
             out << "writeonly ";
         }
         auto* subtype = sampled   ? sampled->type()
@@ -2949,22 +2950,22 @@
         out << (storage ? "image" : "sampler");
 
         switch (tex->dim()) {
-            case ast::TextureDimension::k1d:
+            case type::TextureDimension::k1d:
                 out << "1D";
                 break;
-            case ast::TextureDimension::k2d:
+            case type::TextureDimension::k2d:
                 out << ((ms || depth_ms) ? "2DMS" : "2D");
                 break;
-            case ast::TextureDimension::k2dArray:
+            case type::TextureDimension::k2dArray:
                 out << ((ms || depth_ms) ? "2DMSArray" : "2DArray");
                 break;
-            case ast::TextureDimension::k3d:
+            case type::TextureDimension::k3d:
                 out << "3D";
                 break;
-            case ast::TextureDimension::kCube:
+            case type::TextureDimension::kCube:
                 out << "Cube";
                 break;
-            case ast::TextureDimension::kCubeArray:
+            case type::TextureDimension::kCubeArray:
                 out << "CubeArray";
                 break;
             default:
@@ -3012,8 +3013,8 @@
 
 bool GeneratorImpl::EmitTypeAndName(std::ostream& out,
                                     const type::Type* type,
-                                    ast::AddressSpace address_space,
-                                    ast::Access access,
+                                    type::AddressSpace address_space,
+                                    type::Access access,
                                     const std::string& name) {
     bool printed_name = false;
     if (!EmitType(out, type, address_space, access, name, &printed_name)) {
@@ -3049,7 +3050,7 @@
 
         auto out = line(b);
 
-        if (!EmitTypeAndName(out, ty, ast::AddressSpace::kNone, ast::Access::kReadWrite, name)) {
+        if (!EmitTypeAndName(out, ty, type::AddressSpace::kNone, type::Access::kReadWrite, name)) {
             return false;
         }
         out << ";";
@@ -3117,7 +3118,7 @@
 
     auto out = line();
     // TODO(senorblanco): handle const
-    if (!EmitTypeAndName(out, type, ast::AddressSpace::kNone, ast::Access::kUndefined,
+    if (!EmitTypeAndName(out, type, type::AddressSpace::kNone, type::Access::kUndefined,
                          builder_.Symbols().NameFor(let->symbol))) {
         return false;
     }
@@ -3139,7 +3140,7 @@
 
     auto out = line();
     out << "const ";
-    if (!EmitTypeAndName(out, type, ast::AddressSpace::kNone, ast::Access::kUndefined,
+    if (!EmitTypeAndName(out, type, type::AddressSpace::kNone, type::Access::kUndefined,
                          builder_.Symbols().NameFor(var->symbol))) {
         return false;
     }
@@ -3166,8 +3167,8 @@
         std::vector<std::string> parameter_names;
         {
             auto decl = line(&b);
-            if (!EmitTypeAndName(decl, builtin->ReturnType(), ast::AddressSpace::kNone,
-                                 ast::Access::kUndefined, fn_name)) {
+            if (!EmitTypeAndName(decl, builtin->ReturnType(), type::AddressSpace::kNone,
+                                 type::Access::kUndefined, fn_name)) {
                 return "";
             }
             {
@@ -3182,8 +3183,8 @@
                         decl << "inout ";
                         ty = ptr->StoreType();
                     }
-                    if (!EmitTypeAndName(decl, ty, ast::AddressSpace::kNone,
-                                         ast::Access::kUndefined, param_name)) {
+                    if (!EmitTypeAndName(decl, ty, type::AddressSpace::kNone,
+                                         type::Access::kUndefined, param_name)) {
                         return "";
                     }
                     parameter_names.emplace_back(std::move(param_name));
diff --git a/src/tint/writer/glsl/generator_impl.h b/src/tint/writer/glsl/generator_impl.h
index 35043e9..7a623ed 100644
--- a/src/tint/writer/glsl/generator_impl.h
+++ b/src/tint/writer/glsl/generator_impl.h
@@ -413,8 +413,8 @@
     /// @returns true if the type is emitted
     bool EmitType(std::ostream& out,
                   const type::Type* type,
-                  ast::AddressSpace address_space,
-                  ast::Access access,
+                  type::AddressSpace address_space,
+                  type::Access access,
                   const std::string& name,
                   bool* name_printed = nullptr);
     /// Handles generating type and name
@@ -426,8 +426,8 @@
     /// @returns true if the type is emitted
     bool EmitTypeAndName(std::ostream& out,
                          const type::Type* type,
-                         ast::AddressSpace address_space,
-                         ast::Access access,
+                         type::AddressSpace address_space,
+                         type::Access access,
                          const std::string& name);
     /// Handles generating a structure declaration. If the structure has already been emitted, then
     /// this function will simply return `true` without emitting anything.
diff --git a/src/tint/writer/glsl/generator_impl_array_accessor_test.cc b/src/tint/writer/glsl/generator_impl_array_accessor_test.cc
index bed3dcf..cee4506 100644
--- a/src/tint/writer/glsl/generator_impl_array_accessor_test.cc
+++ b/src/tint/writer/glsl/generator_impl_array_accessor_test.cc
@@ -22,7 +22,7 @@
 using GlslGeneratorImplTest_Expression = TestHelper;
 
 TEST_F(GlslGeneratorImplTest_Expression, IndexAccessor) {
-    GlobalVar("ary", ty.array<i32, 10>(), ast::AddressSpace::kPrivate);
+    GlobalVar("ary", ty.array<i32, 10>(), type::AddressSpace::kPrivate);
     auto* expr = IndexAccessor("ary", 5_i);
     WrapInFunction(expr);
 
diff --git a/src/tint/writer/glsl/generator_impl_assign_test.cc b/src/tint/writer/glsl/generator_impl_assign_test.cc
index 98eae33..73d950c 100644
--- a/src/tint/writer/glsl/generator_impl_assign_test.cc
+++ b/src/tint/writer/glsl/generator_impl_assign_test.cc
@@ -20,8 +20,8 @@
 using GlslGeneratorImplTest_Assign = TestHelper;
 
 TEST_F(GlslGeneratorImplTest_Assign, Emit_Assign) {
-    GlobalVar("lhs", ty.i32(), ast::AddressSpace::kPrivate);
-    GlobalVar("rhs", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("lhs", ty.i32(), type::AddressSpace::kPrivate);
+    GlobalVar("rhs", ty.i32(), type::AddressSpace::kPrivate);
     auto* assign = Assign("lhs", "rhs");
     WrapInFunction(assign);
 
diff --git a/src/tint/writer/glsl/generator_impl_binary_test.cc b/src/tint/writer/glsl/generator_impl_binary_test.cc
index b5e391c..884cba0 100644
--- a/src/tint/writer/glsl/generator_impl_binary_test.cc
+++ b/src/tint/writer/glsl/generator_impl_binary_test.cc
@@ -43,8 +43,8 @@
         return;
     }
 
-    GlobalVar("left", ty.f32(), ast::AddressSpace::kPrivate);
-    GlobalVar("right", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("left", ty.f32(), type::AddressSpace::kPrivate);
+    GlobalVar("right", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* left = Expr("left");
     auto* right = Expr("right");
@@ -71,8 +71,8 @@
 
     Enable(ast::Extension::kF16);
 
-    GlobalVar("left", ty.f16(), ast::AddressSpace::kPrivate);
-    GlobalVar("right", ty.f16(), ast::AddressSpace::kPrivate);
+    GlobalVar("left", ty.f16(), type::AddressSpace::kPrivate);
+    GlobalVar("right", ty.f16(), type::AddressSpace::kPrivate);
 
     auto* left = Expr("left");
     auto* right = Expr("right");
@@ -90,8 +90,8 @@
 TEST_P(GlslBinaryTest, Emit_u32) {
     auto params = GetParam();
 
-    GlobalVar("left", ty.u32(), ast::AddressSpace::kPrivate);
-    GlobalVar("right", ty.u32(), ast::AddressSpace::kPrivate);
+    GlobalVar("left", ty.u32(), type::AddressSpace::kPrivate);
+    GlobalVar("right", ty.u32(), type::AddressSpace::kPrivate);
 
     auto* left = Expr("left");
     auto* right = Expr("right");
@@ -114,8 +114,8 @@
         return;
     }
 
-    GlobalVar("left", ty.i32(), ast::AddressSpace::kPrivate);
-    GlobalVar("right", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("left", ty.i32(), type::AddressSpace::kPrivate);
+    GlobalVar("right", ty.i32(), type::AddressSpace::kPrivate);
 
     auto* left = Expr("left");
     auto* right = Expr("right");
@@ -151,7 +151,7 @@
                     BinaryData{"(left % right)", ast::BinaryOp::kModulo}));
 
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_VectorScalar_f32) {
-    GlobalVar("a", vec3<f32>(1_f, 1_f, 1_f), ast::AddressSpace::kPrivate);
+    GlobalVar("a", vec3<f32>(1_f, 1_f, 1_f), type::AddressSpace::kPrivate);
     auto* lhs = Expr("a");
     auto* rhs = Expr(1_f);
 
@@ -169,7 +169,7 @@
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_VectorScalar_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("a", vec3<f16>(1_h, 1_h, 1_h), ast::AddressSpace::kPrivate);
+    GlobalVar("a", vec3<f16>(1_h, 1_h, 1_h), type::AddressSpace::kPrivate);
     auto* lhs = Expr("a");
     auto* rhs = Expr(1_h);
 
@@ -185,7 +185,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_ScalarVector_f32) {
-    GlobalVar("a", vec3<f32>(1_f, 1_f, 1_f), ast::AddressSpace::kPrivate);
+    GlobalVar("a", vec3<f32>(1_f, 1_f, 1_f), type::AddressSpace::kPrivate);
     auto* lhs = Expr(1_f);
     auto* rhs = Expr("a");
 
@@ -203,7 +203,7 @@
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_ScalarVector_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("a", vec3<f16>(1_h, 1_h, 1_h), ast::AddressSpace::kPrivate);
+    GlobalVar("a", vec3<f16>(1_h, 1_h, 1_h), type::AddressSpace::kPrivate);
     auto* lhs = Expr(1_h);
     auto* rhs = Expr("a");
 
@@ -219,7 +219,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_MatrixScalar_f32) {
-    GlobalVar("mat", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f32>(), type::AddressSpace::kPrivate);
     auto* lhs = Expr("mat");
     auto* rhs = Expr(1_f);
 
@@ -236,7 +236,7 @@
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_MatrixScalar_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("mat", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f16>(), type::AddressSpace::kPrivate);
     auto* lhs = Expr("mat");
     auto* rhs = Expr(1_h);
 
@@ -251,7 +251,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_ScalarMatrix_f32) {
-    GlobalVar("mat", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f32>(), type::AddressSpace::kPrivate);
     auto* lhs = Expr(1_f);
     auto* rhs = Expr("mat");
 
@@ -268,7 +268,7 @@
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_ScalarMatrix_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("mat", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f16>(), type::AddressSpace::kPrivate);
     auto* lhs = Expr(1_h);
     auto* rhs = Expr("mat");
 
@@ -283,7 +283,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_MatrixVector_f32) {
-    GlobalVar("mat", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f32>(), type::AddressSpace::kPrivate);
     auto* lhs = Expr("mat");
     auto* rhs = vec3<f32>(1_f, 1_f, 1_f);
 
@@ -300,7 +300,7 @@
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_MatrixVector_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("mat", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f16>(), type::AddressSpace::kPrivate);
     auto* lhs = Expr("mat");
     auto* rhs = vec3<f16>(1_h, 1_h, 1_h);
 
@@ -315,7 +315,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_VectorMatrix_f32) {
-    GlobalVar("mat", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f32>(), type::AddressSpace::kPrivate);
     auto* lhs = vec3<f32>(1_f, 1_f, 1_f);
     auto* rhs = Expr("mat");
 
@@ -332,7 +332,7 @@
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_VectorMatrix_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("mat", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f16>(), type::AddressSpace::kPrivate);
     auto* lhs = vec3<f16>(1_h, 1_h, 1_h);
     auto* rhs = Expr("mat");
 
@@ -347,8 +347,8 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_MatrixMatrix_f32) {
-    GlobalVar("lhs", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("rhs", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("lhs", ty.mat3x3<f32>(), type::AddressSpace::kPrivate);
+    GlobalVar("rhs", ty.mat3x3<f32>(), type::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kMultiply, Expr("lhs"), Expr("rhs"));
     WrapInFunction(expr);
@@ -363,8 +363,8 @@
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_MatrixMatrix_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("lhs", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
-    GlobalVar("rhs", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
+    GlobalVar("lhs", ty.mat3x3<f16>(), type::AddressSpace::kPrivate);
+    GlobalVar("rhs", ty.mat3x3<f16>(), type::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kMultiply, Expr("lhs"), Expr("rhs"));
     WrapInFunction(expr);
@@ -377,8 +377,8 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, ModF32) {
-    GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.f32(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kModulo, Expr("a"), Expr("b"));
     WrapInFunction(expr);
@@ -393,8 +393,8 @@
 TEST_F(GlslGeneratorImplTest_Binary, ModF16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("a", ty.f16(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.f16(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.f16(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.f16(), type::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kModulo, Expr("a"), Expr("b"));
     WrapInFunction(expr);
@@ -407,8 +407,8 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, ModVec3F32) {
-    GlobalVar("a", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.vec3<f32>(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.vec3<f32>(), type::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kModulo, Expr("a"), Expr("b"));
     WrapInFunction(expr);
@@ -423,8 +423,8 @@
 TEST_F(GlslGeneratorImplTest_Binary, ModVec3F16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("a", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.vec3<f16>(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.vec3<f16>(), type::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kModulo, Expr("a"), Expr("b"));
     WrapInFunction(expr);
@@ -437,8 +437,8 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, ModVec3F32ScalarF32) {
-    GlobalVar("a", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.vec3<f32>(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kModulo, Expr("a"), Expr("b"));
     WrapInFunction(expr);
@@ -453,8 +453,8 @@
 TEST_F(GlslGeneratorImplTest_Binary, ModVec3F16ScalarF16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("a", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.f16(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.vec3<f16>(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.f16(), type::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kModulo, Expr("a"), Expr("b"));
     WrapInFunction(expr);
@@ -467,8 +467,8 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, ModScalarF32Vec3F32) {
-    GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.f32(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.vec3<f32>(), type::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kModulo, Expr("a"), Expr("b"));
     WrapInFunction(expr);
@@ -483,8 +483,8 @@
 TEST_F(GlslGeneratorImplTest_Binary, ModScalarF16Vec3F16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("a", ty.f16(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.f16(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.vec3<f16>(), type::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kModulo, Expr("a"), Expr("b"));
     WrapInFunction(expr);
@@ -497,8 +497,8 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, ModMixedVec3ScalarF32) {
-    GlobalVar("a", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.vec3<f32>(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* expr_vec_mod_vec =
         create<ast::BinaryExpression>(ast::BinaryOp::kModulo, Expr("a"), Expr("a"));
@@ -541,8 +541,8 @@
 TEST_F(GlslGeneratorImplTest_Binary, ModMixedVec3ScalarF16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("a", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.f16(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.vec3<f16>(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.f16(), type::AddressSpace::kPrivate);
 
     auto* expr_vec_mod_vec =
         create<ast::BinaryExpression>(ast::BinaryOp::kModulo, Expr("a"), Expr("a"));
@@ -584,8 +584,8 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, Logical_And) {
-    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b"));
     WrapInFunction(expr);
@@ -604,10 +604,10 @@
 
 TEST_F(GlslGeneratorImplTest_Binary, Logical_Multi) {
     // (a && b) || (c || d)
-    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("c", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("d", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("c", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("d", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(
         ast::BinaryOp::kLogicalOr,
@@ -636,8 +636,8 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, Logical_Or) {
-    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, Expr("a"), Expr("b"));
     WrapInFunction(expr);
@@ -663,9 +663,9 @@
     //   return 3i;
     // }
 
-    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("c", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("c", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* expr =
         If(create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b")),
@@ -700,9 +700,9 @@
 TEST_F(GlslGeneratorImplTest_Binary, Return_WithLogical) {
     // return (a && b) || c;
 
-    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("c", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("c", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* expr = Return(create<ast::BinaryExpression>(
         ast::BinaryOp::kLogicalOr,
@@ -728,10 +728,10 @@
 TEST_F(GlslGeneratorImplTest_Binary, Assign_WithLogical) {
     // a = (b || c) && d;
 
-    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("c", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("d", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("c", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("d", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* expr =
         Assign(Expr("a"),
@@ -759,9 +759,9 @@
 TEST_F(GlslGeneratorImplTest_Binary, Decl_WithLogical) {
     // var a : bool = (b && c) || d;
 
-    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("c", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("d", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("c", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("d", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* var =
         Var("a", ty.bool_(),
@@ -798,10 +798,10 @@
              Param(Sym(), ty.bool_()),
          },
          ty.void_(), utils::Empty, utils::Empty);
-    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("c", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("d", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("c", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("d", ty.bool_(), type::AddressSpace::kPrivate);
 
     utils::Vector params{
         create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b")),
diff --git a/src/tint/writer/glsl/generator_impl_builtin_test.cc b/src/tint/writer/glsl/generator_impl_builtin_test.cc
index d4b7053..be9788b 100644
--- a/src/tint/writer/glsl/generator_impl_builtin_test.cc
+++ b/src/tint/writer/glsl/generator_impl_builtin_test.cc
@@ -198,19 +198,19 @@
     if (param.type == CallParamType::kF16) {
         Enable(ast::Extension::kF16);
 
-        GlobalVar("h2", ty.vec2<f16>(), ast::AddressSpace::kPrivate);
-        GlobalVar("h3", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
-        GlobalVar("hm2x2", ty.mat2x2<f16>(), ast::AddressSpace::kPrivate);
-        GlobalVar("hm3x2", ty.mat3x2<f16>(), ast::AddressSpace::kPrivate);
+        GlobalVar("h2", ty.vec2<f16>(), type::AddressSpace::kPrivate);
+        GlobalVar("h3", ty.vec3<f16>(), type::AddressSpace::kPrivate);
+        GlobalVar("hm2x2", ty.mat2x2<f16>(), type::AddressSpace::kPrivate);
+        GlobalVar("hm3x2", ty.mat3x2<f16>(), type::AddressSpace::kPrivate);
     }
 
-    GlobalVar("f2", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("f3", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("u2", ty.vec2<u32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("i2", ty.vec2<i32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("b2", ty.vec2<bool>(), ast::AddressSpace::kPrivate);
-    GlobalVar("m2x2", ty.mat2x2<f32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("m3x2", ty.mat3x2<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("f2", ty.vec2<f32>(), type::AddressSpace::kPrivate);
+    GlobalVar("f3", ty.vec3<f32>(), type::AddressSpace::kPrivate);
+    GlobalVar("u2", ty.vec2<u32>(), type::AddressSpace::kPrivate);
+    GlobalVar("i2", ty.vec2<i32>(), type::AddressSpace::kPrivate);
+    GlobalVar("b2", ty.vec2<bool>(), type::AddressSpace::kPrivate);
+    GlobalVar("m2x2", ty.mat2x2<f32>(), type::AddressSpace::kPrivate);
+    GlobalVar("m3x2", ty.mat3x2<f32>(), type::AddressSpace::kPrivate);
 
     auto* call = GenerateCall(param.builtin, param.type, this);
     ASSERT_NE(nullptr, call) << "Unhandled builtin";
@@ -342,8 +342,8 @@
 TEST_F(GlslGeneratorImplTest_Builtin, Builtin_Call) {
     auto* call = Call("dot", "param1", "param2");
 
-    GlobalVar("param1", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("param2", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("param1", ty.vec3<f32>(), type::AddressSpace::kPrivate);
+    GlobalVar("param2", ty.vec3<f32>(), type::AddressSpace::kPrivate);
 
     WrapInFunction(CallStmt(call));
 
@@ -356,8 +356,8 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Builtin, Select_Scalar) {
-    GlobalVar("a", Expr(1_f), ast::AddressSpace::kPrivate);
-    GlobalVar("b", Expr(2_f), ast::AddressSpace::kPrivate);
+    GlobalVar("a", Expr(1_f), type::AddressSpace::kPrivate);
+    GlobalVar("b", Expr(2_f), type::AddressSpace::kPrivate);
     auto* call = Call("select", "a", "b", true);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
@@ -369,8 +369,8 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Builtin, Select_Vector) {
-    GlobalVar("a", vec2<i32>(1_i, 2_i), ast::AddressSpace::kPrivate);
-    GlobalVar("b", vec2<i32>(3_i, 4_i), ast::AddressSpace::kPrivate);
+    GlobalVar("a", vec2<i32>(1_i, 2_i), type::AddressSpace::kPrivate);
+    GlobalVar("b", vec2<i32>(3_i, 4_i), type::AddressSpace::kPrivate);
     auto* call = Call("select", "a", "b", vec2<bool>(true, false));
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
@@ -384,9 +384,9 @@
 TEST_F(GlslGeneratorImplTest_Builtin, FMA_f32) {
     auto* call = Call("fma", "a", "b", "c");
 
-    GlobalVar("a", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("c", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.vec3<f32>(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.vec3<f32>(), type::AddressSpace::kPrivate);
+    GlobalVar("c", ty.vec3<f32>(), type::AddressSpace::kPrivate);
 
     WrapInFunction(CallStmt(call));
 
@@ -401,9 +401,9 @@
 TEST_F(GlslGeneratorImplTest_Builtin, FMA_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("a", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
-    GlobalVar("c", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.vec3<f16>(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.vec3<f16>(), type::AddressSpace::kPrivate);
+    GlobalVar("c", ty.vec3<f16>(), type::AddressSpace::kPrivate);
 
     auto* call = Call("fma", "a", "b", "c");
     WrapInFunction(CallStmt(call));
@@ -1247,7 +1247,7 @@
 
 TEST_F(GlslGeneratorImplTest_Builtin, Pack4x8Snorm) {
     auto* call = Call("pack4x8snorm", "p1");
-    GlobalVar("p1", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("p1", ty.vec4<f32>(), type::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1265,7 +1265,7 @@
 
 TEST_F(GlslGeneratorImplTest_Builtin, Pack4x8Unorm) {
     auto* call = Call("pack4x8unorm", "p1");
-    GlobalVar("p1", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("p1", ty.vec4<f32>(), type::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1283,7 +1283,7 @@
 
 TEST_F(GlslGeneratorImplTest_Builtin, Pack2x16Snorm) {
     auto* call = Call("pack2x16snorm", "p1");
-    GlobalVar("p1", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("p1", ty.vec2<f32>(), type::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1301,7 +1301,7 @@
 
 TEST_F(GlslGeneratorImplTest_Builtin, Pack2x16Unorm) {
     auto* call = Call("pack2x16unorm", "p1");
-    GlobalVar("p1", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("p1", ty.vec2<f32>(), type::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1319,7 +1319,7 @@
 
 TEST_F(GlslGeneratorImplTest_Builtin, Pack2x16Float) {
     auto* call = Call("pack2x16float", "p1");
-    GlobalVar("p1", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("p1", ty.vec2<f32>(), type::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1337,7 +1337,7 @@
 
 TEST_F(GlslGeneratorImplTest_Builtin, Unpack4x8Snorm) {
     auto* call = Call("unpack4x8snorm", "p1");
-    GlobalVar("p1", ty.u32(), ast::AddressSpace::kPrivate);
+    GlobalVar("p1", ty.u32(), type::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1355,7 +1355,7 @@
 
 TEST_F(GlslGeneratorImplTest_Builtin, Unpack4x8Unorm) {
     auto* call = Call("unpack4x8unorm", "p1");
-    GlobalVar("p1", ty.u32(), ast::AddressSpace::kPrivate);
+    GlobalVar("p1", ty.u32(), type::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1373,7 +1373,7 @@
 
 TEST_F(GlslGeneratorImplTest_Builtin, Unpack2x16Snorm) {
     auto* call = Call("unpack2x16snorm", "p1");
-    GlobalVar("p1", ty.u32(), ast::AddressSpace::kPrivate);
+    GlobalVar("p1", ty.u32(), type::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1391,7 +1391,7 @@
 
 TEST_F(GlslGeneratorImplTest_Builtin, Unpack2x16Unorm) {
     auto* call = Call("unpack2x16unorm", "p1");
-    GlobalVar("p1", ty.u32(), ast::AddressSpace::kPrivate);
+    GlobalVar("p1", ty.u32(), type::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1409,7 +1409,7 @@
 
 TEST_F(GlslGeneratorImplTest_Builtin, Unpack2x16Float) {
     auto* call = Call("unpack2x16float", "p1");
-    GlobalVar("p1", ty.u32(), ast::AddressSpace::kPrivate);
+    GlobalVar("p1", ty.u32(), type::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1472,7 +1472,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Builtin, DotI32) {
-    GlobalVar("v", ty.vec3<i32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("v", ty.vec3<i32>(), type::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(Call("dot", "v", "v")));
 
     GeneratorImpl& gen = SanitizeAndBuild();
@@ -1498,7 +1498,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Builtin, DotU32) {
-    GlobalVar("v", ty.vec3<u32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("v", ty.vec3<u32>(), type::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(Call("dot", "v", "v")));
 
     GeneratorImpl& gen = SanitizeAndBuild();
@@ -1524,7 +1524,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Builtin, QuantizeToF16_Scalar) {
-    GlobalVar("v", Expr(2_f), ast::AddressSpace::kPrivate);
+    GlobalVar("v", Expr(2_f), type::AddressSpace::kPrivate);
     WrapInFunction(Call("quantizeToF16", "v"));
 
     GeneratorImpl& gen = SanitizeAndBuild();
@@ -1551,7 +1551,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Builtin, QuantizeToF16_Vec2) {
-    GlobalVar("v", vec2<f32>(2_f), ast::AddressSpace::kPrivate);
+    GlobalVar("v", vec2<f32>(2_f), type::AddressSpace::kPrivate);
     WrapInFunction(Call("quantizeToF16", "v"));
 
     GeneratorImpl& gen = SanitizeAndBuild();
@@ -1578,7 +1578,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Builtin, QuantizeToF16_Vec3) {
-    GlobalVar("v", vec3<f32>(2_f), ast::AddressSpace::kPrivate);
+    GlobalVar("v", vec3<f32>(2_f), type::AddressSpace::kPrivate);
     WrapInFunction(Call("quantizeToF16", "v"));
 
     GeneratorImpl& gen = SanitizeAndBuild();
@@ -1607,7 +1607,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Builtin, QuantizeToF16_Vec4) {
-    GlobalVar("v", vec4<f32>(2_f), ast::AddressSpace::kPrivate);
+    GlobalVar("v", vec4<f32>(2_f), type::AddressSpace::kPrivate);
     WrapInFunction(Call("quantizeToF16", "v"));
 
     GeneratorImpl& gen = SanitizeAndBuild();
diff --git a/src/tint/writer/glsl/generator_impl_call_test.cc b/src/tint/writer/glsl/generator_impl_call_test.cc
index adf66d3..4ea3790 100644
--- a/src/tint/writer/glsl/generator_impl_call_test.cc
+++ b/src/tint/writer/glsl/generator_impl_call_test.cc
@@ -42,8 +42,8 @@
              Param(Sym(), ty.f32()),
          },
          ty.f32(), utils::Vector{Return(1.23_f)});
-    GlobalVar("param1", ty.f32(), ast::AddressSpace::kPrivate);
-    GlobalVar("param2", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("param1", ty.f32(), type::AddressSpace::kPrivate);
+    GlobalVar("param2", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* call = Call("my_func", "param1", "param2");
     WrapInFunction(call);
@@ -62,8 +62,8 @@
              Param(Sym(), ty.f32()),
          },
          ty.void_(), utils::Empty, utils::Empty);
-    GlobalVar("param1", ty.f32(), ast::AddressSpace::kPrivate);
-    GlobalVar("param2", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("param1", ty.f32(), type::AddressSpace::kPrivate);
+    GlobalVar("param2", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* call = CallStmt(Call("my_func", "param1", "param2"));
     WrapInFunction(call);
diff --git a/src/tint/writer/glsl/generator_impl_function_test.cc b/src/tint/writer/glsl/generator_impl_function_test.cc
index 0cb72ee..3c3dd53 100644
--- a/src/tint/writer/glsl/generator_impl_function_test.cc
+++ b/src/tint/writer/glsl/generator_impl_function_test.cc
@@ -110,7 +110,7 @@
     // fn f(foo : ptr<function, f32>) -> f32 {
     //   return *foo;
     // }
-    Func("f", utils::Vector{Param("foo", ty.pointer<f32>(ast::AddressSpace::kFunction))}, ty.f32(),
+    Func("f", utils::Vector{Param("foo", ty.pointer<f32>(type::AddressSpace::kFunction))}, ty.f32(),
          utils::Vector{Return(Deref("foo"))});
 
     GeneratorImpl& gen = SanitizeAndBuild();
@@ -352,7 +352,7 @@
 TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_Uniform) {
     auto* ubo_ty = Structure("UBO", utils::Vector{Member("coord", ty.vec4<f32>())});
     auto* ubo =
-        GlobalVar("ubo", ty.Of(ubo_ty), ast::AddressSpace::kUniform, Binding(0_a), Group(1_a));
+        GlobalVar("ubo", ty.Of(ubo_ty), type::AddressSpace::kUniform, Binding(0_a), Group(1_a));
 
     Func("sub_func",
          utils::Vector{
@@ -402,7 +402,7 @@
 TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_UniformStruct) {
     auto* s = Structure("Uniforms", utils::Vector{Member("coord", ty.vec4<f32>())});
 
-    GlobalVar("uniforms", ty.Of(s), ast::AddressSpace::kUniform, Binding(0_a), Group(1_a));
+    GlobalVar("uniforms", ty.Of(s), type::AddressSpace::kUniform, Binding(0_a), Group(1_a));
 
     auto* var = Var("v", ty.f32(), MemberAccessor(MemberAccessor("uniforms", "coord"), "x"));
 
@@ -442,8 +442,8 @@
                                     Member("b", ty.f32()),
                                 });
 
-    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(0_a),
-              Group(1_a));
+    GlobalVar("coord", ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite,
+              Binding(0_a), Group(1_a));
 
     auto* var = Var("v", ty.f32(), MemberAccessor("coord", "b"));
 
@@ -489,7 +489,7 @@
                                     Member("b", ty.f32()),
                                 });
 
-    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("coord", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(0_a),
               Group(1_a));
 
     auto* var = Var("v", ty.f32(), MemberAccessor("coord", "b"));
@@ -537,8 +537,8 @@
                                     Member("b", ty.f32()),
                                 });
 
-    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(0_a),
-              Group(1_a));
+    GlobalVar("coord", ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite,
+              Binding(0_a), Group(1_a));
 
     Func("frag_main", utils::Empty, ty.void_(),
          utils::Vector{
@@ -582,8 +582,8 @@
                                     Member("b", ty.f32()),
                                 });
 
-    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(0_a),
-              Group(1_a));
+    GlobalVar("coord", ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite,
+              Binding(0_a), Group(1_a));
 
     Func("frag_main", utils::Empty, ty.void_(),
          utils::Vector{
@@ -623,7 +623,7 @@
 
 TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_Called_By_EntryPoint_With_Uniform) {
     auto* s = Structure("S", utils::Vector{Member("x", ty.f32())});
-    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kUniform, Binding(0_a), Group(1_a));
+    GlobalVar("coord", ty.Of(s), type::AddressSpace::kUniform, Binding(0_a), Group(1_a));
 
     Func("sub_func", utils::Vector{Param("param", ty.f32())}, ty.f32(),
          utils::Vector{
@@ -668,8 +668,8 @@
 
 TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_Called_By_EntryPoint_With_StorageBuffer) {
     auto* s = Structure("S", utils::Vector{Member("x", ty.f32())});
-    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(0_a),
-              Group(1_a));
+    GlobalVar("coord", ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite,
+              Binding(0_a), Group(1_a));
 
     Func("sub_func", utils::Vector{Param("param", ty.f32())}, ty.f32(),
          utils::Vector{
@@ -879,8 +879,8 @@
 
     auto* s = Structure("Data", utils::Vector{Member("d", ty.f32())});
 
-    GlobalVar("data", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(0_a),
-              Group(0_a));
+    GlobalVar("data", ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite,
+              Binding(0_a), Group(0_a));
 
     {
         auto* var = Var("v", ty.f32(), MemberAccessor("data", "d"));
diff --git a/src/tint/writer/glsl/generator_impl_identifier_test.cc b/src/tint/writer/glsl/generator_impl_identifier_test.cc
index 76835c1..7e528ac 100644
--- a/src/tint/writer/glsl/generator_impl_identifier_test.cc
+++ b/src/tint/writer/glsl/generator_impl_identifier_test.cc
@@ -20,7 +20,7 @@
 using GlslGeneratorImplTest_Identifier = TestHelper;
 
 TEST_F(GlslGeneratorImplTest_Identifier, EmitIdentifierExpression) {
-    GlobalVar("foo", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("foo", ty.i32(), type::AddressSpace::kPrivate);
 
     auto* i = Expr("foo");
     WrapInFunction(i);
diff --git a/src/tint/writer/glsl/generator_impl_if_test.cc b/src/tint/writer/glsl/generator_impl_if_test.cc
index d2368aa..a0957e1 100644
--- a/src/tint/writer/glsl/generator_impl_if_test.cc
+++ b/src/tint/writer/glsl/generator_impl_if_test.cc
@@ -20,7 +20,7 @@
 using GlslGeneratorImplTest_If = TestHelper;
 
 TEST_F(GlslGeneratorImplTest_If, Emit_If) {
-    GlobalVar("cond", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("cond", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* cond = Expr("cond");
     auto* body = Block(Return());
@@ -38,8 +38,8 @@
 }
 
 TEST_F(GlslGeneratorImplTest_If, Emit_IfWithElseIf) {
-    GlobalVar("cond", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("else_cond", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("cond", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("else_cond", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* else_cond = Expr("else_cond");
     auto* else_body = Block(Return());
@@ -65,7 +65,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_If, Emit_IfWithElse) {
-    GlobalVar("cond", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("cond", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* else_body = Block(Return());
 
@@ -88,8 +88,8 @@
 }
 
 TEST_F(GlslGeneratorImplTest_If, Emit_IfWithMultiple) {
-    GlobalVar("cond", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("else_cond", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("cond", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("else_cond", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* else_cond = Expr("else_cond");
 
diff --git a/src/tint/writer/glsl/generator_impl_import_test.cc b/src/tint/writer/glsl/generator_impl_import_test.cc
index d21d6db..54c2405 100644
--- a/src/tint/writer/glsl/generator_impl_import_test.cc
+++ b/src/tint/writer/glsl/generator_impl_import_test.cc
@@ -253,7 +253,7 @@
                          testing::Values(GlslImportData{"clamp", "clamp"}));
 
 TEST_F(GlslGeneratorImplTest_Import, GlslImportData_Determinant) {
-    GlobalVar("var", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("var", ty.mat3x3<f32>(), type::AddressSpace::kPrivate);
 
     auto* expr = Call("determinant", "var");
     WrapInFunction(expr);
diff --git a/src/tint/writer/glsl/generator_impl_loop_test.cc b/src/tint/writer/glsl/generator_impl_loop_test.cc
index 53e26f6..79374a2 100644
--- a/src/tint/writer/glsl/generator_impl_loop_test.cc
+++ b/src/tint/writer/glsl/generator_impl_loop_test.cc
@@ -93,8 +93,8 @@
 TEST_F(GlslGeneratorImplTest_Loop, Emit_LoopNestedWithContinuing) {
     Func("a_statement", {}, ty.void_(), {});
 
-    GlobalVar("lhs", ty.f32(), ast::AddressSpace::kPrivate);
-    GlobalVar("rhs", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("lhs", ty.f32(), type::AddressSpace::kPrivate);
+    GlobalVar("rhs", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* body = Block(Break());
     auto* continuing = Block(CallStmt(Call("a_statement")));
@@ -142,7 +142,7 @@
     //   }
     // }
 
-    GlobalVar("rhs", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("rhs", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* body = Block(Decl(Var("lhs", ty.f32(), Expr(2.4_f))),  //
                        Decl(Var("other", ty.f32())),             //
diff --git a/src/tint/writer/glsl/generator_impl_member_accessor_test.cc b/src/tint/writer/glsl/generator_impl_member_accessor_test.cc
index a906390..e062630 100644
--- a/src/tint/writer/glsl/generator_impl_member_accessor_test.cc
+++ b/src/tint/writer/glsl/generator_impl_member_accessor_test.cc
@@ -91,7 +91,7 @@
 
         auto* s = b.Structure("Data", members);
 
-        b.GlobalVar("data", b.ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite,
+        b.GlobalVar("data", b.ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite,
                     b.Group(1_a), b.Binding(0_a));
     }
 
@@ -112,7 +112,7 @@
 
 TEST_F(GlslGeneratorImplTest_MemberAccessor, EmitExpression_MemberAccessor) {
     auto* s = Structure("Data", utils::Vector{Member("mem", ty.f32())});
-    GlobalVar("str", ty.Of(s), ast::AddressSpace::kPrivate);
+    GlobalVar("str", ty.Of(s), type::AddressSpace::kPrivate);
 
     auto* expr = MemberAccessor("str", "mem");
     WrapInFunction(Var("expr", ty.f32(), expr));
diff --git a/src/tint/writer/glsl/generator_impl_sanitizer_test.cc b/src/tint/writer/glsl/generator_impl_sanitizer_test.cc
index 6bcca21..3bb3e13 100644
--- a/src/tint/writer/glsl/generator_impl_sanitizer_test.cc
+++ b/src/tint/writer/glsl/generator_impl_sanitizer_test.cc
@@ -26,7 +26,7 @@
 
 TEST_F(GlslSanitizerTest, Call_ArrayLength) {
     auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
-    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(1_a),
               Group(2_a));
 
     Func("a_func", utils::Empty, ty.void_(),
@@ -66,7 +66,7 @@
                                          Member(0, "z", ty.f32()),
                                          Member(4, "a", ty.array<f32>(4)),
                                      });
-    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(1_a),
               Group(2_a));
 
     Func("a_func", utils::Empty, ty.void_(),
@@ -105,7 +105,7 @@
 
 TEST_F(GlslSanitizerTest, Call_ArrayLength_ViaLets) {
     auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
-    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(1_a),
               Group(2_a));
 
     auto* p = Let("p", AddressOf("b"));
@@ -233,7 +233,7 @@
     // let p : ptr<function, i32> = &v;
     // let x : i32 = *p;
     auto* v = Var("v", ty.i32());
-    auto* p = Let("p", ty.pointer<i32>(ast::AddressSpace::kFunction), AddressOf(v));
+    auto* p = Let("p", ty.pointer<i32>(type::AddressSpace::kFunction), AddressOf(v));
     auto* x = Var("x", ty.i32(), Deref(p));
 
     Func("main", utils::Empty, ty.void_(),
@@ -274,11 +274,11 @@
     // let vp : ptr<function, vec4<f32>> = &(*mp)[2i];
     // let v : vec4<f32> = *vp;
     auto* a = Var("a", ty.array(ty.mat4x4<f32>(), 4_u));
-    auto* ap = Let("ap", ty.pointer(ty.array(ty.mat4x4<f32>(), 4_u), ast::AddressSpace::kFunction),
+    auto* ap = Let("ap", ty.pointer(ty.array(ty.mat4x4<f32>(), 4_u), type::AddressSpace::kFunction),
                    AddressOf(a));
-    auto* mp = Let("mp", ty.pointer(ty.mat4x4<f32>(), ast::AddressSpace::kFunction),
+    auto* mp = Let("mp", ty.pointer(ty.mat4x4<f32>(), type::AddressSpace::kFunction),
                    AddressOf(IndexAccessor(Deref(ap), 3_i)));
-    auto* vp = Let("vp", ty.pointer(ty.vec4<f32>(), ast::AddressSpace::kFunction),
+    auto* vp = Let("vp", ty.pointer(ty.vec4<f32>(), type::AddressSpace::kFunction),
                    AddressOf(IndexAccessor(Deref(mp), 2_i)));
     auto* v = Var("v", ty.vec4<f32>(), Deref(vp));
 
diff --git a/src/tint/writer/glsl/generator_impl_storage_buffer_test.cc b/src/tint/writer/glsl/generator_impl_storage_buffer_test.cc
index 59ae98e..3572da4 100644
--- a/src/tint/writer/glsl/generator_impl_storage_buffer_test.cc
+++ b/src/tint/writer/glsl/generator_impl_storage_buffer_test.cc
@@ -37,7 +37,7 @@
                        ctx->Member("dewey", ctx->ty.f32(), utils::Vector{ctx->MemberAlign(256_i)}),
                        ctx->Member("louie", ctx->ty.f32(), utils::Vector{ctx->MemberAlign(256_i)}),
                    });
-    ctx->GlobalVar("nephews", ctx->ty.Of(nephews), ast::AddressSpace::kStorage, ctx->Binding(0_a),
+    ctx->GlobalVar("nephews", ctx->ty.Of(nephews), type::AddressSpace::kStorage, ctx->Binding(0_a),
                    ctx->Group(0_a));
 }
 
diff --git a/src/tint/writer/glsl/generator_impl_switch_test.cc b/src/tint/writer/glsl/generator_impl_switch_test.cc
index ada3c0b..2f90c8f 100644
--- a/src/tint/writer/glsl/generator_impl_switch_test.cc
+++ b/src/tint/writer/glsl/generator_impl_switch_test.cc
@@ -22,7 +22,7 @@
 using GlslGeneratorImplTest_Switch = TestHelper;
 
 TEST_F(GlslGeneratorImplTest_Switch, Emit_Switch) {
-    GlobalVar("cond", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("cond", ty.i32(), type::AddressSpace::kPrivate);
 
     auto* def_body = Block(create<ast::BreakStatement>());
     auto* def = create<ast::CaseStatement>(utils::Vector{DefaultCaseSelector()}, def_body);
@@ -51,7 +51,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Switch, Emit_Switch_MixedDefault) {
-    GlobalVar("cond", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("cond", ty.i32(), type::AddressSpace::kPrivate);
 
     auto* def_body = Block(create<ast::BreakStatement>());
     auto* def = create<ast::CaseStatement>(utils::Vector{CaseSelector(5_i), DefaultCaseSelector()},
diff --git a/src/tint/writer/glsl/generator_impl_test.cc b/src/tint/writer/glsl/generator_impl_test.cc
index c06b53e..abb391f 100644
--- a/src/tint/writer/glsl/generator_impl_test.cc
+++ b/src/tint/writer/glsl/generator_impl_test.cc
@@ -62,7 +62,7 @@
                   Builtin(ast::BuiltinValue::kSampleIndex),
                   Disable(ast::DisabledValidation::kIgnoreAddressSpace),
               },
-              ast::AddressSpace::kIn);
+              type::AddressSpace::kIn);
     Func("my_func", utils::Empty, ty.i32(),
          utils::Vector{
              Return(Expr("gl_SampleID")),
@@ -87,7 +87,7 @@
                   Builtin(ast::BuiltinValue::kSampleIndex),
                   Disable(ast::DisabledValidation::kIgnoreAddressSpace),
               },
-              ast::AddressSpace::kIn);
+              type::AddressSpace::kIn);
     Func("my_func", utils::Empty, ty.i32(),
          utils::Vector{
              Return(Expr("gl_SampleID")),
diff --git a/src/tint/writer/glsl/generator_impl_type_test.cc b/src/tint/writer/glsl/generator_impl_type_test.cc
index 9212dbf..fe4c0ab 100644
--- a/src/tint/writer/glsl/generator_impl_type_test.cc
+++ b/src/tint/writer/glsl/generator_impl_type_test.cc
@@ -20,6 +20,7 @@
 #include "src/tint/type/sampled_texture.h"
 #include "src/tint/type/sampler.h"
 #include "src/tint/type/storage_texture.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/writer/glsl/test_helper.h"
 
 using ::testing::HasSubstr;
@@ -33,52 +34,52 @@
 
 TEST_F(GlslGeneratorImplTest_Type, EmitType_Array) {
     auto* arr = ty.array<bool, 4>();
-    GlobalVar("G", arr, ast::AddressSpace::kPrivate);
+    GlobalVar("G", arr, type::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), ast::AddressSpace::kNone,
-                             ast::Access::kReadWrite, "ary"))
+    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), type::AddressSpace::kNone,
+                             type::Access::kReadWrite, "ary"))
         << gen.error();
     EXPECT_EQ(out.str(), "bool ary[4]");
 }
 
 TEST_F(GlslGeneratorImplTest_Type, EmitType_ArrayOfArray) {
     auto* arr = ty.array(ty.array<bool, 4>(), 5_u);
-    GlobalVar("G", arr, ast::AddressSpace::kPrivate);
+    GlobalVar("G", arr, type::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), ast::AddressSpace::kNone,
-                             ast::Access::kReadWrite, "ary"))
+    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), type::AddressSpace::kNone,
+                             type::Access::kReadWrite, "ary"))
         << gen.error();
     EXPECT_EQ(out.str(), "bool ary[5][4]");
 }
 
 TEST_F(GlslGeneratorImplTest_Type, EmitType_ArrayOfArrayOfArray) {
     auto* arr = ty.array(ty.array(ty.array<bool, 4>(), 5_u), 6_u);
-    GlobalVar("G", arr, ast::AddressSpace::kPrivate);
+    GlobalVar("G", arr, type::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), ast::AddressSpace::kNone,
-                             ast::Access::kReadWrite, "ary"))
+    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), type::AddressSpace::kNone,
+                             type::Access::kReadWrite, "ary"))
         << gen.error();
     EXPECT_EQ(out.str(), "bool ary[6][5][4]");
 }
 
 TEST_F(GlslGeneratorImplTest_Type, EmitType_Array_WithoutName) {
     auto* arr = ty.array<bool, 4>();
-    GlobalVar("G", arr, ast::AddressSpace::kPrivate);
+    GlobalVar("G", arr, type::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), ast::AddressSpace::kNone,
-                             ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), type::AddressSpace::kNone,
+                             type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "bool[4]");
 }
@@ -89,7 +90,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, bool_, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, bool_, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "bool");
 }
@@ -100,7 +101,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, f32, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, f32, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "float");
 }
@@ -113,7 +114,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, f16, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, f16, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "float16_t");
 }
@@ -124,7 +125,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, i32, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, i32, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "int");
 }
@@ -137,7 +138,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, mat2x3, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, mat2x3, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "mat2x3");
 }
@@ -152,7 +153,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, mat2x3, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, mat2x3, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "f16mat2x3");
 }
@@ -162,7 +163,7 @@
                                  Member("a", ty.i32()),
                                  Member("b", ty.f32()),
                              });
-    GlobalVar("g", ty.Of(s), ast::AddressSpace::kPrivate);
+    GlobalVar("g", ty.Of(s), type::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
@@ -182,13 +183,13 @@
                                  Member("a", ty.i32()),
                                  Member("b", ty.f32()),
                              });
-    GlobalVar("g", ty.Of(s), ast::AddressSpace::kPrivate);
+    GlobalVar("g", ty.Of(s), type::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
     auto* sem_s = program->TypeOf(s)->As<sem::Struct>();
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, sem_s, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, sem_s, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "S");
 }
@@ -198,7 +199,7 @@
                                  Member("double", ty.i32()),
                                  Member("float", ty.f32()),
                              });
-    GlobalVar("g", ty.Of(s), ast::AddressSpace::kPrivate);
+    GlobalVar("g", ty.Of(s), type::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = SanitizeAndBuild();
 
@@ -215,7 +216,7 @@
                                  Member("a", ty.i32(), utils::Vector{MemberOffset(0_a)}),
                                  Member("b", ty.f32(), utils::Vector{MemberOffset(8_a)}),
                              });
-    GlobalVar("g", ty.Of(s), ast::AddressSpace::kPrivate);
+    GlobalVar("g", ty.Of(s), type::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
@@ -236,7 +237,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, u32, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, u32, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "uint");
 }
@@ -248,7 +249,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, vec3, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, vec3, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "vec3");
 }
@@ -262,7 +263,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, vec3, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, vec3, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "f16vec3");
 }
@@ -273,7 +274,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, void_, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, void_, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "void");
 }
@@ -284,7 +285,8 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_FALSE(gen.EmitType(out, sampler, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_FALSE(
+        gen.EmitType(out, sampler, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
 }
 
@@ -294,12 +296,13 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_FALSE(gen.EmitType(out, sampler, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_FALSE(
+        gen.EmitType(out, sampler, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
 }
 
 struct GlslDepthTextureData {
-    ast::TextureDimension dim;
+    type::TextureDimension dim;
     std::string result;
 };
 inline std::ostream& operator<<(std::ostream& out, GlslDepthTextureData data) {
@@ -331,14 +334,14 @@
     GlslGeneratorImplTest_Type,
     GlslDepthTexturesTest,
     testing::Values(
-        GlslDepthTextureData{ast::TextureDimension::k2d, "sampler2DShadow tex;"},
-        GlslDepthTextureData{ast::TextureDimension::k2dArray, "sampler2DArrayShadow tex;"},
-        GlslDepthTextureData{ast::TextureDimension::kCube, "samplerCubeShadow tex;"},
-        GlslDepthTextureData{ast::TextureDimension::kCubeArray, "samplerCubeArrayShadow tex;"}));
+        GlslDepthTextureData{type::TextureDimension::k2d, "sampler2DShadow tex;"},
+        GlslDepthTextureData{type::TextureDimension::k2dArray, "sampler2DArrayShadow tex;"},
+        GlslDepthTextureData{type::TextureDimension::kCube, "samplerCubeShadow tex;"},
+        GlslDepthTextureData{type::TextureDimension::kCubeArray, "samplerCubeArrayShadow tex;"}));
 
 using GlslDepthMultisampledTexturesTest = TestHelper;
 TEST_F(GlslDepthMultisampledTexturesTest, Emit) {
-    auto* t = ty.depth_multisampled_texture(ast::TextureDimension::k2d);
+    auto* t = ty.depth_multisampled_texture(type::TextureDimension::k2d);
 
     GlobalVar("tex", t, Binding(1_a), Group(2_a));
 
@@ -358,7 +361,7 @@
 
 enum class TextureDataType { F32, U32, I32 };
 struct GlslSampledTextureData {
-    ast::TextureDimension dim;
+    type::TextureDimension dim;
     TextureDataType datatype;
     std::string result;
 };
@@ -403,111 +406,111 @@
                          GlslSampledTexturesTest,
                          testing::Values(
                              GlslSampledTextureData{
-                                 ast::TextureDimension::k1d,
+                                 type::TextureDimension::k1d,
                                  TextureDataType::F32,
                                  "sampler1D tex;",
                              },
                              GlslSampledTextureData{
-                                 ast::TextureDimension::k2d,
+                                 type::TextureDimension::k2d,
                                  TextureDataType::F32,
                                  "sampler2D tex;",
                              },
                              GlslSampledTextureData{
-                                 ast::TextureDimension::k2dArray,
+                                 type::TextureDimension::k2dArray,
                                  TextureDataType::F32,
                                  "sampler2DArray tex;",
                              },
                              GlslSampledTextureData{
-                                 ast::TextureDimension::k3d,
+                                 type::TextureDimension::k3d,
                                  TextureDataType::F32,
                                  "sampler3D tex;",
                              },
                              GlslSampledTextureData{
-                                 ast::TextureDimension::kCube,
+                                 type::TextureDimension::kCube,
                                  TextureDataType::F32,
                                  "samplerCube tex;",
                              },
                              GlslSampledTextureData{
-                                 ast::TextureDimension::kCubeArray,
+                                 type::TextureDimension::kCubeArray,
                                  TextureDataType::F32,
                                  "samplerCubeArray tex;",
                              },
                              GlslSampledTextureData{
-                                 ast::TextureDimension::k1d,
+                                 type::TextureDimension::k1d,
                                  TextureDataType::U32,
                                  "usampler1D tex;",
                              },
                              GlslSampledTextureData{
-                                 ast::TextureDimension::k2d,
+                                 type::TextureDimension::k2d,
                                  TextureDataType::U32,
                                  "usampler2D tex;",
                              },
                              GlslSampledTextureData{
-                                 ast::TextureDimension::k2dArray,
+                                 type::TextureDimension::k2dArray,
                                  TextureDataType::U32,
                                  "usampler2DArray tex;",
                              },
                              GlslSampledTextureData{
-                                 ast::TextureDimension::k3d,
+                                 type::TextureDimension::k3d,
                                  TextureDataType::U32,
                                  "usampler3D tex;",
                              },
                              GlslSampledTextureData{
-                                 ast::TextureDimension::kCube,
+                                 type::TextureDimension::kCube,
                                  TextureDataType::U32,
                                  "usamplerCube tex;",
                              },
                              GlslSampledTextureData{
-                                 ast::TextureDimension::kCubeArray,
+                                 type::TextureDimension::kCubeArray,
                                  TextureDataType::U32,
                                  "usamplerCubeArray tex;",
                              },
                              GlslSampledTextureData{
-                                 ast::TextureDimension::k1d,
+                                 type::TextureDimension::k1d,
                                  TextureDataType::I32,
                                  "isampler1D tex;",
                              },
                              GlslSampledTextureData{
-                                 ast::TextureDimension::k2d,
+                                 type::TextureDimension::k2d,
                                  TextureDataType::I32,
                                  "isampler2D tex;",
                              },
                              GlslSampledTextureData{
-                                 ast::TextureDimension::k2dArray,
+                                 type::TextureDimension::k2dArray,
                                  TextureDataType::I32,
                                  "isampler2DArray tex;",
                              },
                              GlslSampledTextureData{
-                                 ast::TextureDimension::k3d,
+                                 type::TextureDimension::k3d,
                                  TextureDataType::I32,
                                  "isampler3D tex;",
                              },
                              GlslSampledTextureData{
-                                 ast::TextureDimension::kCube,
+                                 type::TextureDimension::kCube,
                                  TextureDataType::I32,
                                  "isamplerCube tex;",
                              },
                              GlslSampledTextureData{
-                                 ast::TextureDimension::kCubeArray,
+                                 type::TextureDimension::kCubeArray,
                                  TextureDataType::I32,
                                  "isamplerCubeArray tex;",
                              }));
 
 TEST_F(GlslGeneratorImplTest_Type, EmitMultisampledTexture) {
     auto* f32 = create<type::F32>();
-    auto* s = create<type::MultisampledTexture>(ast::TextureDimension::k2d, f32);
+    auto* s = create<type::MultisampledTexture>(type::TextureDimension::k2d, f32);
 
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, s, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, s, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "highp sampler2DMS");
 }
 
 struct GlslStorageTextureData {
-    ast::TextureDimension dim;
-    ast::TexelFormat imgfmt;
+    type::TextureDimension dim;
+    type::TexelFormat imgfmt;
     std::string result;
 };
 inline std::ostream& operator<<(std::ostream& out, GlslStorageTextureData data) {
@@ -517,7 +520,7 @@
 TEST_P(GlslStorageTexturesTest, Emit) {
     auto params = GetParam();
 
-    auto* t = ty.storage_texture(params.dim, params.imgfmt, ast::Access::kWrite);
+    auto* t = ty.storage_texture(params.dim, params.imgfmt, type::Access::kWrite);
 
     GlobalVar("tex", t, Binding(1_a), Group(2_a));
 
@@ -537,32 +540,32 @@
 INSTANTIATE_TEST_SUITE_P(
     GlslGeneratorImplTest_Type,
     GlslStorageTexturesTest,
-    testing::Values(GlslStorageTextureData{ast::TextureDimension::k1d,
-                                           ast::TexelFormat::kRgba8Unorm, "image1D tex;"},
-                    GlslStorageTextureData{ast::TextureDimension::k2d,
-                                           ast::TexelFormat::kRgba16Float, "image2D tex;"},
-                    GlslStorageTextureData{ast::TextureDimension::k2dArray,
-                                           ast::TexelFormat::kR32Float, "image2DArray tex;"},
-                    GlslStorageTextureData{ast::TextureDimension::k3d, ast::TexelFormat::kRg32Float,
-                                           "image3D tex;"},
-                    GlslStorageTextureData{ast::TextureDimension::k1d,
-                                           ast::TexelFormat::kRgba32Float, "image1D tex;"},
-                    GlslStorageTextureData{ast::TextureDimension::k2d,
-                                           ast::TexelFormat::kRgba16Uint, "image2D tex;"},
-                    GlslStorageTextureData{ast::TextureDimension::k2dArray,
-                                           ast::TexelFormat::kR32Uint, "image2DArray tex;"},
-                    GlslStorageTextureData{ast::TextureDimension::k3d, ast::TexelFormat::kRg32Uint,
-                                           "image3D tex;"},
-                    GlslStorageTextureData{ast::TextureDimension::k1d,
-                                           ast::TexelFormat::kRgba32Uint, "image1D tex;"},
-                    GlslStorageTextureData{ast::TextureDimension::k2d,
-                                           ast::TexelFormat::kRgba16Sint, "image2D tex;"},
-                    GlslStorageTextureData{ast::TextureDimension::k2dArray,
-                                           ast::TexelFormat::kR32Sint, "image2DArray tex;"},
-                    GlslStorageTextureData{ast::TextureDimension::k3d, ast::TexelFormat::kRg32Sint,
-                                           "image3D tex;"},
-                    GlslStorageTextureData{ast::TextureDimension::k1d,
-                                           ast::TexelFormat::kRgba32Sint, "image1D tex;"}));
+    testing::Values(GlslStorageTextureData{type::TextureDimension::k1d,
+                                           type::TexelFormat::kRgba8Unorm, "image1D tex;"},
+                    GlslStorageTextureData{type::TextureDimension::k2d,
+                                           type::TexelFormat::kRgba16Float, "image2D tex;"},
+                    GlslStorageTextureData{type::TextureDimension::k2dArray,
+                                           type::TexelFormat::kR32Float, "image2DArray tex;"},
+                    GlslStorageTextureData{type::TextureDimension::k3d,
+                                           type::TexelFormat::kRg32Float, "image3D tex;"},
+                    GlslStorageTextureData{type::TextureDimension::k1d,
+                                           type::TexelFormat::kRgba32Float, "image1D tex;"},
+                    GlslStorageTextureData{type::TextureDimension::k2d,
+                                           type::TexelFormat::kRgba16Uint, "image2D tex;"},
+                    GlslStorageTextureData{type::TextureDimension::k2dArray,
+                                           type::TexelFormat::kR32Uint, "image2DArray tex;"},
+                    GlslStorageTextureData{type::TextureDimension::k3d,
+                                           type::TexelFormat::kRg32Uint, "image3D tex;"},
+                    GlslStorageTextureData{type::TextureDimension::k1d,
+                                           type::TexelFormat::kRgba32Uint, "image1D tex;"},
+                    GlslStorageTextureData{type::TextureDimension::k2d,
+                                           type::TexelFormat::kRgba16Sint, "image2D tex;"},
+                    GlslStorageTextureData{type::TextureDimension::k2dArray,
+                                           type::TexelFormat::kR32Sint, "image2DArray tex;"},
+                    GlslStorageTextureData{type::TextureDimension::k3d,
+                                           type::TexelFormat::kRg32Sint, "image3D tex;"},
+                    GlslStorageTextureData{type::TextureDimension::k1d,
+                                           type::TexelFormat::kRgba32Sint, "image1D tex;"}));
 
 }  // namespace
 }  // namespace tint::writer::glsl
diff --git a/src/tint/writer/glsl/generator_impl_unary_op_test.cc b/src/tint/writer/glsl/generator_impl_unary_op_test.cc
index ac54b4e..c0eb7b1 100644
--- a/src/tint/writer/glsl/generator_impl_unary_op_test.cc
+++ b/src/tint/writer/glsl/generator_impl_unary_op_test.cc
@@ -20,7 +20,7 @@
 using GlslUnaryOpTest = TestHelper;
 
 TEST_F(GlslUnaryOpTest, AddressOf) {
-    GlobalVar("expr", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("expr", ty.f32(), type::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kAddressOf, Expr("expr"));
     WrapInFunction(op);
 
@@ -32,7 +32,7 @@
 }
 
 TEST_F(GlslUnaryOpTest, Complement) {
-    GlobalVar("expr", ty.u32(), ast::AddressSpace::kPrivate);
+    GlobalVar("expr", ty.u32(), type::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kComplement, Expr("expr"));
     WrapInFunction(op);
 
@@ -44,7 +44,7 @@
 }
 
 TEST_F(GlslUnaryOpTest, Indirection) {
-    GlobalVar("G", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("G", ty.f32(), type::AddressSpace::kPrivate);
     auto* p = Let("expr", create<ast::UnaryOpExpression>(ast::UnaryOp::kAddressOf, Expr("G")));
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kIndirection, Expr("expr"));
     WrapInFunction(p, op);
@@ -57,7 +57,7 @@
 }
 
 TEST_F(GlslUnaryOpTest, Not) {
-    GlobalVar("expr", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("expr", ty.bool_(), type::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kNot, Expr("expr"));
     WrapInFunction(op);
 
@@ -69,7 +69,7 @@
 }
 
 TEST_F(GlslUnaryOpTest, Negation) {
-    GlobalVar("expr", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("expr", ty.i32(), type::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kNegation, Expr("expr"));
     WrapInFunction(op);
 
diff --git a/src/tint/writer/glsl/generator_impl_uniform_buffer_test.cc b/src/tint/writer/glsl/generator_impl_uniform_buffer_test.cc
index 35b1407..48f635a 100644
--- a/src/tint/writer/glsl/generator_impl_uniform_buffer_test.cc
+++ b/src/tint/writer/glsl/generator_impl_uniform_buffer_test.cc
@@ -26,7 +26,7 @@
 
 TEST_F(GlslGeneratorImplTest_UniformBuffer, Simple) {
     auto* simple = Structure("Simple", utils::Vector{Member("member", ty.f32())});
-    GlobalVar("simple", ty.Of(simple), ast::AddressSpace::kUniform, Group(0_a), Binding(0_a));
+    GlobalVar("simple", ty.Of(simple), type::AddressSpace::kUniform, Group(0_a), Binding(0_a));
 
     GeneratorImpl& gen = Build();
 
@@ -46,7 +46,7 @@
 
 TEST_F(GlslGeneratorImplTest_UniformBuffer, Simple_Desktop) {
     auto* simple = Structure("Simple", utils::Vector{Member("member", ty.f32())});
-    GlobalVar("simple", ty.Of(simple), ast::AddressSpace::kUniform, Group(0_a), Binding(0_a));
+    GlobalVar("simple", ty.Of(simple), type::AddressSpace::kUniform, Group(0_a), Binding(0_a));
 
     GeneratorImpl& gen = Build(Version(Version::Standard::kDesktop, 4, 4));
 
diff --git a/src/tint/writer/glsl/generator_impl_variable_decl_statement_test.cc b/src/tint/writer/glsl/generator_impl_variable_decl_statement_test.cc
index 650e2b4..2cbea95 100644
--- a/src/tint/writer/glsl/generator_impl_variable_decl_statement_test.cc
+++ b/src/tint/writer/glsl/generator_impl_variable_decl_statement_test.cc
@@ -475,7 +475,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Private) {
-    GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.f32(), type::AddressSpace::kPrivate);
 
     WrapInFunction(Expr("a"));
 
diff --git a/src/tint/writer/glsl/generator_impl_workgroup_var_test.cc b/src/tint/writer/glsl/generator_impl_workgroup_var_test.cc
index ef40708..97f8cf8 100644
--- a/src/tint/writer/glsl/generator_impl_workgroup_var_test.cc
+++ b/src/tint/writer/glsl/generator_impl_workgroup_var_test.cc
@@ -27,7 +27,7 @@
 using GlslGeneratorImplTest_WorkgroupVar = TestHelper;
 
 TEST_F(GlslGeneratorImplTest_WorkgroupVar, Basic) {
-    GlobalVar("wg", ty.f32(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("wg", ty.f32(), type::AddressSpace::kWorkgroup);
 
     Func("main", utils::Empty, ty.void_(), utils::Vector{Assign("wg", 1.2_f)},
          utils::Vector{
@@ -43,7 +43,7 @@
 TEST_F(GlslGeneratorImplTest_WorkgroupVar, Aliased) {
     auto* alias = Alias("F32", ty.f32());
 
-    GlobalVar("wg", ty.Of(alias), ast::AddressSpace::kWorkgroup);
+    GlobalVar("wg", ty.Of(alias), type::AddressSpace::kWorkgroup);
 
     Func("main", utils::Empty, ty.void_(), utils::Vector{Assign("wg", 1.2_f)},
          utils::Vector{
diff --git a/src/tint/writer/hlsl/generator_impl.cc b/src/tint/writer/hlsl/generator_impl.cc
index 3bac389..82237db 100644
--- a/src/tint/writer/hlsl/generator_impl.cc
+++ b/src/tint/writer/hlsl/generator_impl.cc
@@ -69,6 +69,7 @@
 #include "src/tint/type/multisampled_texture.h"
 #include "src/tint/type/sampled_texture.h"
 #include "src/tint/type/storage_texture.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/utils/compiler_macros.h"
 #include "src/tint/utils/defer.h"
 #include "src/tint/utils/map.h"
@@ -86,27 +87,27 @@
 
 const char kTempNamePrefix[] = "tint_tmp";
 
-const char* image_format_to_rwtexture_type(ast::TexelFormat image_format) {
+const char* image_format_to_rwtexture_type(type::TexelFormat image_format) {
     switch (image_format) {
-        case ast::TexelFormat::kBgra8Unorm:
-        case ast::TexelFormat::kRgba8Unorm:
-        case ast::TexelFormat::kRgba8Snorm:
-        case ast::TexelFormat::kRgba16Float:
-        case ast::TexelFormat::kR32Float:
-        case ast::TexelFormat::kRg32Float:
-        case ast::TexelFormat::kRgba32Float:
+        case type::TexelFormat::kBgra8Unorm:
+        case type::TexelFormat::kRgba8Unorm:
+        case type::TexelFormat::kRgba8Snorm:
+        case type::TexelFormat::kRgba16Float:
+        case type::TexelFormat::kR32Float:
+        case type::TexelFormat::kRg32Float:
+        case type::TexelFormat::kRgba32Float:
             return "float4";
-        case ast::TexelFormat::kRgba8Uint:
-        case ast::TexelFormat::kRgba16Uint:
-        case ast::TexelFormat::kR32Uint:
-        case ast::TexelFormat::kRg32Uint:
-        case ast::TexelFormat::kRgba32Uint:
+        case type::TexelFormat::kRgba8Uint:
+        case type::TexelFormat::kRgba16Uint:
+        case type::TexelFormat::kR32Uint:
+        case type::TexelFormat::kRg32Uint:
+        case type::TexelFormat::kRgba32Uint:
             return "uint4";
-        case ast::TexelFormat::kRgba8Sint:
-        case ast::TexelFormat::kRgba16Sint:
-        case ast::TexelFormat::kR32Sint:
-        case ast::TexelFormat::kRg32Sint:
-        case ast::TexelFormat::kRgba32Sint:
+        case type::TexelFormat::kRgba8Sint:
+        case type::TexelFormat::kRgba16Sint:
+        case type::TexelFormat::kR32Sint:
+        case type::TexelFormat::kRg32Sint:
+        case type::TexelFormat::kRgba32Sint:
             return "int4";
         default:
             return nullptr;
@@ -333,8 +334,8 @@
                 auto* ty = builder_.Sem().Get(str);
                 auto address_space_uses = ty->AddressSpaceUsage();
                 if (address_space_uses.size() !=
-                    (address_space_uses.count(ast::AddressSpace::kStorage) +
-                     address_space_uses.count(ast::AddressSpace::kUniform))) {
+                    (address_space_uses.count(type::AddressSpace::kStorage) +
+                     address_space_uses.count(type::AddressSpace::kUniform))) {
                     // The structure is used as something other than a storage buffer or
                     // uniform buffer, so it needs to be emitted.
                     // Storage buffer are read and written to via a ByteAddressBuffer
@@ -375,7 +376,7 @@
         std::string fn;
         {
             std::ostringstream ss;
-            if (!EmitType(ss, vec, tint::ast::AddressSpace::kUndefined, ast::Access::kUndefined,
+            if (!EmitType(ss, vec, tint::type::AddressSpace::kUndefined, type::Access::kUndefined,
                           "")) {
                 return "";
             }
@@ -384,13 +385,13 @@
         {
             auto out = line(&helpers_);
             out << "void " << fn << "(inout ";
-            if (!EmitTypeAndName(out, vec, ast::AddressSpace::kUndefined, ast::Access::kUndefined,
+            if (!EmitTypeAndName(out, vec, type::AddressSpace::kUndefined, type::Access::kUndefined,
                                  "vec")) {
                 return "";
             }
             out << ", int idx, ";
-            if (!EmitTypeAndName(out, vec->type(), ast::AddressSpace::kUndefined,
-                                 ast::Access::kUndefined, "val")) {
+            if (!EmitTypeAndName(out, vec->type(), type::AddressSpace::kUndefined,
+                                 type::Access::kUndefined, "val")) {
                 return "";
             }
             out << ") {";
@@ -449,7 +450,7 @@
         std::string fn;
         {
             std::ostringstream ss;
-            if (!EmitType(ss, mat, tint::ast::AddressSpace::kUndefined, ast::Access::kUndefined,
+            if (!EmitType(ss, mat, tint::type::AddressSpace::kUndefined, type::Access::kUndefined,
                           "")) {
                 return "";
             }
@@ -458,13 +459,13 @@
         {
             auto out = line(&helpers_);
             out << "void " << fn << "(inout ";
-            if (!EmitTypeAndName(out, mat, ast::AddressSpace::kUndefined, ast::Access::kUndefined,
+            if (!EmitTypeAndName(out, mat, type::AddressSpace::kUndefined, type::Access::kUndefined,
                                  "mat")) {
                 return "";
             }
             out << ", int col, ";
-            if (!EmitTypeAndName(out, mat->ColumnType(), ast::AddressSpace::kUndefined,
-                                 ast::Access::kUndefined, "val")) {
+            if (!EmitTypeAndName(out, mat->ColumnType(), type::AddressSpace::kUndefined,
+                                 type::Access::kUndefined, "val")) {
                 return "";
             }
             out << ") {";
@@ -518,7 +519,7 @@
         std::string fn;
         {
             std::ostringstream ss;
-            if (!EmitType(ss, mat, tint::ast::AddressSpace::kUndefined, ast::Access::kUndefined,
+            if (!EmitType(ss, mat, tint::type::AddressSpace::kUndefined, type::Access::kUndefined,
                           "")) {
                 return "";
             }
@@ -527,13 +528,13 @@
         {
             auto out = line(&helpers_);
             out << "void " << fn << "(inout ";
-            if (!EmitTypeAndName(out, mat, ast::AddressSpace::kUndefined, ast::Access::kUndefined,
+            if (!EmitTypeAndName(out, mat, type::AddressSpace::kUndefined, type::Access::kUndefined,
                                  "mat")) {
                 return "";
             }
             out << ", int col, int row, ";
-            if (!EmitTypeAndName(out, mat->type(), ast::AddressSpace::kUndefined,
-                                 ast::Access::kUndefined, "val")) {
+            if (!EmitTypeAndName(out, mat->type(), type::AddressSpace::kUndefined,
+                                 type::Access::kUndefined, "val")) {
                 return "";
             }
             out << ") {";
@@ -637,7 +638,7 @@
     }
 
     out << "as";
-    if (!EmitType(out, type, ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
+    if (!EmitType(out, type, type::AddressSpace::kNone, type::Access::kReadWrite, "")) {
         return false;
     }
     out << "(";
@@ -904,9 +905,9 @@
     if (auto* intrinsic = ast::GetAttribute<transform::DecomposeMemoryAccess::Intrinsic>(
             func->Declaration()->attributes)) {
         switch (intrinsic->address_space) {
-            case ast::AddressSpace::kUniform:
+            case type::AddressSpace::kUniform:
                 return EmitUniformBufferAccess(out, expr, intrinsic);
-            case ast::AddressSpace::kStorage:
+            case type::AddressSpace::kStorage:
                 if (!intrinsic->IsAtomic()) {
                     return EmitStorageBufferAccess(out, expr, intrinsic);
                 }
@@ -1025,7 +1026,7 @@
 bool GeneratorImpl::EmitTypeConversion(std::ostream& out,
                                        const sem::Call* call,
                                        const sem::TypeConversion* conv) {
-    if (!EmitType(out, conv->Target(), ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
+    if (!EmitType(out, conv->Target(), type::AddressSpace::kNone, type::Access::kReadWrite, "")) {
         return false;
     }
     out << "(";
@@ -1070,7 +1071,7 @@
     if (brackets) {
         out << "{";
     } else {
-        if (!EmitType(out, type, ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
+        if (!EmitType(out, type, type::AddressSpace::kNone, type::Access::kReadWrite, "")) {
             return false;
         }
         out << "(";
@@ -1587,12 +1588,12 @@
     auto rmw = [&](const char* hlsl) -> bool {
         {
             auto fn = line(&buf);
-            if (!EmitTypeAndName(fn, result_ty, ast::AddressSpace::kNone, ast::Access::kUndefined,
+            if (!EmitTypeAndName(fn, result_ty, type::AddressSpace::kNone, type::Access::kUndefined,
                                  name)) {
                 return false;
             }
             fn << "(RWByteAddressBuffer buffer, uint offset, ";
-            if (!EmitTypeAndName(fn, result_ty, ast::AddressSpace::kNone, ast::Access::kUndefined,
+            if (!EmitTypeAndName(fn, result_ty, type::AddressSpace::kNone, type::Access::kUndefined,
                                  "value")) {
                 return false;
             }
@@ -1608,7 +1609,7 @@
 
         {
             auto l = line(&buf);
-            if (!EmitTypeAndName(l, result_ty, ast::AddressSpace::kNone, ast::Access::kUndefined,
+            if (!EmitTypeAndName(l, result_ty, type::AddressSpace::kNone, type::Access::kUndefined,
                                  "original_value")) {
                 return false;
             }
@@ -1657,8 +1658,8 @@
             // InterlockedOr using 0 as the OR value
             {
                 auto fn = line(&buf);
-                if (!EmitTypeAndName(fn, result_ty, ast::AddressSpace::kNone,
-                                     ast::Access::kUndefined, name)) {
+                if (!EmitTypeAndName(fn, result_ty, type::AddressSpace::kNone,
+                                     type::Access::kUndefined, name)) {
                     return false;
                 }
                 fn << "(RWByteAddressBuffer buffer, uint offset) {";
@@ -1673,8 +1674,8 @@
 
             {
                 auto l = line(&buf);
-                if (!EmitTypeAndName(l, result_ty, ast::AddressSpace::kNone,
-                                     ast::Access::kUndefined, "value")) {
+                if (!EmitTypeAndName(l, result_ty, type::AddressSpace::kNone,
+                                     type::Access::kUndefined, "value")) {
                     return false;
                 }
                 l << " = 0;";
@@ -1691,8 +1692,8 @@
             {
                 auto fn = line(&buf);
                 fn << "void " << name << "(RWByteAddressBuffer buffer, uint offset, ";
-                if (!EmitTypeAndName(fn, value_ty, ast::AddressSpace::kNone,
-                                     ast::Access::kUndefined, "value")) {
+                if (!EmitTypeAndName(fn, value_ty, type::AddressSpace::kNone,
+                                     type::Access::kUndefined, "value")) {
                     return false;
                 }
                 fn << ") {";
@@ -1707,8 +1708,8 @@
 
             {
                 auto l = line(&buf);
-                if (!EmitTypeAndName(l, value_ty, ast::AddressSpace::kNone, ast::Access::kUndefined,
-                                     "ignored")) {
+                if (!EmitTypeAndName(l, value_ty, type::AddressSpace::kNone,
+                                     type::Access::kUndefined, "ignored")) {
                     return false;
                 }
                 l << ";";
@@ -1722,18 +1723,18 @@
             auto* value_ty = params[2]->Type()->UnwrapRef();
             {
                 auto fn = line(&buf);
-                if (!EmitTypeAndName(fn, result_ty, ast::AddressSpace::kNone,
-                                     ast::Access::kUndefined, name)) {
+                if (!EmitTypeAndName(fn, result_ty, type::AddressSpace::kNone,
+                                     type::Access::kUndefined, name)) {
                     return false;
                 }
                 fn << "(RWByteAddressBuffer buffer, uint offset, ";
-                if (!EmitTypeAndName(fn, value_ty, ast::AddressSpace::kNone,
-                                     ast::Access::kUndefined, "compare")) {
+                if (!EmitTypeAndName(fn, value_ty, type::AddressSpace::kNone,
+                                     type::Access::kUndefined, "compare")) {
                     return false;
                 }
                 fn << ", ";
-                if (!EmitTypeAndName(fn, value_ty, ast::AddressSpace::kNone,
-                                     ast::Access::kUndefined, "value")) {
+                if (!EmitTypeAndName(fn, value_ty, type::AddressSpace::kNone,
+                                     type::Access::kUndefined, "value")) {
                     return false;
                 }
                 fn << ") {";
@@ -1748,8 +1749,8 @@
 
             {  // T result = {0};
                 auto l = line(&buf);
-                if (!EmitTypeAndName(l, result_ty, ast::AddressSpace::kNone,
-                                     ast::Access::kUndefined, "result")) {
+                if (!EmitTypeAndName(l, result_ty, type::AddressSpace::kNone,
+                                     type::Access::kUndefined, "result")) {
                     return false;
                 }
                 l << "=";
@@ -1783,8 +1784,8 @@
 
     if (!builtin->ReturnType()->Is<type::Void>()) {
         auto pre = line();
-        if (!EmitTypeAndName(pre, builtin->ReturnType(), ast::AddressSpace::kNone,
-                             ast::Access::kUndefined, result)) {
+        if (!EmitTypeAndName(pre, builtin->ReturnType(), type::AddressSpace::kNone,
+                             type::Access::kUndefined, result)) {
             return false;
         }
         pre << " = ";
@@ -1847,8 +1848,8 @@
             {  // T result = 0;
                 auto pre = line();
                 auto* value_ty = builtin->Parameters()[1]->Type()->UnwrapRef();
-                if (!EmitTypeAndName(pre, value_ty, ast::AddressSpace::kNone,
-                                     ast::Access::kUndefined, result)) {
+                if (!EmitTypeAndName(pre, value_ty, type::AddressSpace::kNone,
+                                     type::Access::kUndefined, result)) {
                     return false;
                 }
                 pre << " = ";
@@ -1886,7 +1887,8 @@
             {  // T compare_value = <compare_value>;
                 auto pre = line();
                 if (!EmitTypeAndName(pre, TypeOf(compare_value)->UnwrapRef(),
-                                     ast::AddressSpace::kNone, ast::Access::kUndefined, compare)) {
+                                     type::AddressSpace::kNone, type::Access::kUndefined,
+                                     compare)) {
                     return false;
                 }
                 pre << " = ";
@@ -1995,8 +1997,8 @@
 
             {
                 auto l = line(b);
-                if (!EmitType(l, builtin->ReturnType(), ast::AddressSpace::kNone,
-                              ast::Access::kUndefined, "")) {
+                if (!EmitType(l, builtin->ReturnType(), type::AddressSpace::kNone,
+                              type::Access::kUndefined, "")) {
                     return false;
                 }
                 l << " result;";
@@ -2037,8 +2039,8 @@
             line(b) << member_type << " fract = frexp(" << in << ", exp);";
             {
                 auto l = line(b);
-                if (!EmitType(l, builtin->ReturnType(), ast::AddressSpace::kNone,
-                              ast::Access::kUndefined, "")) {
+                if (!EmitType(l, builtin->ReturnType(), type::AddressSpace::kNone,
+                              type::Access::kUndefined, "")) {
                     return false;
                 }
                 l << " result = {fract, int" << width << "(exp)};";
@@ -2075,7 +2077,7 @@
 // type after the call to `sign`.
 bool GeneratorImpl::EmitSignCall(std::ostream& out, const sem::Call* call, const sem::Builtin*) {
     auto* arg = call->Arguments()[0];
-    if (!EmitType(out, arg->Type(), ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
+    if (!EmitType(out, arg->Type(), type::AddressSpace::kNone, type::Access::kReadWrite, "")) {
         return false;
     }
     out << "(sign(";
@@ -2312,27 +2314,27 @@
             switch (builtin->Type()) {
                 case sem::BuiltinType::kTextureDimensions:
                     switch (texture_type->dim()) {
-                        case ast::TextureDimension::kNone:
+                        case type::TextureDimension::kNone:
                             TINT_ICE(Writer, diagnostics_) << "texture dimension is kNone";
                             return false;
-                        case ast::TextureDimension::k1d:
+                        case type::TextureDimension::k1d:
                             num_dimensions = 1;
                             break;
-                        case ast::TextureDimension::k2d:
+                        case type::TextureDimension::k2d:
                             num_dimensions = is_ms ? 3 : 2;
                             swizzle = is_ms ? ".xy" : "";
                             break;
-                        case ast::TextureDimension::k2dArray:
+                        case type::TextureDimension::k2dArray:
                             num_dimensions = is_ms ? 4 : 3;
                             swizzle = ".xy";
                             break;
-                        case ast::TextureDimension::k3d:
+                        case type::TextureDimension::k3d:
                             num_dimensions = 3;
                             break;
-                        case ast::TextureDimension::kCube:
+                        case type::TextureDimension::kCube:
                             num_dimensions = 2;
                             break;
-                        case ast::TextureDimension::kCubeArray:
+                        case type::TextureDimension::kCubeArray:
                             num_dimensions = 3;
                             swizzle = ".xy";
                             break;
@@ -2343,11 +2345,11 @@
                         default:
                             TINT_ICE(Writer, diagnostics_) << "texture dimension is not arrayed";
                             return false;
-                        case ast::TextureDimension::k2dArray:
+                        case type::TextureDimension::k2dArray:
                             num_dimensions = is_ms ? 4 : 3;
                             swizzle = ".z";
                             break;
-                        case ast::TextureDimension::kCubeArray:
+                        case type::TextureDimension::kCubeArray:
                             num_dimensions = 3;
                             swizzle = ".z";
                             break;
@@ -2359,18 +2361,18 @@
                             TINT_ICE(Writer, diagnostics_)
                                 << "texture dimension does not support mips";
                             return false;
-                        case ast::TextureDimension::k1d:
+                        case type::TextureDimension::k1d:
                             num_dimensions = 2;
                             swizzle = ".y";
                             break;
-                        case ast::TextureDimension::k2d:
-                        case ast::TextureDimension::kCube:
+                        case type::TextureDimension::k2d:
+                        case type::TextureDimension::kCube:
                             num_dimensions = 3;
                             swizzle = ".z";
                             break;
-                        case ast::TextureDimension::k2dArray:
-                        case ast::TextureDimension::k3d:
-                        case ast::TextureDimension::kCubeArray:
+                        case type::TextureDimension::k2dArray:
+                        case type::TextureDimension::k3d:
+                        case type::TextureDimension::kCubeArray:
                             num_dimensions = 4;
                             swizzle = ".w";
                             break;
@@ -2382,11 +2384,11 @@
                             TINT_ICE(Writer, diagnostics_)
                                 << "texture dimension does not support multisampling";
                             return false;
-                        case ast::TextureDimension::k2d:
+                        case type::TextureDimension::k2d:
                             num_dimensions = 3;
                             swizzle = ".z";
                             break;
-                        case ast::TextureDimension::k2dArray:
+                        case type::TextureDimension::k2dArray:
                             num_dimensions = 4;
                             swizzle = ".w";
                             break;
@@ -2855,7 +2857,7 @@
     // Emit storage atomic helpers
     if (auto* intrinsic =
             ast::GetAttribute<transform::DecomposeMemoryAccess::Intrinsic>(func->attributes)) {
-        if (intrinsic->address_space == ast::AddressSpace::kStorage && intrinsic->IsAtomic()) {
+        if (intrinsic->address_space == type::AddressSpace::kStorage && intrinsic->IsAtomic()) {
             if (!EmitStorageAtomicIntrinsic(func, intrinsic)) {
                 return false;
             }
@@ -2877,15 +2879,15 @@
             auto typedef_name = UniqueIdentifier(name + "_ret");
             auto pre = line();
             pre << "typedef ";
-            if (!EmitTypeAndName(pre, sem->ReturnType(), ast::AddressSpace::kNone,
-                                 ast::Access::kReadWrite, typedef_name)) {
+            if (!EmitTypeAndName(pre, sem->ReturnType(), type::AddressSpace::kNone,
+                                 type::Access::kReadWrite, typedef_name)) {
                 return false;
             }
             pre << ";";
             out << typedef_name;
         } else {
-            if (!EmitType(out, sem->ReturnType(), ast::AddressSpace::kNone, ast::Access::kReadWrite,
-                          "")) {
+            if (!EmitType(out, sem->ReturnType(), type::AddressSpace::kNone,
+                          type::Access::kReadWrite, "")) {
                 return false;
             }
         }
@@ -2901,14 +2903,14 @@
             first = false;
 
             auto const* type = v->Type();
-            auto address_space = ast::AddressSpace::kNone;
-            auto access = ast::Access::kUndefined;
+            auto address_space = type::AddressSpace::kNone;
+            auto access = type::Access::kUndefined;
 
             if (auto* ptr = type->As<type::Pointer>()) {
                 type = ptr->StoreType();
                 switch (ptr->AddressSpace()) {
-                    case ast::AddressSpace::kStorage:
-                    case ast::AddressSpace::kUniform:
+                    case type::AddressSpace::kStorage:
+                    case type::AddressSpace::kUniform:
                         // Not allowed by WGSL, but is used by certain transforms (e.g. DMA) to pass
                         // storage buffers and uniform buffers down into transform-generated
                         // functions. In this situation we want to generate the parameter without an
@@ -2975,8 +2977,8 @@
     auto name = builder_.Symbols().NameFor(builder_.Symbols().New("unused"));
     {
         auto out = line();
-        if (!EmitTypeAndName(out, sem->ReturnType(), ast::AddressSpace::kNone,
-                             ast::Access::kReadWrite, name)) {
+        if (!EmitTypeAndName(out, sem->ReturnType(), type::AddressSpace::kNone,
+                             type::Access::kReadWrite, name)) {
             return false;
         }
         out << ";";
@@ -2992,17 +2994,17 @@
         [&](const ast::Var* var) {
             auto* sem = builder_.Sem().Get(global);
             switch (sem->AddressSpace()) {
-                case ast::AddressSpace::kUniform:
+                case type::AddressSpace::kUniform:
                     return EmitUniformVariable(var, sem);
-                case ast::AddressSpace::kStorage:
+                case type::AddressSpace::kStorage:
                     return EmitStorageVariable(var, sem);
-                case ast::AddressSpace::kHandle:
+                case type::AddressSpace::kHandle:
                     return EmitHandleVariable(var, sem);
-                case ast::AddressSpace::kPrivate:
+                case type::AddressSpace::kPrivate:
                     return EmitPrivateVariable(sem);
-                case ast::AddressSpace::kWorkgroup:
+                case type::AddressSpace::kWorkgroup:
                     return EmitWorkgroupVariable(sem);
-                case ast::AddressSpace::kPushConstant:
+                case type::AddressSpace::kPushConstant:
                     diagnostics_.add_error(
                         diag::System::Writer,
                         "unhandled address space " + utils::ToString(sem->AddressSpace()));
@@ -3041,7 +3043,7 @@
     {
         ScopedIndent si(this);
         auto out = line();
-        if (!EmitTypeAndName(out, type, ast::AddressSpace::kUniform, sem->Access(), name)) {
+        if (!EmitTypeAndName(out, type, type::AddressSpace::kUniform, sem->Access(), name)) {
             return false;
         }
         out << ";";
@@ -3055,13 +3057,13 @@
 bool GeneratorImpl::EmitStorageVariable(const ast::Var* var, const sem::Variable* sem) {
     auto* type = sem->Type()->UnwrapRef();
     auto out = line();
-    if (!EmitTypeAndName(out, type, ast::AddressSpace::kStorage, sem->Access(),
+    if (!EmitTypeAndName(out, type, type::AddressSpace::kStorage, sem->Access(),
                          builder_.Symbols().NameFor(var->symbol))) {
         return false;
     }
 
     auto* global_sem = sem->As<sem::GlobalVariable>();
-    out << RegisterAndSpace(sem->Access() == ast::Access::kRead ? 't' : 'u',
+    out << RegisterAndSpace(sem->Access() == type::Access::kRead ? 't' : 'u',
                             global_sem->BindingPoint())
         << ";";
 
@@ -3326,7 +3328,7 @@
                 return true;
             }
 
-            if (!EmitType(out, v, ast::AddressSpace::kNone, ast::Access::kUndefined, "")) {
+            if (!EmitType(out, v, type::AddressSpace::kNone, type::Access::kUndefined, "")) {
                 return false;
             }
 
@@ -3343,7 +3345,7 @@
             return true;
         },
         [&](const type::Matrix* m) {
-            if (!EmitType(out, m, ast::AddressSpace::kNone, ast::Access::kUndefined, "")) {
+            if (!EmitType(out, m, type::AddressSpace::kNone, type::Access::kUndefined, "")) {
                 return false;
             }
 
@@ -3362,7 +3364,7 @@
         [&](const type::Array* a) {
             if (constant->AllZero()) {
                 out << "(";
-                if (!EmitType(out, a, ast::AddressSpace::kNone, ast::Access::kUndefined, "")) {
+                if (!EmitType(out, a, type::AddressSpace::kNone, type::Access::kUndefined, "")) {
                     return false;
                 }
                 out << ")0";
@@ -3502,7 +3504,7 @@
             return true;
         },
         [&](const type::Vector* vec) {
-            if (!EmitType(out, type, ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
+            if (!EmitType(out, type, type::AddressSpace::kNone, type::Access::kReadWrite, "")) {
                 return false;
             }
             ScopedParen sp(out);
@@ -3517,7 +3519,7 @@
             return true;
         },
         [&](const type::Matrix* mat) {
-            if (!EmitType(out, type, ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
+            if (!EmitType(out, type, type::AddressSpace::kNone, type::Access::kReadWrite, "")) {
                 return false;
             }
             ScopedParen sp(out);
@@ -3534,12 +3536,12 @@
         [&](const sem::Struct*) {
             out << "(";
             TINT_DEFER(out << ")" << value);
-            return EmitType(out, type, ast::AddressSpace::kNone, ast::Access::kUndefined, "");
+            return EmitType(out, type, type::AddressSpace::kNone, type::Access::kUndefined, "");
         },
         [&](const type::Array*) {
             out << "(";
             TINT_DEFER(out << ")" << value);
-            return EmitType(out, type, ast::AddressSpace::kNone, ast::Access::kUndefined, "");
+            return EmitType(out, type, type::AddressSpace::kNone, type::Access::kUndefined, "");
         },
         [&](Default) {
             diagnostics_.add_error(
@@ -3914,21 +3916,21 @@
 
 bool GeneratorImpl::EmitType(std::ostream& out,
                              const type::Type* type,
-                             ast::AddressSpace address_space,
-                             ast::Access access,
+                             type::AddressSpace address_space,
+                             type::Access access,
                              const std::string& name,
                              bool* name_printed /* = nullptr */) {
     if (name_printed) {
         *name_printed = false;
     }
     switch (address_space) {
-        case ast::AddressSpace::kStorage:
-            if (access != ast::Access::kRead) {
+        case type::AddressSpace::kStorage:
+            if (access != type::Access::kRead) {
                 out << "RW";
             }
             out << "ByteAddressBuffer";
             return true;
-        case ast::AddressSpace::kUniform: {
+        case type::AddressSpace::kUniform: {
             auto array_length = (type->Size() + 15) / 16;
             out << "uint4 " << name << "[" << array_length << "]";
             if (name_printed) {
@@ -4045,28 +4047,28 @@
             auto* depth_ms = tex->As<type::DepthMultisampledTexture>();
             auto* sampled = tex->As<type::SampledTexture>();
 
-            if (storage && storage->access() != ast::Access::kRead) {
+            if (storage && storage->access() != type::Access::kRead) {
                 out << "RW";
             }
             out << "Texture";
 
             switch (tex->dim()) {
-                case ast::TextureDimension::k1d:
+                case type::TextureDimension::k1d:
                     out << "1D";
                     break;
-                case ast::TextureDimension::k2d:
+                case type::TextureDimension::k2d:
                     out << ((ms || depth_ms) ? "2DMS" : "2D");
                     break;
-                case ast::TextureDimension::k2dArray:
+                case type::TextureDimension::k2dArray:
                     out << ((ms || depth_ms) ? "2DMSArray" : "2DArray");
                     break;
-                case ast::TextureDimension::k3d:
+                case type::TextureDimension::k3d:
                     out << "3D";
                     break;
-                case ast::TextureDimension::kCube:
+                case type::TextureDimension::kCube:
                     out << "Cube";
                     break;
-                case ast::TextureDimension::kCubeArray:
+                case type::TextureDimension::kCubeArray:
                     out << "CubeArray";
                     break;
                 default:
@@ -4141,8 +4143,8 @@
 
 bool GeneratorImpl::EmitTypeAndName(std::ostream& out,
                                     const type::Type* type,
-                                    ast::AddressSpace address_space,
-                                    ast::Access access,
+                                    type::AddressSpace address_space,
+                                    type::Access access,
                                     const std::string& name) {
     bool name_printed = false;
     if (!EmitType(out, type, address_space, access, name, &name_printed)) {
@@ -4224,7 +4226,7 @@
             }
 
             out << pre;
-            if (!EmitTypeAndName(out, ty, ast::AddressSpace::kNone, ast::Access::kReadWrite,
+            if (!EmitTypeAndName(out, ty, type::AddressSpace::kNone, type::Access::kReadWrite,
                                  mem_name)) {
                 return false;
             }
@@ -4294,7 +4296,7 @@
 
     auto out = line();
     out << "const ";
-    if (!EmitTypeAndName(out, type, ast::AddressSpace::kNone, ast::Access::kUndefined,
+    if (!EmitTypeAndName(out, type, type::AddressSpace::kNone, type::Access::kUndefined,
                          builder_.Symbols().NameFor(let->symbol))) {
         return false;
     }
@@ -4321,8 +4323,8 @@
         std::vector<std::string> parameter_names;
         {
             auto decl = line(&b);
-            if (!EmitTypeAndName(decl, builtin->ReturnType(), ast::AddressSpace::kNone,
-                                 ast::Access::kUndefined, fn_name)) {
+            if (!EmitTypeAndName(decl, builtin->ReturnType(), type::AddressSpace::kNone,
+                                 type::Access::kUndefined, fn_name)) {
                 return "";
             }
             {
@@ -4337,8 +4339,8 @@
                         decl << "inout ";
                         ty = ptr->StoreType();
                     }
-                    if (!EmitTypeAndName(decl, ty, ast::AddressSpace::kNone,
-                                         ast::Access::kUndefined, param_name)) {
+                    if (!EmitTypeAndName(decl, ty, type::AddressSpace::kNone,
+                                         type::Access::kUndefined, param_name)) {
                         return "";
                     }
                     parameter_names.emplace_back(std::move(param_name));
diff --git a/src/tint/writer/hlsl/generator_impl.h b/src/tint/writer/hlsl/generator_impl.h
index 76b9042..7b2d97f 100644
--- a/src/tint/writer/hlsl/generator_impl.h
+++ b/src/tint/writer/hlsl/generator_impl.h
@@ -413,8 +413,8 @@
     /// @returns true if the type is emitted
     bool EmitType(std::ostream& out,
                   const type::Type* type,
-                  ast::AddressSpace address_space,
-                  ast::Access access,
+                  type::AddressSpace address_space,
+                  type::Access access,
                   const std::string& name,
                   bool* name_printed = nullptr);
     /// Handles generating type and name
@@ -426,8 +426,8 @@
     /// @returns true if the type is emitted
     bool EmitTypeAndName(std::ostream& out,
                          const type::Type* type,
-                         ast::AddressSpace address_space,
-                         ast::Access access,
+                         type::AddressSpace address_space,
+                         type::Access access,
                          const std::string& name);
     /// Handles generating a structure declaration. If the structure has already been emitted, then
     /// this function will simply return `true` without emitting anything.
diff --git a/src/tint/writer/hlsl/generator_impl_array_accessor_test.cc b/src/tint/writer/hlsl/generator_impl_array_accessor_test.cc
index 0da678a..71bf057 100644
--- a/src/tint/writer/hlsl/generator_impl_array_accessor_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_array_accessor_test.cc
@@ -22,7 +22,7 @@
 using HlslGeneratorImplTest_Expression = TestHelper;
 
 TEST_F(HlslGeneratorImplTest_Expression, IndexAccessor) {
-    GlobalVar("ary", ty.array<i32, 10>(), ast::AddressSpace::kPrivate);
+    GlobalVar("ary", ty.array<i32, 10>(), type::AddressSpace::kPrivate);
     auto* expr = IndexAccessor("ary", 5_i);
     WrapInFunction(expr);
 
diff --git a/src/tint/writer/hlsl/generator_impl_binary_test.cc b/src/tint/writer/hlsl/generator_impl_binary_test.cc
index 6e2b3c7..afc6b8f 100644
--- a/src/tint/writer/hlsl/generator_impl_binary_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_binary_test.cc
@@ -50,8 +50,8 @@
         return;
     }
 
-    GlobalVar("left", ty.f32(), ast::AddressSpace::kPrivate);
-    GlobalVar("right", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("left", ty.f32(), type::AddressSpace::kPrivate);
+    GlobalVar("right", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* left = Expr("left");
     auto* right = Expr("right");
@@ -82,8 +82,8 @@
 
     Enable(ast::Extension::kF16);
 
-    GlobalVar("left", ty.f16(), ast::AddressSpace::kPrivate);
-    GlobalVar("right", ty.f16(), ast::AddressSpace::kPrivate);
+    GlobalVar("left", ty.f16(), type::AddressSpace::kPrivate);
+    GlobalVar("right", ty.f16(), type::AddressSpace::kPrivate);
 
     auto* left = Expr("left");
     auto* right = Expr("right");
@@ -105,8 +105,8 @@
         return;
     }
 
-    GlobalVar("left", ty.u32(), ast::AddressSpace::kPrivate);
-    GlobalVar("right", ty.u32(), ast::AddressSpace::kPrivate);
+    GlobalVar("left", ty.u32(), type::AddressSpace::kPrivate);
+    GlobalVar("right", ty.u32(), type::AddressSpace::kPrivate);
 
     auto* left = Expr("left");
     auto* right = Expr("right");
@@ -133,8 +133,8 @@
         return;
     }
 
-    GlobalVar("left", ty.i32(), ast::AddressSpace::kPrivate);
-    GlobalVar("right", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("left", ty.i32(), type::AddressSpace::kPrivate);
+    GlobalVar("right", ty.i32(), type::AddressSpace::kPrivate);
 
     auto* left = Expr("left");
     auto* right = Expr("right");
@@ -237,7 +237,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixScalar_f32) {
-    GlobalVar("mat", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f32>(), type::AddressSpace::kPrivate);
     auto* lhs = Expr("mat");
     auto* rhs = Expr(1_f);
 
@@ -254,7 +254,7 @@
 TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixScalar_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("mat", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f16>(), type::AddressSpace::kPrivate);
     auto* lhs = Expr("mat");
     auto* rhs = Expr(1_h);
 
@@ -269,7 +269,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Binary, Multiply_ScalarMatrix_f32) {
-    GlobalVar("mat", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f32>(), type::AddressSpace::kPrivate);
     auto* lhs = Expr(1_f);
     auto* rhs = Expr("mat");
 
@@ -286,7 +286,7 @@
 TEST_F(HlslGeneratorImplTest_Binary, Multiply_ScalarMatrix_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("mat", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f16>(), type::AddressSpace::kPrivate);
     auto* lhs = Expr(1_h);
     auto* rhs = Expr("mat");
 
@@ -301,7 +301,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixVector_f32) {
-    GlobalVar("mat", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f32>(), type::AddressSpace::kPrivate);
     auto* lhs = Expr("mat");
     auto* rhs = vec3<f32>(1_f, 1_f, 1_f);
 
@@ -318,7 +318,7 @@
 TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixVector_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("mat", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f16>(), type::AddressSpace::kPrivate);
     auto* lhs = Expr("mat");
     auto* rhs = vec3<f16>(1_h, 1_h, 1_h);
 
@@ -333,7 +333,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Binary, Multiply_VectorMatrix_f32) {
-    GlobalVar("mat", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f32>(), type::AddressSpace::kPrivate);
     auto* lhs = vec3<f32>(1_f, 1_f, 1_f);
     auto* rhs = Expr("mat");
 
@@ -350,7 +350,7 @@
 TEST_F(HlslGeneratorImplTest_Binary, Multiply_VectorMatrix_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("mat", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f16>(), type::AddressSpace::kPrivate);
     auto* lhs = vec3<f16>(1_h, 1_h, 1_h);
     auto* rhs = Expr("mat");
 
@@ -365,8 +365,8 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixMatrix_f32) {
-    GlobalVar("lhs", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("rhs", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("lhs", ty.mat3x3<f32>(), type::AddressSpace::kPrivate);
+    GlobalVar("rhs", ty.mat3x3<f32>(), type::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kMultiply, Expr("lhs"), Expr("rhs"));
     WrapInFunction(expr);
@@ -381,8 +381,8 @@
 TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixMatrix_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("lhs", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
-    GlobalVar("rhs", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
+    GlobalVar("lhs", ty.mat3x3<f16>(), type::AddressSpace::kPrivate);
+    GlobalVar("rhs", ty.mat3x3<f16>(), type::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kMultiply, Expr("lhs"), Expr("rhs"));
     WrapInFunction(expr);
@@ -395,8 +395,8 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Binary, Logical_And) {
-    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b"));
     WrapInFunction(expr);
@@ -415,10 +415,10 @@
 
 TEST_F(HlslGeneratorImplTest_Binary, Logical_Multi) {
     // (a && b) || (c || d)
-    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("c", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("d", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("c", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("d", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(
         ast::BinaryOp::kLogicalOr,
@@ -447,8 +447,8 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Binary, Logical_Or) {
-    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, Expr("a"), Expr("b"));
     WrapInFunction(expr);
@@ -474,9 +474,9 @@
     //   return 3i;
     // }
 
-    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("c", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("c", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* expr =
         If(create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b")),
@@ -511,9 +511,9 @@
 TEST_F(HlslGeneratorImplTest_Binary, Return_WithLogical) {
     // return (a && b) || c;
 
-    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("c", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("c", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* expr = Return(create<ast::BinaryExpression>(
         ast::BinaryOp::kLogicalOr,
@@ -539,10 +539,10 @@
 TEST_F(HlslGeneratorImplTest_Binary, Assign_WithLogical) {
     // a = (b || c) && d;
 
-    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("c", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("d", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("c", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("d", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* expr =
         Assign(Expr("a"),
@@ -570,12 +570,12 @@
 TEST_F(HlslGeneratorImplTest_Binary, Decl_WithLogical) {
     // var a : bool = (b && c) || d;
 
-    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("c", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("d", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("c", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("d", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* var =
-        Var("a", ty.bool_(), ast::AddressSpace::kNone,
+        Var("a", ty.bool_(), type::AddressSpace::kNone,
             create<ast::BinaryExpression>(
                 ast::BinaryOp::kLogicalOr,
                 create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("b"), Expr("c")),
@@ -609,10 +609,10 @@
              Param(Sym(), ty.bool_()),
          },
          ty.void_(), utils::Empty, utils::Empty);
-    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("c", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("d", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("c", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("d", ty.bool_(), type::AddressSpace::kPrivate);
 
     utils::Vector params{
         create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b")),
diff --git a/src/tint/writer/hlsl/generator_impl_builtin_test.cc b/src/tint/writer/hlsl/generator_impl_builtin_test.cc
index 785e1fd..fadfbd2 100644
--- a/src/tint/writer/hlsl/generator_impl_builtin_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_builtin_test.cc
@@ -197,19 +197,19 @@
     if (param.type == CallParamType::kF16) {
         Enable(ast::Extension::kF16);
 
-        GlobalVar("h2", ty.vec2<f16>(), ast::AddressSpace::kPrivate);
-        GlobalVar("h3", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
-        GlobalVar("hm2x2", ty.mat2x2<f16>(), ast::AddressSpace::kPrivate);
-        GlobalVar("hm3x2", ty.mat3x2<f16>(), ast::AddressSpace::kPrivate);
+        GlobalVar("h2", ty.vec2<f16>(), type::AddressSpace::kPrivate);
+        GlobalVar("h3", ty.vec3<f16>(), type::AddressSpace::kPrivate);
+        GlobalVar("hm2x2", ty.mat2x2<f16>(), type::AddressSpace::kPrivate);
+        GlobalVar("hm3x2", ty.mat3x2<f16>(), type::AddressSpace::kPrivate);
     }
 
-    GlobalVar("f2", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("f3", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("u2", ty.vec2<u32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("i2", ty.vec2<i32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("b2", ty.vec2<bool>(), ast::AddressSpace::kPrivate);
-    GlobalVar("m2x2", ty.mat2x2<f32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("m3x2", ty.mat3x2<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("f2", ty.vec2<f32>(), type::AddressSpace::kPrivate);
+    GlobalVar("f3", ty.vec3<f32>(), type::AddressSpace::kPrivate);
+    GlobalVar("u2", ty.vec2<u32>(), type::AddressSpace::kPrivate);
+    GlobalVar("i2", ty.vec2<i32>(), type::AddressSpace::kPrivate);
+    GlobalVar("b2", ty.vec2<bool>(), type::AddressSpace::kPrivate);
+    GlobalVar("m2x2", ty.mat2x2<f32>(), type::AddressSpace::kPrivate);
+    GlobalVar("m3x2", ty.mat3x2<f32>(), type::AddressSpace::kPrivate);
 
     auto* call = GenerateCall(param.builtin, param.type, this);
     ASSERT_NE(nullptr, call) << "Unhandled builtin";
@@ -339,8 +339,8 @@
 TEST_F(HlslGeneratorImplTest_Builtin, Builtin_Call) {
     auto* call = Call("dot", "param1", "param2");
 
-    GlobalVar("param1", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("param2", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("param1", ty.vec3<f32>(), type::AddressSpace::kPrivate);
+    GlobalVar("param2", ty.vec3<f32>(), type::AddressSpace::kPrivate);
 
     WrapInFunction(CallStmt(call));
 
@@ -353,8 +353,8 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Builtin, Select_Scalar) {
-    GlobalVar("a", Expr(1_f), ast::AddressSpace::kPrivate);
-    GlobalVar("b", Expr(2_f), ast::AddressSpace::kPrivate);
+    GlobalVar("a", Expr(1_f), type::AddressSpace::kPrivate);
+    GlobalVar("b", Expr(2_f), type::AddressSpace::kPrivate);
     auto* call = Call("select", "a", "b", true);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
@@ -366,8 +366,8 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Builtin, Select_Vector) {
-    GlobalVar("a", vec2<i32>(1_i, 2_i), ast::AddressSpace::kPrivate);
-    GlobalVar("b", vec2<i32>(3_i, 4_i), ast::AddressSpace::kPrivate);
+    GlobalVar("a", vec2<i32>(1_i, 2_i), type::AddressSpace::kPrivate);
+    GlobalVar("b", vec2<i32>(3_i, 4_i), type::AddressSpace::kPrivate);
     auto* call = Call("select", "a", "b", vec2<bool>(true, false));
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
@@ -1107,7 +1107,7 @@
 
 TEST_F(HlslGeneratorImplTest_Builtin, Pack4x8Snorm) {
     auto* call = Call("pack4x8snorm", "p1");
-    GlobalVar("p1", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("p1", ty.vec4<f32>(), type::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1129,7 +1129,7 @@
 
 TEST_F(HlslGeneratorImplTest_Builtin, Pack4x8Unorm) {
     auto* call = Call("pack4x8unorm", "p1");
-    GlobalVar("p1", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("p1", ty.vec4<f32>(), type::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1151,7 +1151,7 @@
 
 TEST_F(HlslGeneratorImplTest_Builtin, Pack2x16Snorm) {
     auto* call = Call("pack2x16snorm", "p1");
-    GlobalVar("p1", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("p1", ty.vec2<f32>(), type::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1173,7 +1173,7 @@
 
 TEST_F(HlslGeneratorImplTest_Builtin, Pack2x16Unorm) {
     auto* call = Call("pack2x16unorm", "p1");
-    GlobalVar("p1", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("p1", ty.vec2<f32>(), type::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1195,7 +1195,7 @@
 
 TEST_F(HlslGeneratorImplTest_Builtin, Pack2x16Float) {
     auto* call = Call("pack2x16float", "p1");
-    GlobalVar("p1", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("p1", ty.vec2<f32>(), type::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1217,7 +1217,7 @@
 
 TEST_F(HlslGeneratorImplTest_Builtin, Unpack4x8Snorm) {
     auto* call = Call("unpack4x8snorm", "p1");
-    GlobalVar("p1", ty.u32(), ast::AddressSpace::kPrivate);
+    GlobalVar("p1", ty.u32(), type::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1240,7 +1240,7 @@
 
 TEST_F(HlslGeneratorImplTest_Builtin, Unpack4x8Unorm) {
     auto* call = Call("unpack4x8unorm", "p1");
-    GlobalVar("p1", ty.u32(), ast::AddressSpace::kPrivate);
+    GlobalVar("p1", ty.u32(), type::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1263,7 +1263,7 @@
 
 TEST_F(HlslGeneratorImplTest_Builtin, Unpack2x16Snorm) {
     auto* call = Call("unpack2x16snorm", "p1");
-    GlobalVar("p1", ty.u32(), ast::AddressSpace::kPrivate);
+    GlobalVar("p1", ty.u32(), type::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1286,7 +1286,7 @@
 
 TEST_F(HlslGeneratorImplTest_Builtin, Unpack2x16Unorm) {
     auto* call = Call("unpack2x16unorm", "p1");
-    GlobalVar("p1", ty.u32(), ast::AddressSpace::kPrivate);
+    GlobalVar("p1", ty.u32(), type::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1309,7 +1309,7 @@
 
 TEST_F(HlslGeneratorImplTest_Builtin, Unpack2x16Float) {
     auto* call = Call("unpack2x16float", "p1");
-    GlobalVar("p1", ty.u32(), ast::AddressSpace::kPrivate);
+    GlobalVar("p1", ty.u32(), type::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
diff --git a/src/tint/writer/hlsl/generator_impl_call_test.cc b/src/tint/writer/hlsl/generator_impl_call_test.cc
index 33e0762..46b1406 100644
--- a/src/tint/writer/hlsl/generator_impl_call_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_call_test.cc
@@ -42,8 +42,8 @@
              Param(Sym(), ty.f32()),
          },
          ty.f32(), utils::Vector{Return(1.23_f)});
-    GlobalVar("param1", ty.f32(), ast::AddressSpace::kPrivate);
-    GlobalVar("param2", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("param1", ty.f32(), type::AddressSpace::kPrivate);
+    GlobalVar("param2", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* call = Call("my_func", "param1", "param2");
     WrapInFunction(call);
@@ -62,8 +62,8 @@
              Param(Sym(), ty.f32()),
          },
          ty.void_(), utils::Empty, utils::Empty);
-    GlobalVar("param1", ty.f32(), ast::AddressSpace::kPrivate);
-    GlobalVar("param2", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("param1", ty.f32(), type::AddressSpace::kPrivate);
+    GlobalVar("param2", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* call = CallStmt(Call("my_func", "param1", "param2"));
     WrapInFunction(call);
diff --git a/src/tint/writer/hlsl/generator_impl_function_test.cc b/src/tint/writer/hlsl/generator_impl_function_test.cc
index 56465d3..8e734ca 100644
--- a/src/tint/writer/hlsl/generator_impl_function_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_function_test.cc
@@ -101,7 +101,7 @@
     // fn f(foo : ptr<function, f32>) -> f32 {
     //   return *foo;
     // }
-    Func("f", utils::Vector{Param("foo", ty.pointer<f32>(ast::AddressSpace::kFunction))}, ty.f32(),
+    Func("f", utils::Vector{Param("foo", ty.pointer<f32>(type::AddressSpace::kFunction))}, ty.f32(),
          utils::Vector{Return(Deref("foo"))});
 
     GeneratorImpl& gen = SanitizeAndBuild();
@@ -361,7 +361,7 @@
 TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_Uniform) {
     auto* ubo_ty = Structure("UBO", utils::Vector{Member("coord", ty.vec4<f32>())});
     auto* ubo =
-        GlobalVar("ubo", ty.Of(ubo_ty), ast::AddressSpace::kUniform, Binding(0_a), Group(1_a));
+        GlobalVar("ubo", ty.Of(ubo_ty), type::AddressSpace::kUniform, Binding(0_a), Group(1_a));
 
     Func("sub_func",
          utils::Vector{
@@ -404,7 +404,7 @@
 TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_UniformStruct) {
     auto* s = Structure("Uniforms", utils::Vector{Member("coord", ty.vec4<f32>())});
 
-    GlobalVar("uniforms", ty.Of(s), ast::AddressSpace::kUniform, Binding(0_a), Group(1_a));
+    GlobalVar("uniforms", ty.Of(s), type::AddressSpace::kUniform, Binding(0_a), Group(1_a));
 
     auto* var = Var("v", ty.f32(), MemberAccessor(MemberAccessor("uniforms", "coord"), "x"));
 
@@ -437,8 +437,8 @@
                                     Member("b", ty.f32()),
                                 });
 
-    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(0_a),
-              Group(1_a));
+    GlobalVar("coord", ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite,
+              Binding(0_a), Group(1_a));
 
     auto* var = Var("v", ty.f32(), MemberAccessor("coord", "b"));
 
@@ -470,7 +470,7 @@
                                     Member("b", ty.f32()),
                                 });
 
-    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("coord", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(0_a),
               Group(1_a));
 
     auto* var = Var("v", ty.f32(), MemberAccessor("coord", "b"));
@@ -503,8 +503,8 @@
                                     Member("b", ty.f32()),
                                 });
 
-    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(0_a),
-              Group(1_a));
+    GlobalVar("coord", ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite,
+              Binding(0_a), Group(1_a));
 
     Func("frag_main", utils::Empty, ty.void_(),
          utils::Vector{
@@ -534,8 +534,8 @@
                                     Member("b", ty.f32()),
                                 });
 
-    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(0_a),
-              Group(1_a));
+    GlobalVar("coord", ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite,
+              Binding(0_a), Group(1_a));
 
     Func("frag_main", utils::Empty, ty.void_(),
          utils::Vector{
@@ -561,7 +561,7 @@
 
 TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_Called_By_EntryPoint_With_Uniform) {
     auto* s = Structure("S", utils::Vector{Member("x", ty.f32())});
-    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kUniform, Binding(0_a), Group(1_a));
+    GlobalVar("coord", ty.Of(s), type::AddressSpace::kUniform, Binding(0_a), Group(1_a));
 
     Func("sub_func",
          utils::Vector{
@@ -603,8 +603,8 @@
 
 TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_Called_By_EntryPoint_With_StorageBuffer) {
     auto* s = Structure("S", utils::Vector{Member("x", ty.f32())});
-    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(0_a),
-              Group(1_a));
+    GlobalVar("coord", ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite,
+              Binding(0_a), Group(1_a));
 
     Func("sub_func",
          utils::Vector{
@@ -831,8 +831,8 @@
 
     auto* s = Structure("Data", utils::Vector{Member("d", ty.f32())});
 
-    GlobalVar("data", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(0_a),
-              Group(0_a));
+    GlobalVar("data", ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite,
+              Binding(0_a), Group(0_a));
 
     {
         auto* var = Var("v", ty.f32(), MemberAccessor("data", "d"));
diff --git a/src/tint/writer/hlsl/generator_impl_identifier_test.cc b/src/tint/writer/hlsl/generator_impl_identifier_test.cc
index b6434d8..c28e757 100644
--- a/src/tint/writer/hlsl/generator_impl_identifier_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_identifier_test.cc
@@ -20,7 +20,7 @@
 using HlslGeneratorImplTest_Identifier = TestHelper;
 
 TEST_F(HlslGeneratorImplTest_Identifier, EmitIdentifierExpression) {
-    GlobalVar("foo", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("foo", ty.i32(), type::AddressSpace::kPrivate);
 
     auto* i = Expr("foo");
     WrapInFunction(i);
diff --git a/src/tint/writer/hlsl/generator_impl_if_test.cc b/src/tint/writer/hlsl/generator_impl_if_test.cc
index 37c9ea9..c599648 100644
--- a/src/tint/writer/hlsl/generator_impl_if_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_if_test.cc
@@ -20,7 +20,7 @@
 using HlslGeneratorImplTest_If = TestHelper;
 
 TEST_F(HlslGeneratorImplTest_If, Emit_If) {
-    GlobalVar("cond", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("cond", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* cond = Expr("cond");
     auto* body = Block(Return());
@@ -38,8 +38,8 @@
 }
 
 TEST_F(HlslGeneratorImplTest_If, Emit_IfWithElseIf) {
-    GlobalVar("cond", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("else_cond", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("cond", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("else_cond", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* else_cond = Expr("else_cond");
     auto* else_body = Block(Return());
@@ -65,7 +65,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_If, Emit_IfWithElse) {
-    GlobalVar("cond", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("cond", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* else_body = Block(Return());
 
@@ -88,8 +88,8 @@
 }
 
 TEST_F(HlslGeneratorImplTest_If, Emit_IfWithMultiple) {
-    GlobalVar("cond", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("else_cond", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("cond", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("else_cond", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* else_cond = Expr("else_cond");
 
diff --git a/src/tint/writer/hlsl/generator_impl_import_test.cc b/src/tint/writer/hlsl/generator_impl_import_test.cc
index 3e9e591..9d00c3f 100644
--- a/src/tint/writer/hlsl/generator_impl_import_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_import_test.cc
@@ -254,7 +254,7 @@
                          testing::Values(HlslImportData{"clamp", "clamp"}));
 
 TEST_F(HlslGeneratorImplTest_Import, HlslImportData_Determinant) {
-    GlobalVar("var", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("var", ty.mat3x3<f32>(), type::AddressSpace::kPrivate);
 
     auto* expr = Call("determinant", "var");
     WrapInFunction(expr);
@@ -267,7 +267,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Import, HlslImportData_QuantizeToF16_Scalar) {
-    GlobalVar("v", Expr(2_f), ast::AddressSpace::kPrivate);
+    GlobalVar("v", Expr(2_f), type::AddressSpace::kPrivate);
 
     auto* expr = Call("quantizeToF16", "v");
     WrapInFunction(expr);
@@ -280,7 +280,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Import, HlslImportData_QuantizeToF16_Vector) {
-    GlobalVar("v", vec3<f32>(2_f), ast::AddressSpace::kPrivate);
+    GlobalVar("v", vec3<f32>(2_f), type::AddressSpace::kPrivate);
 
     auto* expr = Call("quantizeToF16", "v");
     WrapInFunction(expr);
diff --git a/src/tint/writer/hlsl/generator_impl_loop_test.cc b/src/tint/writer/hlsl/generator_impl_loop_test.cc
index 4249f1e..620543d 100644
--- a/src/tint/writer/hlsl/generator_impl_loop_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_loop_test.cc
@@ -93,8 +93,8 @@
 TEST_F(HlslGeneratorImplTest_Loop, Emit_LoopNestedWithContinuing) {
     Func("a_statement", {}, ty.void_(), {});
 
-    GlobalVar("lhs", ty.f32(), ast::AddressSpace::kPrivate);
-    GlobalVar("rhs", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("lhs", ty.f32(), type::AddressSpace::kPrivate);
+    GlobalVar("rhs", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* body = Block(Break());
     auto* continuing = Block(CallStmt(Call("a_statement")));
@@ -142,7 +142,7 @@
     //   }
     // }
 
-    GlobalVar("rhs", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("rhs", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* body = Block(Decl(Var("lhs", ty.f32(), Expr(2.4_f))),  //
                        Decl(Var("other", ty.f32())),             //
diff --git a/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc b/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc
index b3440b8..bec778a 100644
--- a/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc
@@ -93,7 +93,7 @@
         ProgramBuilder& b = *this;
         auto* s = b.Structure("Data", members);
 
-        b.GlobalVar("data", b.ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite,
+        b.GlobalVar("data", b.ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite,
                     b.Group(1_a), b.Binding(0_a));
     }
 
@@ -101,7 +101,7 @@
         ProgramBuilder& b = *this;
         auto* s = b.Structure("Data", members);
 
-        b.GlobalVar("data", b.ty.Of(s), ast::AddressSpace::kUniform, ast::Access::kUndefined,
+        b.GlobalVar("data", b.ty.Of(s), type::AddressSpace::kUniform, type::Access::kUndefined,
                     b.Group(1_a), b.Binding(1_a));
     }
 
@@ -122,7 +122,7 @@
 
 TEST_F(HlslGeneratorImplTest_MemberAccessor, EmitExpression_MemberAccessor) {
     auto* s = Structure("Data", utils::Vector{Member("mem", ty.f32())});
-    GlobalVar("str", ty.Of(s), ast::AddressSpace::kPrivate);
+    GlobalVar("str", ty.Of(s), type::AddressSpace::kPrivate);
 
     auto* expr = MemberAccessor("str", "mem");
     WrapInFunction(Var("expr", ty.f32(), expr));
diff --git a/src/tint/writer/hlsl/generator_impl_sanitizer_test.cc b/src/tint/writer/hlsl/generator_impl_sanitizer_test.cc
index 761eb82..10c4147 100644
--- a/src/tint/writer/hlsl/generator_impl_sanitizer_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_sanitizer_test.cc
@@ -26,7 +26,7 @@
 
 TEST_F(HlslSanitizerTest, Call_ArrayLength) {
     auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
-    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(1_a),
               Group(2_a));
 
     Func("a_func", utils::Empty, ty.void_(),
@@ -60,7 +60,7 @@
                                          Member(0, "z", ty.f32()),
                                          Member(4, "a", ty.array<f32>(4)),
                                      });
-    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(1_a),
               Group(2_a));
 
     Func("a_func", utils::Empty, ty.void_(),
@@ -92,7 +92,7 @@
 
 TEST_F(HlslSanitizerTest, Call_ArrayLength_ViaLets) {
     auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
-    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(1_a),
               Group(2_a));
 
     auto* p = Let("p", AddressOf("b"));
@@ -129,9 +129,9 @@
 
 TEST_F(HlslSanitizerTest, Call_ArrayLength_ArrayLengthFromUniform) {
     auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
-    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(1_a),
               Group(2_a));
-    GlobalVar("c", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(2_a),
+    GlobalVar("c", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(2_a),
               Group(2_a));
 
     Func("a_func", utils::Empty, ty.void_(),
@@ -242,7 +242,7 @@
     // let p : ptr<function, i32> = &v;
     // let x : i32 = *p;
     auto* v = Var("v", ty.i32());
-    auto* p = Let("p", ty.pointer<i32>(ast::AddressSpace::kFunction), AddressOf(v));
+    auto* p = Let("p", ty.pointer<i32>(type::AddressSpace::kFunction), AddressOf(v));
     auto* x = Var("x", ty.i32(), Deref(p));
 
     Func("main", utils::Empty, ty.void_(),
@@ -276,11 +276,11 @@
     // let vp : ptr<function, vec4<f32>> = &(*mp)[2i];
     // let v : vec4<f32> = *vp;
     auto* a = Var("a", ty.array(ty.mat4x4<f32>(), 4_u));
-    auto* ap = Let("ap", ty.pointer(ty.array(ty.mat4x4<f32>(), 4_u), ast::AddressSpace::kFunction),
+    auto* ap = Let("ap", ty.pointer(ty.array(ty.mat4x4<f32>(), 4_u), type::AddressSpace::kFunction),
                    AddressOf(a));
-    auto* mp = Let("mp", ty.pointer(ty.mat4x4<f32>(), ast::AddressSpace::kFunction),
+    auto* mp = Let("mp", ty.pointer(ty.mat4x4<f32>(), type::AddressSpace::kFunction),
                    AddressOf(IndexAccessor(Deref(ap), 3_i)));
-    auto* vp = Let("vp", ty.pointer(ty.vec4<f32>(), ast::AddressSpace::kFunction),
+    auto* vp = Let("vp", ty.pointer(ty.vec4<f32>(), type::AddressSpace::kFunction),
                    AddressOf(IndexAccessor(Deref(mp), 2_i)));
     auto* v = Var("v", ty.vec4<f32>(), Deref(vp));
 
diff --git a/src/tint/writer/hlsl/generator_impl_switch_test.cc b/src/tint/writer/hlsl/generator_impl_switch_test.cc
index a84e632..698083a 100644
--- a/src/tint/writer/hlsl/generator_impl_switch_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_switch_test.cc
@@ -22,7 +22,7 @@
 using HlslGeneratorImplTest_Switch = TestHelper;
 
 TEST_F(HlslGeneratorImplTest_Switch, Emit_Switch) {
-    GlobalVar("cond", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("cond", ty.i32(), type::AddressSpace::kPrivate);
     auto* s = Switch(                             //
         Expr("cond"),                             //
         Case(CaseSelector(5_i), Block(Break())),  //
@@ -46,7 +46,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Switch, Emit_Switch_MixedDefault) {
-    GlobalVar("cond", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("cond", ty.i32(), type::AddressSpace::kPrivate);
     auto* s = Switch(  //
         Expr("cond"),  //
         Case(utils::Vector{CaseSelector(5_i), DefaultCaseSelector()}, Block(Break())));
@@ -67,8 +67,8 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Switch, Emit_Switch_OnlyDefaultCase) {
-    GlobalVar("cond", ty.i32(), ast::AddressSpace::kPrivate);
-    GlobalVar("a", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("cond", ty.i32(), type::AddressSpace::kPrivate);
+    GlobalVar("a", ty.i32(), type::AddressSpace::kPrivate);
     auto* s = Switch(  //
         Expr("cond"),  //
         DefaultCase(Block(Assign(Expr("a"), Expr(42_i)))));
diff --git a/src/tint/writer/hlsl/generator_impl_type_test.cc b/src/tint/writer/hlsl/generator_impl_type_test.cc
index 0b3b75e..493bc2a 100644
--- a/src/tint/writer/hlsl/generator_impl_type_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_type_test.cc
@@ -20,6 +20,7 @@
 #include "src/tint/type/sampled_texture.h"
 #include "src/tint/type/sampler.h"
 #include "src/tint/type/storage_texture.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/writer/hlsl/test_helper.h"
 
 using ::testing::HasSubstr;
@@ -33,52 +34,52 @@
 
 TEST_F(HlslGeneratorImplTest_Type, EmitType_Array) {
     auto* arr = ty.array<bool, 4>();
-    GlobalVar("G", arr, ast::AddressSpace::kPrivate);
+    GlobalVar("G", arr, type::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), ast::AddressSpace::kNone,
-                             ast::Access::kReadWrite, "ary"))
+    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), type::AddressSpace::kNone,
+                             type::Access::kReadWrite, "ary"))
         << gen.error();
     EXPECT_EQ(out.str(), "bool ary[4]");
 }
 
 TEST_F(HlslGeneratorImplTest_Type, EmitType_ArrayOfArray) {
     auto* arr = ty.array(ty.array<bool, 4>(), 5_u);
-    GlobalVar("G", arr, ast::AddressSpace::kPrivate);
+    GlobalVar("G", arr, type::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), ast::AddressSpace::kNone,
-                             ast::Access::kReadWrite, "ary"))
+    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), type::AddressSpace::kNone,
+                             type::Access::kReadWrite, "ary"))
         << gen.error();
     EXPECT_EQ(out.str(), "bool ary[5][4]");
 }
 
 TEST_F(HlslGeneratorImplTest_Type, EmitType_ArrayOfArrayOfArray) {
     auto* arr = ty.array(ty.array(ty.array<bool, 4>(), 5_u), 6_u);
-    GlobalVar("G", arr, ast::AddressSpace::kPrivate);
+    GlobalVar("G", arr, type::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), ast::AddressSpace::kNone,
-                             ast::Access::kReadWrite, "ary"))
+    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), type::AddressSpace::kNone,
+                             type::Access::kReadWrite, "ary"))
         << gen.error();
     EXPECT_EQ(out.str(), "bool ary[6][5][4]");
 }
 
 TEST_F(HlslGeneratorImplTest_Type, EmitType_Array_WithoutName) {
     auto* arr = ty.array<bool, 4>();
-    GlobalVar("G", arr, ast::AddressSpace::kPrivate);
+    GlobalVar("G", arr, type::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), ast::AddressSpace::kNone,
-                             ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), type::AddressSpace::kNone,
+                             type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "bool[4]");
 }
@@ -89,7 +90,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, bool_, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, bool_, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "bool");
 }
@@ -100,7 +101,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, f16, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, f16, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "float16_t");
 }
@@ -111,7 +112,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, f32, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, f32, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "float");
 }
@@ -122,7 +123,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, i32, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, i32, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "int");
 }
@@ -135,7 +136,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, mat2x3, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, mat2x3, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "matrix<float16_t, 2, 3>");
 }
@@ -148,7 +149,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, mat2x3, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, mat2x3, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "float2x3");
 }
@@ -158,7 +159,7 @@
                                  Member("a", ty.i32()),
                                  Member("b", ty.f32()),
                              });
-    GlobalVar("g", ty.Of(s), ast::AddressSpace::kPrivate);
+    GlobalVar("g", ty.Of(s), type::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
@@ -177,7 +178,7 @@
                                  Member("a", ty.i32()),
                                  Member("b", ty.f32()),
                              });
-    GlobalVar("g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(0_a),
+    GlobalVar("g", ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite, Binding(0_a),
               Group(0_a));
 
     GeneratorImpl& gen = Build();
@@ -191,13 +192,13 @@
                                  Member("a", ty.i32()),
                                  Member("b", ty.f32()),
                              });
-    GlobalVar("g", ty.Of(s), ast::AddressSpace::kPrivate);
+    GlobalVar("g", ty.Of(s), type::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
     auto* sem_s = program->TypeOf(s)->As<sem::Struct>();
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, sem_s, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, sem_s, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "S");
 }
@@ -207,7 +208,7 @@
                                  Member("double", ty.i32()),
                                  Member("float", ty.f32()),
                              });
-    GlobalVar("g", ty.Of(s), ast::AddressSpace::kPrivate);
+    GlobalVar("g", ty.Of(s), type::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = SanitizeAndBuild();
 
@@ -224,7 +225,7 @@
                                  Member("a", ty.i32(), utils::Vector{MemberOffset(0_a)}),
                                  Member("b", ty.f32(), utils::Vector{MemberOffset(8_a)}),
                              });
-    GlobalVar("g", ty.Of(s), ast::AddressSpace::kPrivate);
+    GlobalVar("g", ty.Of(s), type::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
@@ -244,7 +245,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, u32, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, u32, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "uint");
 }
@@ -256,7 +257,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, vec3, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, vec3, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "float3");
 }
@@ -267,7 +268,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, void_, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, void_, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "void");
 }
@@ -278,7 +279,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, sampler, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, sampler, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "SamplerState");
 }
@@ -289,13 +290,13 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, sampler, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, sampler, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "SamplerComparisonState");
 }
 
 struct HlslDepthTextureData {
-    ast::TextureDimension dim;
+    type::TextureDimension dim;
     std::string result;
 };
 inline std::ostream& operator<<(std::ostream& out, HlslDepthTextureData data) {
@@ -326,18 +327,18 @@
 INSTANTIATE_TEST_SUITE_P(
     HlslGeneratorImplTest_Type,
     HlslDepthTexturesTest,
-    testing::Values(HlslDepthTextureData{ast::TextureDimension::k2d,
+    testing::Values(HlslDepthTextureData{type::TextureDimension::k2d,
                                          "Texture2D tex : register(t1, space2);"},
-                    HlslDepthTextureData{ast::TextureDimension::k2dArray,
+                    HlslDepthTextureData{type::TextureDimension::k2dArray,
                                          "Texture2DArray tex : register(t1, space2);"},
-                    HlslDepthTextureData{ast::TextureDimension::kCube,
+                    HlslDepthTextureData{type::TextureDimension::kCube,
                                          "TextureCube tex : register(t1, space2);"},
-                    HlslDepthTextureData{ast::TextureDimension::kCubeArray,
+                    HlslDepthTextureData{type::TextureDimension::kCubeArray,
                                          "TextureCubeArray tex : register(t1, space2);"}));
 
 using HlslDepthMultisampledTexturesTest = TestHelper;
 TEST_F(HlslDepthMultisampledTexturesTest, Emit) {
-    auto* t = ty.depth_multisampled_texture(ast::TextureDimension::k2d);
+    auto* t = ty.depth_multisampled_texture(type::TextureDimension::k2d);
 
     GlobalVar("tex", t, Binding(1_a), Group(2_a));
 
@@ -357,7 +358,7 @@
 
 enum class TextureDataType { F32, U32, I32 };
 struct HlslSampledTextureData {
-    ast::TextureDimension dim;
+    type::TextureDimension dim;
     TextureDataType datatype;
     std::string result;
 };
@@ -402,111 +403,111 @@
                          HlslSampledTexturesTest,
                          testing::Values(
                              HlslSampledTextureData{
-                                 ast::TextureDimension::k1d,
+                                 type::TextureDimension::k1d,
                                  TextureDataType::F32,
                                  "Texture1D<float4> tex : register(t1, space2);",
                              },
                              HlslSampledTextureData{
-                                 ast::TextureDimension::k2d,
+                                 type::TextureDimension::k2d,
                                  TextureDataType::F32,
                                  "Texture2D<float4> tex : register(t1, space2);",
                              },
                              HlslSampledTextureData{
-                                 ast::TextureDimension::k2dArray,
+                                 type::TextureDimension::k2dArray,
                                  TextureDataType::F32,
                                  "Texture2DArray<float4> tex : register(t1, space2);",
                              },
                              HlslSampledTextureData{
-                                 ast::TextureDimension::k3d,
+                                 type::TextureDimension::k3d,
                                  TextureDataType::F32,
                                  "Texture3D<float4> tex : register(t1, space2);",
                              },
                              HlslSampledTextureData{
-                                 ast::TextureDimension::kCube,
+                                 type::TextureDimension::kCube,
                                  TextureDataType::F32,
                                  "TextureCube<float4> tex : register(t1, space2);",
                              },
                              HlslSampledTextureData{
-                                 ast::TextureDimension::kCubeArray,
+                                 type::TextureDimension::kCubeArray,
                                  TextureDataType::F32,
                                  "TextureCubeArray<float4> tex : register(t1, space2);",
                              },
                              HlslSampledTextureData{
-                                 ast::TextureDimension::k1d,
+                                 type::TextureDimension::k1d,
                                  TextureDataType::U32,
                                  "Texture1D<uint4> tex : register(t1, space2);",
                              },
                              HlslSampledTextureData{
-                                 ast::TextureDimension::k2d,
+                                 type::TextureDimension::k2d,
                                  TextureDataType::U32,
                                  "Texture2D<uint4> tex : register(t1, space2);",
                              },
                              HlslSampledTextureData{
-                                 ast::TextureDimension::k2dArray,
+                                 type::TextureDimension::k2dArray,
                                  TextureDataType::U32,
                                  "Texture2DArray<uint4> tex : register(t1, space2);",
                              },
                              HlslSampledTextureData{
-                                 ast::TextureDimension::k3d,
+                                 type::TextureDimension::k3d,
                                  TextureDataType::U32,
                                  "Texture3D<uint4> tex : register(t1, space2);",
                              },
                              HlslSampledTextureData{
-                                 ast::TextureDimension::kCube,
+                                 type::TextureDimension::kCube,
                                  TextureDataType::U32,
                                  "TextureCube<uint4> tex : register(t1, space2);",
                              },
                              HlslSampledTextureData{
-                                 ast::TextureDimension::kCubeArray,
+                                 type::TextureDimension::kCubeArray,
                                  TextureDataType::U32,
                                  "TextureCubeArray<uint4> tex : register(t1, space2);",
                              },
                              HlslSampledTextureData{
-                                 ast::TextureDimension::k1d,
+                                 type::TextureDimension::k1d,
                                  TextureDataType::I32,
                                  "Texture1D<int4> tex : register(t1, space2);",
                              },
                              HlslSampledTextureData{
-                                 ast::TextureDimension::k2d,
+                                 type::TextureDimension::k2d,
                                  TextureDataType::I32,
                                  "Texture2D<int4> tex : register(t1, space2);",
                              },
                              HlslSampledTextureData{
-                                 ast::TextureDimension::k2dArray,
+                                 type::TextureDimension::k2dArray,
                                  TextureDataType::I32,
                                  "Texture2DArray<int4> tex : register(t1, space2);",
                              },
                              HlslSampledTextureData{
-                                 ast::TextureDimension::k3d,
+                                 type::TextureDimension::k3d,
                                  TextureDataType::I32,
                                  "Texture3D<int4> tex : register(t1, space2);",
                              },
                              HlslSampledTextureData{
-                                 ast::TextureDimension::kCube,
+                                 type::TextureDimension::kCube,
                                  TextureDataType::I32,
                                  "TextureCube<int4> tex : register(t1, space2);",
                              },
                              HlslSampledTextureData{
-                                 ast::TextureDimension::kCubeArray,
+                                 type::TextureDimension::kCubeArray,
                                  TextureDataType::I32,
                                  "TextureCubeArray<int4> tex : register(t1, space2);",
                              }));
 
 TEST_F(HlslGeneratorImplTest_Type, EmitMultisampledTexture) {
     auto* f32 = create<type::F32>();
-    auto* s = create<type::MultisampledTexture>(ast::TextureDimension::k2d, f32);
+    auto* s = create<type::MultisampledTexture>(type::TextureDimension::k2d, f32);
 
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, s, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, s, type::AddressSpace::kNone, type::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "Texture2DMS<float4>");
 }
 
 struct HlslStorageTextureData {
-    ast::TextureDimension dim;
-    ast::TexelFormat imgfmt;
+    type::TextureDimension dim;
+    type::TexelFormat imgfmt;
     std::string result;
 };
 inline std::ostream& operator<<(std::ostream& out, HlslStorageTextureData data) {
@@ -517,7 +518,7 @@
 TEST_P(HlslStorageTexturesTest, Emit) {
     auto params = GetParam();
 
-    auto* t = ty.storage_texture(params.dim, params.imgfmt, ast::Access::kWrite);
+    auto* t = ty.storage_texture(params.dim, params.imgfmt, type::Access::kWrite);
 
     GlobalVar("tex", t,
               utils::Vector{
@@ -542,31 +543,31 @@
     HlslGeneratorImplTest_Type,
     HlslStorageTexturesTest,
     testing::Values(
-        HlslStorageTextureData{ast::TextureDimension::k1d, ast::TexelFormat::kRgba8Unorm,
+        HlslStorageTextureData{type::TextureDimension::k1d, type::TexelFormat::kRgba8Unorm,
                                "RWTexture1D<float4> tex : register(u1, space2);"},
-        HlslStorageTextureData{ast::TextureDimension::k2d, ast::TexelFormat::kRgba16Float,
+        HlslStorageTextureData{type::TextureDimension::k2d, type::TexelFormat::kRgba16Float,
                                "RWTexture2D<float4> tex : register(u1, space2);"},
-        HlslStorageTextureData{ast::TextureDimension::k2dArray, ast::TexelFormat::kR32Float,
+        HlslStorageTextureData{type::TextureDimension::k2dArray, type::TexelFormat::kR32Float,
                                "RWTexture2DArray<float4> tex : register(u1, space2);"},
-        HlslStorageTextureData{ast::TextureDimension::k3d, ast::TexelFormat::kRg32Float,
+        HlslStorageTextureData{type::TextureDimension::k3d, type::TexelFormat::kRg32Float,
                                "RWTexture3D<float4> tex : register(u1, space2);"},
-        HlslStorageTextureData{ast::TextureDimension::k1d, ast::TexelFormat::kRgba32Float,
+        HlslStorageTextureData{type::TextureDimension::k1d, type::TexelFormat::kRgba32Float,
                                "RWTexture1D<float4> tex : register(u1, space2);"},
-        HlslStorageTextureData{ast::TextureDimension::k2d, ast::TexelFormat::kRgba16Uint,
+        HlslStorageTextureData{type::TextureDimension::k2d, type::TexelFormat::kRgba16Uint,
                                "RWTexture2D<uint4> tex : register(u1, space2);"},
-        HlslStorageTextureData{ast::TextureDimension::k2dArray, ast::TexelFormat::kR32Uint,
+        HlslStorageTextureData{type::TextureDimension::k2dArray, type::TexelFormat::kR32Uint,
                                "RWTexture2DArray<uint4> tex : register(u1, space2);"},
-        HlslStorageTextureData{ast::TextureDimension::k3d, ast::TexelFormat::kRg32Uint,
+        HlslStorageTextureData{type::TextureDimension::k3d, type::TexelFormat::kRg32Uint,
                                "RWTexture3D<uint4> tex : register(u1, space2);"},
-        HlslStorageTextureData{ast::TextureDimension::k1d, ast::TexelFormat::kRgba32Uint,
+        HlslStorageTextureData{type::TextureDimension::k1d, type::TexelFormat::kRgba32Uint,
                                "RWTexture1D<uint4> tex : register(u1, space2);"},
-        HlslStorageTextureData{ast::TextureDimension::k2d, ast::TexelFormat::kRgba16Sint,
+        HlslStorageTextureData{type::TextureDimension::k2d, type::TexelFormat::kRgba16Sint,
                                "RWTexture2D<int4> tex : register(u1, space2);"},
-        HlslStorageTextureData{ast::TextureDimension::k2dArray, ast::TexelFormat::kR32Sint,
+        HlslStorageTextureData{type::TextureDimension::k2dArray, type::TexelFormat::kR32Sint,
                                "RWTexture2DArray<int4> tex : register(u1, space2);"},
-        HlslStorageTextureData{ast::TextureDimension::k3d, ast::TexelFormat::kRg32Sint,
+        HlslStorageTextureData{type::TextureDimension::k3d, type::TexelFormat::kRg32Sint,
                                "RWTexture3D<int4> tex : register(u1, space2);"},
-        HlslStorageTextureData{ast::TextureDimension::k1d, ast::TexelFormat::kRgba32Sint,
+        HlslStorageTextureData{type::TextureDimension::k1d, type::TexelFormat::kRgba32Sint,
                                "RWTexture1D<int4> tex : register(u1, space2);"}));
 
 }  // namespace
diff --git a/src/tint/writer/hlsl/generator_impl_unary_op_test.cc b/src/tint/writer/hlsl/generator_impl_unary_op_test.cc
index c7f0336..93a61dc 100644
--- a/src/tint/writer/hlsl/generator_impl_unary_op_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_unary_op_test.cc
@@ -20,7 +20,7 @@
 using HlslUnaryOpTest = TestHelper;
 
 TEST_F(HlslUnaryOpTest, AddressOf) {
-    GlobalVar("expr", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("expr", ty.f32(), type::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kAddressOf, Expr("expr"));
     WrapInFunction(op);
 
@@ -32,7 +32,7 @@
 }
 
 TEST_F(HlslUnaryOpTest, Complement) {
-    GlobalVar("expr", ty.u32(), ast::AddressSpace::kPrivate);
+    GlobalVar("expr", ty.u32(), type::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kComplement, Expr("expr"));
     WrapInFunction(op);
 
@@ -44,7 +44,7 @@
 }
 
 TEST_F(HlslUnaryOpTest, Indirection) {
-    GlobalVar("G", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("G", ty.f32(), type::AddressSpace::kPrivate);
     auto* p = Let("expr", create<ast::UnaryOpExpression>(ast::UnaryOp::kAddressOf, Expr("G")));
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kIndirection, Expr("expr"));
     WrapInFunction(p, op);
@@ -57,7 +57,7 @@
 }
 
 TEST_F(HlslUnaryOpTest, Not) {
-    GlobalVar("expr", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("expr", ty.bool_(), type::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kNot, Expr("expr"));
     WrapInFunction(op);
 
@@ -69,7 +69,7 @@
 }
 
 TEST_F(HlslUnaryOpTest, Negation) {
-    GlobalVar("expr", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("expr", ty.i32(), type::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kNegation, Expr("expr"));
     WrapInFunction(op);
 
diff --git a/src/tint/writer/hlsl/generator_impl_variable_decl_statement_test.cc b/src/tint/writer/hlsl/generator_impl_variable_decl_statement_test.cc
index 5df476a..11bf317 100644
--- a/src/tint/writer/hlsl/generator_impl_variable_decl_statement_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_variable_decl_statement_test.cc
@@ -357,7 +357,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Private) {
-    GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.f32(), type::AddressSpace::kPrivate);
 
     WrapInFunction(Expr("a"));
 
diff --git a/src/tint/writer/hlsl/generator_impl_workgroup_var_test.cc b/src/tint/writer/hlsl/generator_impl_workgroup_var_test.cc
index 4ec7af2..ea30962 100644
--- a/src/tint/writer/hlsl/generator_impl_workgroup_var_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_workgroup_var_test.cc
@@ -27,7 +27,7 @@
 using HlslGeneratorImplTest_WorkgroupVar = TestHelper;
 
 TEST_F(HlslGeneratorImplTest_WorkgroupVar, Basic) {
-    GlobalVar("wg", ty.f32(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("wg", ty.f32(), type::AddressSpace::kWorkgroup);
 
     Func("main", utils::Empty, ty.void_(), utils::Vector{Assign("wg", 1.2_f)},
          utils::Vector{
@@ -43,7 +43,7 @@
 TEST_F(HlslGeneratorImplTest_WorkgroupVar, Aliased) {
     auto* alias = Alias("F32", ty.f32());
 
-    GlobalVar("wg", ty.Of(alias), ast::AddressSpace::kWorkgroup);
+    GlobalVar("wg", ty.Of(alias), type::AddressSpace::kWorkgroup);
 
     Func("main", utils::Empty, ty.void_(), utils::Vector{Assign("wg", 1.2_f)},
          utils::Vector{
diff --git a/src/tint/writer/msl/generator_impl.cc b/src/tint/writer/msl/generator_impl.cc
index 4889d7d..251483e 100644
--- a/src/tint/writer/msl/generator_impl.cc
+++ b/src/tint/writer/msl/generator_impl.cc
@@ -72,6 +72,7 @@
 #include "src/tint/type/reference.h"
 #include "src/tint/type/sampled_texture.h"
 #include "src/tint/type/storage_texture.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/type/u32.h"
 #include "src/tint/type/vector.h"
 #include "src/tint/type/void.h"
@@ -204,7 +205,7 @@
         // Use the SSBO binding numbers as the indices for the buffer size lookups.
         for (auto* var : in->AST().GlobalVariables()) {
             auto* global = in->Sem().Get<sem::GlobalVariable>(var);
-            if (global && global->AddressSpace() == ast::AddressSpace::kStorage) {
+            if (global && global->AddressSpace() == type::AddressSpace::kStorage) {
                 array_length_from_uniform_cfg.bindpoint_to_size_index.emplace(
                     global->BindingPoint(), global->BindingPoint().binding);
             }
@@ -1020,25 +1021,25 @@
     };
 
     // MSL requires that `lod` is a constant 0 for 1D textures.
-    bool level_is_constant_zero = texture_type->dim() == ast::TextureDimension::k1d;
+    bool level_is_constant_zero = texture_type->dim() == type::TextureDimension::k1d;
 
     switch (builtin->Type()) {
         case sem::BuiltinType::kTextureDimensions: {
             std::vector<const char*> dims;
             switch (texture_type->dim()) {
-                case ast::TextureDimension::kNone:
+                case type::TextureDimension::kNone:
                     diagnostics_.add_error(diag::System::Writer, "texture dimension is kNone");
                     return false;
-                case ast::TextureDimension::k1d:
+                case type::TextureDimension::k1d:
                     dims = {"width"};
                     break;
-                case ast::TextureDimension::k2d:
-                case ast::TextureDimension::k2dArray:
-                case ast::TextureDimension::kCube:
-                case ast::TextureDimension::kCubeArray:
+                case type::TextureDimension::k2d:
+                case type::TextureDimension::k2dArray:
+                case type::TextureDimension::kCube:
+                case type::TextureDimension::kCubeArray:
                     dims = {"width", "height"};
                     break;
-                case ast::TextureDimension::k3d:
+                case type::TextureDimension::k3d:
                     dims = {"width", "height", "depth"};
                     break;
             }
@@ -1155,14 +1156,14 @@
             if (usage == Usage::kCoords && e->Type()->UnwrapRef()->is_integer_scalar_or_vector()) {
                 casted = true;
                 switch (texture_type->dim()) {
-                    case ast::TextureDimension::k1d:
+                    case type::TextureDimension::k1d:
                         out << "uint(";
                         break;
-                    case ast::TextureDimension::k2d:
-                    case ast::TextureDimension::k2dArray:
+                    case type::TextureDimension::k2d:
+                    case type::TextureDimension::k2dArray:
                         out << "uint2(";
                         break;
-                    case ast::TextureDimension::k3d:
+                    case type::TextureDimension::k3d:
                         out << "uint3(";
                         break;
                     default:
@@ -1212,17 +1213,17 @@
     if (auto* ddx = arg(Usage::kDdx)) {
         auto dim = texture_type->dim();
         switch (dim) {
-            case ast::TextureDimension::k2d:
-            case ast::TextureDimension::k2dArray:
+            case type::TextureDimension::k2d:
+            case type::TextureDimension::k2dArray:
                 maybe_write_comma();
                 out << "gradient2d(";
                 break;
-            case ast::TextureDimension::k3d:
+            case type::TextureDimension::k3d:
                 maybe_write_comma();
                 out << "gradient3d(";
                 break;
-            case ast::TextureDimension::kCube:
-            case ast::TextureDimension::kCubeArray:
+            case type::TextureDimension::kCube:
+            case type::TextureDimension::kCubeArray:
                 maybe_write_comma();
                 out << "gradientcube(";
                 break;
@@ -1257,8 +1258,8 @@
         if (!has_offset) {
             // offset argument may need to be provided if we have a component.
             switch (texture_type->dim()) {
-                case ast::TextureDimension::k2d:
-                case ast::TextureDimension::k2dArray:
+                case type::TextureDimension::k2d:
+                case type::TextureDimension::k2dArray:
                     out << "int2(0), ";
                     break;
                 default:
@@ -2034,12 +2035,12 @@
                 }
             } else if (auto* ptr = param->type->As<ast::Pointer>()) {
                 auto sc = ptr->address_space;
-                if (sc == ast::AddressSpace::kWorkgroup) {
+                if (sc == type::AddressSpace::kWorkgroup) {
                     auto& allocations = workgroup_allocations_[func_name];
                     out << " [[threadgroup(" << allocations.size() << ")]]";
                     allocations.push_back(program_->Sem().Get(ptr->type)->Size());
-                } else if (TINT_LIKELY(sc == ast::AddressSpace::kStorage ||
-                                       sc == ast::AddressSpace::kUniform)) {
+                } else if (TINT_LIKELY(sc == type::AddressSpace::kStorage ||
+                                       sc == type::AddressSpace::kUniform)) {
                     uint32_t binding = get_binding_index(param);
                     if (binding == kInvalidBindingIndex) {
                         return false;
@@ -2584,7 +2585,7 @@
             return true;
         },
         [&](const type::Pointer* ptr) {
-            if (ptr->Access() == ast::Access::kRead) {
+            if (ptr->Access() == type::Access::kRead) {
                 out << "const ";
             }
             if (!EmitAddressSpace(out, ptr->AddressSpace())) {
@@ -2624,22 +2625,22 @@
             }
 
             switch (tex->dim()) {
-                case ast::TextureDimension::k1d:
+                case type::TextureDimension::k1d:
                     out << "1d";
                     break;
-                case ast::TextureDimension::k2d:
+                case type::TextureDimension::k2d:
                     out << "2d";
                     break;
-                case ast::TextureDimension::k2dArray:
+                case type::TextureDimension::k2dArray:
                     out << "2d_array";
                     break;
-                case ast::TextureDimension::k3d:
+                case type::TextureDimension::k3d:
                     out << "3d";
                     break;
-                case ast::TextureDimension::kCube:
+                case type::TextureDimension::kCube:
                     out << "cube";
                     break;
-                case ast::TextureDimension::kCubeArray:
+                case type::TextureDimension::kCubeArray:
                     out << "cube_array";
                     break;
                 default:
@@ -2668,9 +2669,9 @@
                     }
 
                     std::string access_str;
-                    if (storage->access() == ast::Access::kRead) {
+                    if (storage->access() == type::Access::kRead) {
                         out << ", access::read";
-                    } else if (storage->access() == ast::Access::kWrite) {
+                    } else if (storage->access() == type::Access::kWrite) {
                         out << ", access::write";
                     } else {
                         diagnostics_.add_error(diag::System::Writer,
@@ -2734,20 +2735,20 @@
     return true;
 }
 
-bool GeneratorImpl::EmitAddressSpace(std::ostream& out, ast::AddressSpace sc) {
+bool GeneratorImpl::EmitAddressSpace(std::ostream& out, type::AddressSpace sc) {
     switch (sc) {
-        case ast::AddressSpace::kFunction:
-        case ast::AddressSpace::kPrivate:
-        case ast::AddressSpace::kHandle:
+        case type::AddressSpace::kFunction:
+        case type::AddressSpace::kPrivate:
+        case type::AddressSpace::kHandle:
             out << "thread";
             return true;
-        case ast::AddressSpace::kWorkgroup:
+        case type::AddressSpace::kWorkgroup:
             out << "threadgroup";
             return true;
-        case ast::AddressSpace::kStorage:
+        case type::AddressSpace::kStorage:
             out << "device";
             return true;
-        case ast::AddressSpace::kUniform:
+        case type::AddressSpace::kUniform:
             out << "constant";
             return true;
         default:
@@ -2999,14 +3000,14 @@
     auto out = line();
 
     switch (sem->AddressSpace()) {
-        case ast::AddressSpace::kFunction:
-        case ast::AddressSpace::kHandle:
-        case ast::AddressSpace::kNone:
+        case type::AddressSpace::kFunction:
+        case type::AddressSpace::kHandle:
+        case type::AddressSpace::kNone:
             break;
-        case ast::AddressSpace::kPrivate:
+        case type::AddressSpace::kPrivate:
             out << "thread ";
             break;
-        case ast::AddressSpace::kWorkgroup:
+        case type::AddressSpace::kWorkgroup:
             out << "threadgroup ";
             break;
         default:
@@ -3028,9 +3029,9 @@
         if (!EmitExpression(out, var->initializer)) {
             return false;
         }
-    } else if (sem->AddressSpace() == ast::AddressSpace::kPrivate ||
-               sem->AddressSpace() == ast::AddressSpace::kFunction ||
-               sem->AddressSpace() == ast::AddressSpace::kNone) {
+    } else if (sem->AddressSpace() == type::AddressSpace::kPrivate ||
+               sem->AddressSpace() == type::AddressSpace::kFunction ||
+               sem->AddressSpace() == type::AddressSpace::kNone) {
         out << " = ";
         if (!EmitZeroValue(out, type)) {
             return false;
@@ -3048,14 +3049,14 @@
     auto out = line();
 
     switch (sem->AddressSpace()) {
-        case ast::AddressSpace::kFunction:
-        case ast::AddressSpace::kHandle:
-        case ast::AddressSpace::kNone:
+        case type::AddressSpace::kFunction:
+        case type::AddressSpace::kHandle:
+        case type::AddressSpace::kNone:
             break;
-        case ast::AddressSpace::kPrivate:
+        case type::AddressSpace::kPrivate:
             out << "thread ";
             break;
-        case ast::AddressSpace::kWorkgroup:
+        case type::AddressSpace::kWorkgroup:
             out << "threadgroup ";
             break;
         default:
diff --git a/src/tint/writer/msl/generator_impl.h b/src/tint/writer/msl/generator_impl.h
index 64c83af..f983506 100644
--- a/src/tint/writer/msl/generator_impl.h
+++ b/src/tint/writer/msl/generator_impl.h
@@ -326,7 +326,7 @@
     /// @param out the output of the type stream
     /// @param sc the address space to generate
     /// @returns true if the address space is emitted
-    bool EmitAddressSpace(std::ostream& out, ast::AddressSpace sc);
+    bool EmitAddressSpace(std::ostream& out, type::AddressSpace sc);
     /// Handles generating a struct declaration. If the structure has already been emitted, then
     /// this function will simply return `true` without emitting anything.
     /// @param buffer the text buffer that the type declaration will be written to
@@ -410,7 +410,7 @@
     /// Name of atomicCompareExchangeWeak() helper for the given pointer storage
     /// class and struct return type
     using ACEWKeyType =
-        utils::UnorderedKeyWrapper<std::tuple<ast::AddressSpace, const sem::Struct*>>;
+        utils::UnorderedKeyWrapper<std::tuple<type::AddressSpace, const sem::Struct*>>;
     std::unordered_map<ACEWKeyType, std::string> atomicCompareExchangeWeak_;
 
     /// Unique name of the 'TINT_INVARIANT' preprocessor define.
diff --git a/src/tint/writer/msl/generator_impl_array_accessor_test.cc b/src/tint/writer/msl/generator_impl_array_accessor_test.cc
index 771d537..eae2c17 100644
--- a/src/tint/writer/msl/generator_impl_array_accessor_test.cc
+++ b/src/tint/writer/msl/generator_impl_array_accessor_test.cc
@@ -34,7 +34,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, IndexAccessor_OfDref) {
-    GlobalVar("ary", ty.array<i32, 10>(), ast::AddressSpace::kPrivate);
+    GlobalVar("ary", ty.array<i32, 10>(), type::AddressSpace::kPrivate);
 
     auto* p = Let("p", AddressOf("ary"));
     auto* expr = IndexAccessor(Deref("p"), 5_i);
diff --git a/src/tint/writer/msl/generator_impl_builtin_test.cc b/src/tint/writer/msl/generator_impl_builtin_test.cc
index 7a69a14..baaab18 100644
--- a/src/tint/writer/msl/generator_impl_builtin_test.cc
+++ b/src/tint/writer/msl/generator_impl_builtin_test.cc
@@ -216,21 +216,21 @@
     if (param.type == CallParamType::kF16) {
         Enable(ast::Extension::kF16);
 
-        GlobalVar("h2", ty.vec2<f16>(), ast::AddressSpace::kPrivate);
-        GlobalVar("h3", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
-        GlobalVar("hm2x2", ty.mat2x2<f16>(), ast::AddressSpace::kPrivate);
-        GlobalVar("hm3x2", ty.mat3x2<f16>(), ast::AddressSpace::kPrivate);
+        GlobalVar("h2", ty.vec2<f16>(), type::AddressSpace::kPrivate);
+        GlobalVar("h3", ty.vec3<f16>(), type::AddressSpace::kPrivate);
+        GlobalVar("hm2x2", ty.mat2x2<f16>(), type::AddressSpace::kPrivate);
+        GlobalVar("hm3x2", ty.mat3x2<f16>(), type::AddressSpace::kPrivate);
     }
 
-    GlobalVar("f2", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("f3", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("f4", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("u1", ty.u32(), ast::AddressSpace::kPrivate);
-    GlobalVar("u2", ty.vec2<u32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("i2", ty.vec2<i32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("b2", ty.vec2<bool>(), ast::AddressSpace::kPrivate);
-    GlobalVar("m2x2", ty.mat2x2<f32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("m3x2", ty.mat3x2<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("f2", ty.vec2<f32>(), type::AddressSpace::kPrivate);
+    GlobalVar("f3", ty.vec3<f32>(), type::AddressSpace::kPrivate);
+    GlobalVar("f4", ty.vec4<f32>(), type::AddressSpace::kPrivate);
+    GlobalVar("u1", ty.u32(), type::AddressSpace::kPrivate);
+    GlobalVar("u2", ty.vec2<u32>(), type::AddressSpace::kPrivate);
+    GlobalVar("i2", ty.vec2<i32>(), type::AddressSpace::kPrivate);
+    GlobalVar("b2", ty.vec2<bool>(), type::AddressSpace::kPrivate);
+    GlobalVar("m2x2", ty.mat2x2<f32>(), type::AddressSpace::kPrivate);
+    GlobalVar("m3x2", ty.mat3x2<f32>(), type::AddressSpace::kPrivate);
 
     auto* call = GenerateCall(param.builtin, param.type, this);
     ASSERT_NE(nullptr, call) << "Unhandled builtin";
@@ -370,8 +370,8 @@
                     "unpack_unorm2x16_to_float"}));
 
 TEST_F(MslGeneratorImplTest, Builtin_Call) {
-    GlobalVar("param1", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
-    GlobalVar("param2", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("param1", ty.vec2<f32>(), type::AddressSpace::kPrivate);
+    GlobalVar("param2", ty.vec2<f32>(), type::AddressSpace::kPrivate);
 
     auto* call = Call("dot", "param1", "param2");
     WrapInFunction(CallStmt(call));
@@ -1065,7 +1065,7 @@
 
 TEST_F(MslGeneratorImplTest, Pack2x16Float) {
     auto* call = Call("pack2x16float", "p1");
-    GlobalVar("p1", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("p1", ty.vec2<f32>(), type::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
 
     GeneratorImpl& gen = Build();
@@ -1077,7 +1077,7 @@
 
 TEST_F(MslGeneratorImplTest, Unpack2x16Float) {
     auto* call = Call("unpack2x16float", "p1");
-    GlobalVar("p1", ty.u32(), ast::AddressSpace::kPrivate);
+    GlobalVar("p1", ty.u32(), type::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
 
     GeneratorImpl& gen = Build();
@@ -1088,7 +1088,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, DotI32) {
-    GlobalVar("v", ty.vec3<i32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("v", ty.vec3<i32>(), type::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(Call("dot", "v", "v")));
 
     GeneratorImpl& gen = SanitizeAndBuild();
diff --git a/src/tint/writer/msl/generator_impl_call_test.cc b/src/tint/writer/msl/generator_impl_call_test.cc
index 75504fb..4449c2b 100644
--- a/src/tint/writer/msl/generator_impl_call_test.cc
+++ b/src/tint/writer/msl/generator_impl_call_test.cc
@@ -45,8 +45,8 @@
          utils::Vector{
              Return(1.23_f),
          });
-    GlobalVar("param1", ty.f32(), ast::AddressSpace::kPrivate);
-    GlobalVar("param2", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("param1", ty.f32(), type::AddressSpace::kPrivate);
+    GlobalVar("param2", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* call = Call("my_func", "param1", "param2");
     WrapInFunction(call);
@@ -65,8 +65,8 @@
              Param(Sym(), ty.f32()),
          },
          ty.void_(), utils::Empty, utils::Empty);
-    GlobalVar("param1", ty.f32(), ast::AddressSpace::kPrivate);
-    GlobalVar("param2", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("param1", ty.f32(), type::AddressSpace::kPrivate);
+    GlobalVar("param2", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* call = Call("my_func", "param1", "param2");
     auto* stmt = CallStmt(call);
diff --git a/src/tint/writer/msl/generator_impl_function_test.cc b/src/tint/writer/msl/generator_impl_function_test.cc
index 3fa5a21..0b01e1c 100644
--- a/src/tint/writer/msl/generator_impl_function_test.cc
+++ b/src/tint/writer/msl/generator_impl_function_test.cc
@@ -342,7 +342,7 @@
                                     Member("b", ty.f32()),
                                 });
 
-    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Group(0_a),
+    GlobalVar("coord", ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite, Group(0_a),
               Binding(0_a));
 
     auto* var = Var("v", ty.f32(), MemberAccessor("coord", "b"));
@@ -381,7 +381,7 @@
                                     Member("b", ty.f32()),
                                 });
 
-    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Group(0_a),
+    GlobalVar("coord", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Group(0_a),
               Binding(0_a));
 
     auto* var = Var("v", ty.f32(), MemberAccessor("coord", "b"));
@@ -417,7 +417,7 @@
 TEST_F(MslGeneratorImplTest, Emit_Attribute_Called_By_EntryPoint_With_Uniform) {
     auto* ubo_ty = Structure("UBO", utils::Vector{Member("coord", ty.vec4<f32>())});
     auto* ubo =
-        GlobalVar("ubo", ty.Of(ubo_ty), ast::AddressSpace::kUniform, Group(0_a), Binding(0_a));
+        GlobalVar("ubo", ty.Of(ubo_ty), type::AddressSpace::kUniform, Group(0_a), Binding(0_a));
 
     Func("sub_func",
          utils::Vector{
@@ -467,7 +467,7 @@
                                     Member("b", ty.f32()),
                                 });
 
-    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Group(0_a),
+    GlobalVar("coord", ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite, Group(0_a),
               Binding(0_a));
 
     Func("sub_func",
@@ -519,7 +519,7 @@
                                     Member("b", ty.f32()),
                                 });
 
-    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Group(0_a),
+    GlobalVar("coord", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Group(0_a),
               Binding(0_a));
 
     Func("sub_func",
@@ -657,7 +657,7 @@
 
     auto* s = Structure("Data", utils::Vector{Member("d", ty.f32())});
 
-    GlobalVar("data", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Group(0_a),
+    GlobalVar("data", ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite, Group(0_a),
               Binding(0_a));
 
     {
diff --git a/src/tint/writer/msl/generator_impl_import_test.cc b/src/tint/writer/msl/generator_impl_import_test.cc
index 07f4acd..6fd95ae 100644
--- a/src/tint/writer/msl/generator_impl_import_test.cc
+++ b/src/tint/writer/msl/generator_impl_import_test.cc
@@ -234,7 +234,7 @@
                                          MslImportData{"clamp", "clamp"}));
 
 TEST_F(MslGeneratorImplTest, MslImportData_Determinant) {
-    GlobalVar("var", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("var", ty.mat3x3<f32>(), type::AddressSpace::kPrivate);
 
     auto* expr = Call("determinant", "var");
 
@@ -248,7 +248,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, MslImportData_QuantizeToF16_Scalar) {
-    GlobalVar("v", Expr(2_f), ast::AddressSpace::kPrivate);
+    GlobalVar("v", Expr(2_f), type::AddressSpace::kPrivate);
 
     auto* expr = Call("quantizeToF16", "v");
     WrapInFunction(expr);
@@ -261,7 +261,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, MslImportData_QuantizeToF16_Vector) {
-    GlobalVar("v", vec3<f32>(2_f), ast::AddressSpace::kPrivate);
+    GlobalVar("v", vec3<f32>(2_f), type::AddressSpace::kPrivate);
 
     auto* expr = Call("quantizeToF16", "v");
     WrapInFunction(expr);
diff --git a/src/tint/writer/msl/generator_impl_loop_test.cc b/src/tint/writer/msl/generator_impl_loop_test.cc
index 8926f2a..cac1306 100644
--- a/src/tint/writer/msl/generator_impl_loop_test.cc
+++ b/src/tint/writer/msl/generator_impl_loop_test.cc
@@ -93,8 +93,8 @@
 TEST_F(MslGeneratorImplTest, Emit_LoopNestedWithContinuing) {
     Func("a_statement", {}, ty.void_(), utils::Empty);
 
-    GlobalVar("lhs", ty.f32(), ast::AddressSpace::kPrivate);
-    GlobalVar("rhs", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("lhs", ty.f32(), type::AddressSpace::kPrivate);
+    GlobalVar("rhs", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* body = Block(Break());
     auto* continuing = Block(CallStmt(Call("a_statement")));
@@ -139,7 +139,7 @@
     // }
     //
 
-    GlobalVar("rhs", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("rhs", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* body = Block(Decl(Var("lhs", ty.f32(), Expr(2.4_f))),  //
                        Decl(Var("other", ty.f32())),             //
@@ -216,7 +216,7 @@
     Func("f", utils::Vector{Param("i", ty.i32())}, ty.void_(), utils::Empty);
     auto f = [&](auto&& expr) { return CallStmt(Call("f", expr)); };
 
-    GlobalVar("a", ty.atomic<i32>(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("a", ty.atomic<i32>(), type::AddressSpace::kWorkgroup);
     auto* multi_stmt = Block(f(1_i), f(2_i));
     auto* loop = For(multi_stmt, nullptr, nullptr,  //
                      Block(Return()));
@@ -292,7 +292,7 @@
     Func("f", utils::Vector{Param("i", ty.i32())}, ty.void_(), utils::Empty);
     auto f = [&](auto&& expr) { return CallStmt(Call("f", expr)); };
 
-    GlobalVar("a", ty.atomic<i32>(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("a", ty.atomic<i32>(), type::AddressSpace::kWorkgroup);
     auto* multi_stmt = Block(f(1_i), f(2_i));
     auto* loop = For(nullptr, nullptr, multi_stmt,  //
                      Block(Return()));
@@ -347,7 +347,7 @@
     Func("f", utils::Vector{Param("i", ty.i32())}, ty.void_(), utils::Empty);
     auto f = [&](auto&& expr) { return CallStmt(Call("f", expr)); };
 
-    GlobalVar("a", ty.atomic<i32>(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("a", ty.atomic<i32>(), type::AddressSpace::kWorkgroup);
     auto* multi_stmt_a = Block(f(1_i), f(2_i));
     auto* multi_stmt_b = Block(f(3_i), f(4_i));
     auto* loop = For(multi_stmt_a, Expr(true), multi_stmt_b,  //
diff --git a/src/tint/writer/msl/generator_impl_member_accessor_test.cc b/src/tint/writer/msl/generator_impl_member_accessor_test.cc
index 2f16f4a..0b54a52 100644
--- a/src/tint/writer/msl/generator_impl_member_accessor_test.cc
+++ b/src/tint/writer/msl/generator_impl_member_accessor_test.cc
@@ -21,7 +21,7 @@
 
 TEST_F(MslGeneratorImplTest, EmitExpression_MemberAccessor) {
     GlobalVar("str", ty.Of(Structure("my_str", utils::Vector{Member("mem", ty.f32())})),
-              ast::AddressSpace::kPrivate);
+              type::AddressSpace::kPrivate);
     auto* expr = MemberAccessor("str", "mem");
     WrapInFunction(expr);
 
@@ -33,7 +33,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, EmitExpression_MemberAccessor_Swizzle_xyz) {
-    GlobalVar("my_vec", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_vec", ty.vec4<f32>(), type::AddressSpace::kPrivate);
 
     auto* expr = MemberAccessor("my_vec", "xyz");
     WrapInFunction(expr);
@@ -45,7 +45,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, EmitExpression_MemberAccessor_Swizzle_gbr) {
-    GlobalVar("my_vec", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("my_vec", ty.vec4<f32>(), type::AddressSpace::kPrivate);
 
     auto* expr = MemberAccessor("my_vec", "gbr");
     WrapInFunction(expr);
diff --git a/src/tint/writer/msl/generator_impl_sanitizer_test.cc b/src/tint/writer/msl/generator_impl_sanitizer_test.cc
index 71fe1f6..1a0ce77 100644
--- a/src/tint/writer/msl/generator_impl_sanitizer_test.cc
+++ b/src/tint/writer/msl/generator_impl_sanitizer_test.cc
@@ -28,7 +28,7 @@
 
 TEST_F(MslSanitizerTest, Call_ArrayLength) {
     auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
-    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(1_a),
               Group(2_a));
 
     Func("a_func", utils::Empty, ty.void_(),
@@ -82,7 +82,7 @@
                                          Member(0, "z", ty.f32()),
                                          Member(4, "a", ty.array<f32>(4)),
                                      });
-    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(1_a),
               Group(2_a));
 
     Func("a_func", utils::Empty, ty.void_(),
@@ -135,7 +135,7 @@
 
 TEST_F(MslSanitizerTest, Call_ArrayLength_ViaLets) {
     auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
-    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(1_a),
               Group(2_a));
 
     auto* p = Let("p", AddressOf("b"));
@@ -192,9 +192,9 @@
 
 TEST_F(MslSanitizerTest, Call_ArrayLength_ArrayLengthFromUniform) {
     auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
-    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(1_a),
               Group(0_a));
-    GlobalVar("c", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(2_a),
+    GlobalVar("c", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(2_a),
               Group(0_a));
 
     Func("a_func", utils::Empty, ty.void_(),
@@ -251,9 +251,9 @@
 
 TEST_F(MslSanitizerTest, Call_ArrayLength_ArrayLengthFromUniformMissingBinding) {
     auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
-    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(1_a),
               Group(0_a));
-    GlobalVar("c", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(2_a),
+    GlobalVar("c", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(2_a),
               Group(0_a));
 
     Func("a_func", utils::Empty, ty.void_(),
diff --git a/src/tint/writer/msl/generator_impl_test.cc b/src/tint/writer/msl/generator_impl_test.cc
index 2299c19..ff3a4c9 100644
--- a/src/tint/writer/msl/generator_impl_test.cc
+++ b/src/tint/writer/msl/generator_impl_test.cc
@@ -163,7 +163,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, WorkgroupMatrix) {
-    GlobalVar("m", ty.mat2x2<f32>(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("m", ty.mat2x2<f32>(), type::AddressSpace::kWorkgroup);
     Func("comp_main", utils::Empty, ty.void_(), utils::Vector{Decl(Let("x", Expr("m")))},
          utils::Vector{
              Stage(ast::PipelineStage::kCompute),
@@ -203,7 +203,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, WorkgroupMatrixInArray) {
-    GlobalVar("m", ty.array(ty.mat2x2<f32>(), 4_i), ast::AddressSpace::kWorkgroup);
+    GlobalVar("m", ty.array(ty.mat2x2<f32>(), 4_i), type::AddressSpace::kWorkgroup);
     Func("comp_main", utils::Empty, ty.void_(), utils::Vector{Decl(Let("x", Expr("m")))},
          utils::Vector{
              Stage(ast::PipelineStage::kCompute),
@@ -264,7 +264,7 @@
     Structure("S2", utils::Vector{
                         Member("s", ty.type_name("S1")),
                     });
-    GlobalVar("s", ty.type_name("S2"), ast::AddressSpace::kWorkgroup);
+    GlobalVar("s", ty.type_name("S2"), type::AddressSpace::kWorkgroup);
     Func("comp_main", utils::Empty, ty.void_(), utils::Vector{Decl(Let("x", Expr("s")))},
          utils::Vector{
              Stage(ast::PipelineStage::kCompute),
@@ -314,15 +314,15 @@
 }
 
 TEST_F(MslGeneratorImplTest, WorkgroupMatrix_Multiples) {
-    GlobalVar("m1", ty.mat2x2<f32>(), ast::AddressSpace::kWorkgroup);
-    GlobalVar("m2", ty.mat2x3<f32>(), ast::AddressSpace::kWorkgroup);
-    GlobalVar("m3", ty.mat2x4<f32>(), ast::AddressSpace::kWorkgroup);
-    GlobalVar("m4", ty.mat3x2<f32>(), ast::AddressSpace::kWorkgroup);
-    GlobalVar("m5", ty.mat3x3<f32>(), ast::AddressSpace::kWorkgroup);
-    GlobalVar("m6", ty.mat3x4<f32>(), ast::AddressSpace::kWorkgroup);
-    GlobalVar("m7", ty.mat4x2<f32>(), ast::AddressSpace::kWorkgroup);
-    GlobalVar("m8", ty.mat4x3<f32>(), ast::AddressSpace::kWorkgroup);
-    GlobalVar("m9", ty.mat4x4<f32>(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("m1", ty.mat2x2<f32>(), type::AddressSpace::kWorkgroup);
+    GlobalVar("m2", ty.mat2x3<f32>(), type::AddressSpace::kWorkgroup);
+    GlobalVar("m3", ty.mat2x4<f32>(), type::AddressSpace::kWorkgroup);
+    GlobalVar("m4", ty.mat3x2<f32>(), type::AddressSpace::kWorkgroup);
+    GlobalVar("m5", ty.mat3x3<f32>(), type::AddressSpace::kWorkgroup);
+    GlobalVar("m6", ty.mat3x4<f32>(), type::AddressSpace::kWorkgroup);
+    GlobalVar("m7", ty.mat4x2<f32>(), type::AddressSpace::kWorkgroup);
+    GlobalVar("m8", ty.mat4x3<f32>(), type::AddressSpace::kWorkgroup);
+    GlobalVar("m9", ty.mat4x4<f32>(), type::AddressSpace::kWorkgroup);
     Func("main1", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(Let("a1", Expr("m1"))),
diff --git a/src/tint/writer/msl/generator_impl_type_test.cc b/src/tint/writer/msl/generator_impl_type_test.cc
index 3b63013..057b9e1 100644
--- a/src/tint/writer/msl/generator_impl_type_test.cc
+++ b/src/tint/writer/msl/generator_impl_type_test.cc
@@ -22,6 +22,7 @@
 #include "src/tint/type/sampled_texture.h"
 #include "src/tint/type/sampler.h"
 #include "src/tint/type/storage_texture.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/writer/msl/test_helper.h"
 
 using ::testing::HasSubstr;
@@ -89,7 +90,7 @@
 
 TEST_F(MslGeneratorImplTest, EmitType_Array) {
     auto* arr = ty.array<bool, 4>();
-    GlobalVar("G", arr, ast::AddressSpace::kPrivate);
+    GlobalVar("G", arr, type::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
@@ -101,7 +102,7 @@
 TEST_F(MslGeneratorImplTest, EmitType_ArrayOfArray) {
     auto* a = ty.array<bool, 4>();
     auto* b = ty.array(a, 5_u);
-    GlobalVar("G", b, ast::AddressSpace::kPrivate);
+    GlobalVar("G", b, type::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
@@ -114,7 +115,7 @@
     auto* a = ty.array<bool, 4>();
     auto* b = ty.array(a, 5_u);
     auto* c = ty.array(b, 6_u);
-    GlobalVar("G", c, ast::AddressSpace::kPrivate);
+    GlobalVar("G", c, type::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
@@ -125,7 +126,7 @@
 
 TEST_F(MslGeneratorImplTest, EmitType_Array_WithoutName) {
     auto* arr = ty.array<bool, 4>();
-    GlobalVar("G", arr, ast::AddressSpace::kPrivate);
+    GlobalVar("G", arr, type::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
@@ -136,7 +137,7 @@
 
 TEST_F(MslGeneratorImplTest, EmitType_RuntimeArray) {
     auto* arr = ty.array<bool, 1>();
-    GlobalVar("G", arr, ast::AddressSpace::kPrivate);
+    GlobalVar("G", arr, type::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
@@ -211,7 +212,7 @@
 
 TEST_F(MslGeneratorImplTest, EmitType_Pointer) {
     auto* f32 = create<type::F32>();
-    auto* p = create<type::Pointer>(f32, ast::AddressSpace::kWorkgroup, ast::Access::kReadWrite);
+    auto* p = create<type::Pointer>(f32, type::AddressSpace::kWorkgroup, type::Access::kReadWrite);
 
     GeneratorImpl& gen = Build();
 
@@ -282,7 +283,7 @@
                  Member("z", ty.f32()),
              });
 
-    GlobalVar("G", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("G", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(0_a),
               Group(0_a));
 
     GeneratorImpl& gen = Build();
@@ -390,7 +391,7 @@
                                  Member("e", ty.f32()),
                              });
 
-    GlobalVar("G", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("G", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(0_a),
               Group(0_a));
 
     GeneratorImpl& gen = Build();
@@ -481,7 +482,7 @@
                                  Member("f", array_z),
                              });
 
-    GlobalVar("G", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("G", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(0_a),
               Group(0_a));
 
     GeneratorImpl& gen = Build();
@@ -564,7 +565,7 @@
                                  Member("c", ty.i32()),
                              });
 
-    GlobalVar("G", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("G", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(0_a),
               Group(0_a));
 
     GeneratorImpl& gen = Build();
@@ -625,7 +626,7 @@
                                  Member("tint_pad_21", ty.f32()),
                              });
 
-    GlobalVar("G", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("G", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(0_a),
               Group(0_a));
 
     GeneratorImpl& gen = Build();
@@ -683,7 +684,7 @@
                                  Member("b", ty.f32()),
                              });
 
-    GlobalVar("G", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("G", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(0_a),
               Group(0_a));
 
     GeneratorImpl& gen = Build();
@@ -750,7 +751,7 @@
 }
 
 struct MslDepthTextureData {
-    ast::TextureDimension dim;
+    type::TextureDimension dim;
     std::string result;
 };
 inline std::ostream& operator<<(std::ostream& out, MslDepthTextureData data) {
@@ -773,16 +774,16 @@
     MslGeneratorImplTest,
     MslDepthTexturesTest,
     testing::Values(
-        MslDepthTextureData{ast::TextureDimension::k2d, "depth2d<float, access::sample>"},
-        MslDepthTextureData{ast::TextureDimension::k2dArray,
+        MslDepthTextureData{type::TextureDimension::k2d, "depth2d<float, access::sample>"},
+        MslDepthTextureData{type::TextureDimension::k2dArray,
                             "depth2d_array<float, access::sample>"},
-        MslDepthTextureData{ast::TextureDimension::kCube, "depthcube<float, access::sample>"},
-        MslDepthTextureData{ast::TextureDimension::kCubeArray,
+        MslDepthTextureData{type::TextureDimension::kCube, "depthcube<float, access::sample>"},
+        MslDepthTextureData{type::TextureDimension::kCubeArray,
                             "depthcube_array<float, access::sample>"}));
 
 using MslDepthMultisampledTexturesTest = TestHelper;
 TEST_F(MslDepthMultisampledTexturesTest, Emit) {
-    type::DepthMultisampledTexture s(ast::TextureDimension::k2d);
+    type::DepthMultisampledTexture s(type::TextureDimension::k2d);
 
     GeneratorImpl& gen = Build();
 
@@ -792,7 +793,7 @@
 }
 
 struct MslTextureData {
-    ast::TextureDimension dim;
+    type::TextureDimension dim;
     std::string result;
 };
 inline std::ostream& operator<<(std::ostream& out, MslTextureData data) {
@@ -816,17 +817,17 @@
     MslGeneratorImplTest,
     MslSampledtexturesTest,
     testing::Values(
-        MslTextureData{ast::TextureDimension::k1d, "texture1d<float, access::sample>"},
-        MslTextureData{ast::TextureDimension::k2d, "texture2d<float, access::sample>"},
-        MslTextureData{ast::TextureDimension::k2dArray, "texture2d_array<float, access::sample>"},
-        MslTextureData{ast::TextureDimension::k3d, "texture3d<float, access::sample>"},
-        MslTextureData{ast::TextureDimension::kCube, "texturecube<float, access::sample>"},
-        MslTextureData{ast::TextureDimension::kCubeArray,
+        MslTextureData{type::TextureDimension::k1d, "texture1d<float, access::sample>"},
+        MslTextureData{type::TextureDimension::k2d, "texture2d<float, access::sample>"},
+        MslTextureData{type::TextureDimension::k2dArray, "texture2d_array<float, access::sample>"},
+        MslTextureData{type::TextureDimension::k3d, "texture3d<float, access::sample>"},
+        MslTextureData{type::TextureDimension::kCube, "texturecube<float, access::sample>"},
+        MslTextureData{type::TextureDimension::kCubeArray,
                        "texturecube_array<float, access::sample>"}));
 
 TEST_F(MslGeneratorImplTest, Emit_TypeMultisampledTexture) {
     auto* u32 = create<type::U32>();
-    auto* ms = create<type::MultisampledTexture>(ast::TextureDimension::k2d, u32);
+    auto* ms = create<type::MultisampledTexture>(type::TextureDimension::k2d, u32);
 
     GeneratorImpl& gen = Build();
 
@@ -836,7 +837,7 @@
 }
 
 struct MslStorageTextureData {
-    ast::TextureDimension dim;
+    type::TextureDimension dim;
     std::string result;
 };
 inline std::ostream& operator<<(std::ostream& out, MslStorageTextureData data) {
@@ -846,7 +847,7 @@
 TEST_P(MslStorageTexturesTest, Emit) {
     auto params = GetParam();
 
-    auto* s = ty.storage_texture(params.dim, ast::TexelFormat::kR32Float, ast::Access::kWrite);
+    auto* s = ty.storage_texture(params.dim, type::TexelFormat::kR32Float, type::Access::kWrite);
     GlobalVar("test_var", s, Binding(0_a), Group(0_a));
 
     GeneratorImpl& gen = Build();
@@ -859,11 +860,11 @@
     MslGeneratorImplTest,
     MslStorageTexturesTest,
     testing::Values(
-        MslStorageTextureData{ast::TextureDimension::k1d, "texture1d<float, access::write>"},
-        MslStorageTextureData{ast::TextureDimension::k2d, "texture2d<float, access::write>"},
-        MslStorageTextureData{ast::TextureDimension::k2dArray,
+        MslStorageTextureData{type::TextureDimension::k1d, "texture1d<float, access::write>"},
+        MslStorageTextureData{type::TextureDimension::k2d, "texture2d<float, access::write>"},
+        MslStorageTextureData{type::TextureDimension::k2dArray,
                               "texture2d_array<float, access::write>"},
-        MslStorageTextureData{ast::TextureDimension::k3d, "texture3d<float, access::write>"}));
+        MslStorageTextureData{type::TextureDimension::k3d, "texture3d<float, access::write>"}));
 
 }  // namespace
 }  // namespace tint::writer::msl
diff --git a/src/tint/writer/msl/generator_impl_unary_op_test.cc b/src/tint/writer/msl/generator_impl_unary_op_test.cc
index 0c234df..ff4ac50 100644
--- a/src/tint/writer/msl/generator_impl_unary_op_test.cc
+++ b/src/tint/writer/msl/generator_impl_unary_op_test.cc
@@ -20,7 +20,7 @@
 using MslUnaryOpTest = TestHelper;
 
 TEST_F(MslUnaryOpTest, AddressOf) {
-    GlobalVar("expr", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("expr", ty.f32(), type::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kAddressOf, Expr("expr"));
     WrapInFunction(op);
 
@@ -32,7 +32,7 @@
 }
 
 TEST_F(MslUnaryOpTest, Complement) {
-    GlobalVar("expr", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("expr", ty.i32(), type::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kComplement, Expr("expr"));
     WrapInFunction(op);
 
@@ -44,7 +44,7 @@
 }
 
 TEST_F(MslUnaryOpTest, Indirection) {
-    GlobalVar("G", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("G", ty.f32(), type::AddressSpace::kPrivate);
     auto* p = Let("expr", create<ast::UnaryOpExpression>(ast::UnaryOp::kAddressOf, Expr("G")));
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kIndirection, Expr("expr"));
     WrapInFunction(p, op);
@@ -57,7 +57,7 @@
 }
 
 TEST_F(MslUnaryOpTest, Not) {
-    GlobalVar("expr", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("expr", ty.bool_(), type::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kNot, Expr("expr"));
     WrapInFunction(op);
 
@@ -69,7 +69,7 @@
 }
 
 TEST_F(MslUnaryOpTest, Negation) {
-    GlobalVar("expr", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("expr", ty.i32(), type::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kNegation, Expr("expr"));
     WrapInFunction(op);
 
diff --git a/src/tint/writer/msl/generator_impl_variable_decl_statement_test.cc b/src/tint/writer/msl/generator_impl_variable_decl_statement_test.cc
index b57a39f..5ee1c33 100644
--- a/src/tint/writer/msl/generator_impl_variable_decl_statement_test.cc
+++ b/src/tint/writer/msl/generator_impl_variable_decl_statement_test.cc
@@ -518,7 +518,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Private) {
-    GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.f32(), type::AddressSpace::kPrivate);
 
     WrapInFunction(Expr("a"));
 
@@ -531,7 +531,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Workgroup) {
-    GlobalVar("a", ty.f32(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("a", ty.f32(), type::AddressSpace::kWorkgroup);
 
     WrapInFunction(Expr("a"));
 
diff --git a/src/tint/writer/spirv/builder.cc b/src/tint/writer/spirv/builder.cc
index df5a2e3..abab05b 100644
--- a/src/tint/writer/spirv/builder.cc
+++ b/src/tint/writer/spirv/builder.cc
@@ -44,6 +44,7 @@
 #include "src/tint/type/multisampled_texture.h"
 #include "src/tint/type/reference.h"
 #include "src/tint/type/sampled_texture.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/type/vector.h"
 #include "src/tint/utils/compiler_macros.h"
 #include "src/tint/utils/defer.h"
@@ -505,8 +506,8 @@
     for (const auto* var : func_sem->TransitivelyReferencedGlobals()) {
         // For SPIR-V 1.3 we only output Input/output variables. If we update to
         // SPIR-V 1.4 or later this should be all variables.
-        if (var->AddressSpace() != ast::AddressSpace::kIn &&
-            var->AddressSpace() != ast::AddressSpace::kOut) {
+        if (var->AddressSpace() != type::AddressSpace::kIn &&
+            var->AddressSpace() != type::AddressSpace::kOut) {
             continue;
         }
 
@@ -716,7 +717,7 @@
 
     auto result = result_op();
     auto var_id = std::get<uint32_t>(result);
-    auto sc = ast::AddressSpace::kFunction;
+    auto sc = type::AddressSpace::kFunction;
     auto* type = sem->Type();
     auto type_id = GenerateTypeIfNeeded(type);
     if (type_id == 0) {
@@ -775,8 +776,8 @@
     auto result = result_op();
     auto var_id = std::get<uint32_t>(result);
 
-    auto sc = sem->AddressSpace() == ast::AddressSpace::kNone ? ast::AddressSpace::kPrivate
-                                                              : sem->AddressSpace();
+    auto sc = sem->AddressSpace() == type::AddressSpace::kNone ? type::AddressSpace::kPrivate
+                                                               : sem->AddressSpace();
 
     auto type_id = GenerateTypeIfNeeded(sem->Type());
     if (type_id == 0) {
@@ -795,16 +796,16 @@
             // type is a sem::Struct or a type::StorageTexture
             auto access = st ? st->access() : sem->Access();
             switch (access) {
-                case ast::Access::kWrite:
+                case type::Access::kWrite:
                     push_annot(spv::Op::OpDecorate,
                                {Operand(var_id), U32Operand(SpvDecorationNonReadable)});
                     break;
-                case ast::Access::kRead:
+                case type::Access::kRead:
                     push_annot(spv::Op::OpDecorate,
                                {Operand(var_id), U32Operand(SpvDecorationNonWritable)});
                     break;
-                case ast::Access::kUndefined:
-                case ast::Access::kReadWrite:
+                case type::Access::kUndefined:
+                case type::Access::kReadWrite:
                     break;
             }
         }
@@ -814,10 +815,10 @@
             // If we're a Workgroup variable, and the
             // VK_KHR_zero_initialize_workgroup_memory extension is enabled, we should
             // also zero-initialize.
-            if (sem->AddressSpace() == ast::AddressSpace::kPrivate ||
-                sem->AddressSpace() == ast::AddressSpace::kOut ||
+            if (sem->AddressSpace() == type::AddressSpace::kPrivate ||
+                sem->AddressSpace() == type::AddressSpace::kOut ||
                 (zero_initialize_workgroup_memory_ &&
-                 sem->AddressSpace() == ast::AddressSpace::kWorkgroup)) {
+                 sem->AddressSpace() == type::AddressSpace::kWorkgroup)) {
                 init_id = GenerateConstantNullIfNeeded(type);
                 if (init_id == 0) {
                     return 0;
@@ -1902,10 +1903,10 @@
 uint32_t Builder::GenerateSplat(uint32_t scalar_id, const type::Type* vec_type) {
     // Create a new vector to splat scalar into
     auto splat_vector = result_op();
-    auto* splat_vector_type = builder_.create<type::Pointer>(vec_type, ast::AddressSpace::kFunction,
-                                                             ast::Access::kReadWrite);
+    auto* splat_vector_type = builder_.create<type::Pointer>(
+        vec_type, type::AddressSpace::kFunction, type::Access::kReadWrite);
     push_function_var({Operand(GenerateTypeIfNeeded(splat_vector_type)), splat_vector,
-                       U32Operand(ConvertAddressSpace(ast::AddressSpace::kFunction)),
+                       U32Operand(ConvertAddressSpace(type::AddressSpace::kFunction)),
                        Operand(GenerateConstantNullIfNeeded(vec_type))});
 
     // Splat scalar into vector
@@ -2785,16 +2786,16 @@
             std::vector<uint32_t> swizzle;
             uint32_t spirv_dims = 0;
             switch (texture_type->dim()) {
-                case ast::TextureDimension::kNone:
+                case type::TextureDimension::kNone:
                     error_ = "texture dimension is kNone";
                     return false;
-                case ast::TextureDimension::k1d:
-                case ast::TextureDimension::k2d:
-                case ast::TextureDimension::k3d:
-                case ast::TextureDimension::kCube:
+                case type::TextureDimension::k1d:
+                case type::TextureDimension::k2d:
+                case type::TextureDimension::k3d:
+                case type::TextureDimension::kCube:
                     break;  // No swizzle needed
-                case ast::TextureDimension::kCubeArray:
-                case ast::TextureDimension::k2dArray:
+                case type::TextureDimension::kCubeArray:
+                case type::TextureDimension::k2dArray:
                     swizzle = {0, 1};  // Strip array index
                     spirv_dims = 3;    // [width, height, array_count]
                     break;
@@ -2825,8 +2826,8 @@
                 default:
                     error_ = "texture is not arrayed";
                     return false;
-                case ast::TextureDimension::k2dArray:
-                case ast::TextureDimension::kCubeArray:
+                case type::TextureDimension::k2dArray:
+                case type::TextureDimension::kCubeArray:
                     spirv_dims = 3;
                     break;
             }
@@ -3072,11 +3073,11 @@
 
     uint32_t memory_id = 0;
     switch (builtin->Parameters()[0]->Type()->As<type::Pointer>()->AddressSpace()) {
-        case ast::AddressSpace::kWorkgroup:
+        case type::AddressSpace::kWorkgroup:
             memory_id = GenerateConstantIfNeeded(
                 ScalarConstant::U32(static_cast<uint32_t>(spv::Scope::Workgroup)));
             break;
-        case ast::AddressSpace::kStorage:
+        case type::AddressSpace::kStorage:
             memory_id = GenerateConstantIfNeeded(
                 ScalarConstant::U32(static_cast<uint32_t>(spv::Scope::Device)));
             break;
@@ -3659,10 +3660,10 @@
     // fine.
     if (auto* ptr = type->As<type::Pointer>()) {
         type = builder_.create<type::Pointer>(ptr->StoreType(), ptr->AddressSpace(),
-                                              ast::Access::kReadWrite);
+                                              type::Access::kReadWrite);
     } else if (auto* ref = type->As<type::Reference>()) {
         type = builder_.create<type::Pointer>(ref->StoreType(), ref->AddressSpace(),
-                                              ast::Access::kReadWrite);
+                                              type::Access::kReadWrite);
     }
 
     return utils::GetOrCreate(type_to_id_, type, [&]() -> uint32_t {
@@ -3721,11 +3722,11 @@
                 // SPIR-V, we must output a single type, while the variable is
                 // annotated with the access type. Doing this ensures we de-dupe.
                 type_to_id_[builder_.create<type::StorageTexture>(
-                    tex->dim(), tex->texel_format(), ast::Access::kRead, tex->type())] = id;
+                    tex->dim(), tex->texel_format(), type::Access::kRead, tex->type())] = id;
                 type_to_id_[builder_.create<type::StorageTexture>(
-                    tex->dim(), tex->texel_format(), ast::Access::kWrite, tex->type())] = id;
+                    tex->dim(), tex->texel_format(), type::Access::kWrite, tex->type())] = id;
                 type_to_id_[builder_.create<type::StorageTexture>(
-                    tex->dim(), tex->texel_format(), ast::Access::kReadWrite, tex->type())] = id;
+                    tex->dim(), tex->texel_format(), type::Access::kReadWrite, tex->type())] = id;
                 return true;
             },
             [&](const type::Texture* tex) { return GenerateTextureType(tex, result); },
@@ -3764,12 +3765,12 @@
 
     uint32_t array_literal = 0u;
     const auto dim = texture->dim();
-    if (dim == ast::TextureDimension::k2dArray || dim == ast::TextureDimension::kCubeArray) {
+    if (dim == type::TextureDimension::k2dArray || dim == type::TextureDimension::kCubeArray) {
         array_literal = 1u;
     }
 
     uint32_t dim_literal = SpvDim2D;
-    if (dim == ast::TextureDimension::k1d) {
+    if (dim == type::TextureDimension::k1d) {
         dim_literal = SpvDim1D;
         if (texture->Is<type::SampledTexture>()) {
             push_capability(SpvCapabilitySampled1D);
@@ -3777,10 +3778,10 @@
             push_capability(SpvCapabilityImage1D);
         }
     }
-    if (dim == ast::TextureDimension::k3d) {
+    if (dim == type::TextureDimension::k3d) {
         dim_literal = SpvDim3D;
     }
-    if (dim == ast::TextureDimension::kCube || dim == ast::TextureDimension::kCubeArray) {
+    if (dim == type::TextureDimension::kCube || dim == type::TextureDimension::kCubeArray) {
         dim_literal = SpvDimCube;
     }
 
@@ -3800,7 +3801,7 @@
         sampled_literal = 1u;
     }
 
-    if (dim == ast::TextureDimension::kCubeArray) {
+    if (dim == type::TextureDimension::kCubeArray) {
         if (texture->IsAnyOf<type::SampledTexture, type::DepthTexture>()) {
             push_capability(SpvCapabilitySampledCubeArray);
         }
@@ -3979,40 +3980,40 @@
     return true;
 }
 
-SpvStorageClass Builder::ConvertAddressSpace(ast::AddressSpace klass) const {
+SpvStorageClass Builder::ConvertAddressSpace(type::AddressSpace klass) const {
     switch (klass) {
-        case ast::AddressSpace::kUndefined:
+        case type::AddressSpace::kUndefined:
             return SpvStorageClassMax;
-        case ast::AddressSpace::kIn:
+        case type::AddressSpace::kIn:
             return SpvStorageClassInput;
-        case ast::AddressSpace::kOut:
+        case type::AddressSpace::kOut:
             return SpvStorageClassOutput;
-        case ast::AddressSpace::kUniform:
+        case type::AddressSpace::kUniform:
             return SpvStorageClassUniform;
-        case ast::AddressSpace::kWorkgroup:
+        case type::AddressSpace::kWorkgroup:
             return SpvStorageClassWorkgroup;
-        case ast::AddressSpace::kPushConstant:
+        case type::AddressSpace::kPushConstant:
             return SpvStorageClassPushConstant;
-        case ast::AddressSpace::kHandle:
+        case type::AddressSpace::kHandle:
             return SpvStorageClassUniformConstant;
-        case ast::AddressSpace::kStorage:
+        case type::AddressSpace::kStorage:
             return SpvStorageClassStorageBuffer;
-        case ast::AddressSpace::kPrivate:
+        case type::AddressSpace::kPrivate:
             return SpvStorageClassPrivate;
-        case ast::AddressSpace::kFunction:
+        case type::AddressSpace::kFunction:
             return SpvStorageClassFunction;
-        case ast::AddressSpace::kNone:
+        case type::AddressSpace::kNone:
             break;
     }
     return SpvStorageClassMax;
 }
 
-SpvBuiltIn Builder::ConvertBuiltin(ast::BuiltinValue builtin, ast::AddressSpace storage) {
+SpvBuiltIn Builder::ConvertBuiltin(ast::BuiltinValue builtin, type::AddressSpace storage) {
     switch (builtin) {
         case ast::BuiltinValue::kPosition:
-            if (storage == ast::AddressSpace::kIn) {
+            if (storage == type::AddressSpace::kIn) {
                 return SpvBuiltInFragCoord;
-            } else if (TINT_LIKELY(storage == ast::AddressSpace::kOut)) {
+            } else if (TINT_LIKELY(storage == type::AddressSpace::kOut)) {
                 return SpvBuiltInPosition;
             } else {
                 TINT_ICE(Writer, builder_.Diagnostics()) << "invalid address space for builtin";
@@ -4077,48 +4078,48 @@
     }
 }
 
-SpvImageFormat Builder::convert_texel_format_to_spv(const ast::TexelFormat format) {
+SpvImageFormat Builder::convert_texel_format_to_spv(const type::TexelFormat format) {
     switch (format) {
-        case ast::TexelFormat::kBgra8Unorm:
+        case type::TexelFormat::kBgra8Unorm:
             TINT_ICE(Writer, builder_.Diagnostics())
                 << "bgra8unorm should have been polyfilled to rgba8unorm";
             return SpvImageFormatUnknown;
-        case ast::TexelFormat::kR32Uint:
+        case type::TexelFormat::kR32Uint:
             return SpvImageFormatR32ui;
-        case ast::TexelFormat::kR32Sint:
+        case type::TexelFormat::kR32Sint:
             return SpvImageFormatR32i;
-        case ast::TexelFormat::kR32Float:
+        case type::TexelFormat::kR32Float:
             return SpvImageFormatR32f;
-        case ast::TexelFormat::kRgba8Unorm:
+        case type::TexelFormat::kRgba8Unorm:
             return SpvImageFormatRgba8;
-        case ast::TexelFormat::kRgba8Snorm:
+        case type::TexelFormat::kRgba8Snorm:
             return SpvImageFormatRgba8Snorm;
-        case ast::TexelFormat::kRgba8Uint:
+        case type::TexelFormat::kRgba8Uint:
             return SpvImageFormatRgba8ui;
-        case ast::TexelFormat::kRgba8Sint:
+        case type::TexelFormat::kRgba8Sint:
             return SpvImageFormatRgba8i;
-        case ast::TexelFormat::kRg32Uint:
+        case type::TexelFormat::kRg32Uint:
             push_capability(SpvCapabilityStorageImageExtendedFormats);
             return SpvImageFormatRg32ui;
-        case ast::TexelFormat::kRg32Sint:
+        case type::TexelFormat::kRg32Sint:
             push_capability(SpvCapabilityStorageImageExtendedFormats);
             return SpvImageFormatRg32i;
-        case ast::TexelFormat::kRg32Float:
+        case type::TexelFormat::kRg32Float:
             push_capability(SpvCapabilityStorageImageExtendedFormats);
             return SpvImageFormatRg32f;
-        case ast::TexelFormat::kRgba16Uint:
+        case type::TexelFormat::kRgba16Uint:
             return SpvImageFormatRgba16ui;
-        case ast::TexelFormat::kRgba16Sint:
+        case type::TexelFormat::kRgba16Sint:
             return SpvImageFormatRgba16i;
-        case ast::TexelFormat::kRgba16Float:
+        case type::TexelFormat::kRgba16Float:
             return SpvImageFormatRgba16f;
-        case ast::TexelFormat::kRgba32Uint:
+        case type::TexelFormat::kRgba32Uint:
             return SpvImageFormatRgba32ui;
-        case ast::TexelFormat::kRgba32Sint:
+        case type::TexelFormat::kRgba32Sint:
             return SpvImageFormatRgba32i;
-        case ast::TexelFormat::kRgba32Float:
+        case type::TexelFormat::kRgba32Float:
             return SpvImageFormatRgba32f;
-        case ast::TexelFormat::kUndefined:
+        case type::TexelFormat::kUndefined:
             return SpvImageFormatUnknown;
     }
     return SpvImageFormatUnknown;
diff --git a/src/tint/writer/spirv/builder.h b/src/tint/writer/spirv/builder.h
index 0704074..12e16c1 100644
--- a/src/tint/writer/spirv/builder.h
+++ b/src/tint/writer/spirv/builder.h
@@ -208,12 +208,12 @@
     /// Converts a address space to a SPIR-V address space.
     /// @param klass the address space to convert
     /// @returns the SPIR-V address space or SpvStorageClassMax on error.
-    SpvStorageClass ConvertAddressSpace(ast::AddressSpace klass) const;
+    SpvStorageClass ConvertAddressSpace(type::AddressSpace klass) const;
     /// Converts a builtin to a SPIR-V builtin and pushes a capability if needed.
     /// @param builtin the builtin to convert
     /// @param storage the address space that this builtin is being used with
     /// @returns the SPIR-V builtin or SpvBuiltInMax on error.
-    SpvBuiltIn ConvertBuiltin(ast::BuiltinValue builtin, ast::AddressSpace storage);
+    SpvBuiltIn ConvertBuiltin(ast::BuiltinValue builtin, type::AddressSpace storage);
 
     /// Converts an interpolate attribute to SPIR-V decorations and pushes a
     /// capability if needed.
@@ -535,7 +535,7 @@
     /// Converts TexelFormat to SPIR-V and pushes an appropriate capability.
     /// @param format AST image format type
     /// @returns SPIR-V image format type
-    SpvImageFormat convert_texel_format_to_spv(const ast::TexelFormat format);
+    SpvImageFormat convert_texel_format_to_spv(const type::TexelFormat format);
 
     /// Determines if the given type initializer is created from constant values
     /// @param expr the expression to check
diff --git a/src/tint/writer/spirv/builder_assign_test.cc b/src/tint/writer/spirv/builder_assign_test.cc
index 1e2cf65..a82d4b9 100644
--- a/src/tint/writer/spirv/builder_assign_test.cc
+++ b/src/tint/writer/spirv/builder_assign_test.cc
@@ -23,7 +23,7 @@
 using BuilderTest = TestHelper;
 
 TEST_F(BuilderTest, Assign_Var) {
-    auto* v = GlobalVar("var", ty.f32(), ast::AddressSpace::kPrivate);
+    auto* v = GlobalVar("var", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* assign = Assign("var", 1_f);
 
@@ -51,7 +51,7 @@
 }
 
 TEST_F(BuilderTest, Assign_Var_OutsideFunction_IsError) {
-    auto* v = GlobalVar("var", ty.f32(), ast::AddressSpace::kPrivate);
+    auto* v = GlobalVar("var", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* assign = Assign("var", Expr(1_f));
 
@@ -70,7 +70,7 @@
 }
 
 TEST_F(BuilderTest, Assign_Var_ZeroInitializer) {
-    auto* v = GlobalVar("var", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    auto* v = GlobalVar("var", ty.vec3<f32>(), type::AddressSpace::kPrivate);
 
     auto* val = vec3<f32>();
     auto* assign = Assign("var", val);
@@ -101,7 +101,7 @@
 TEST_F(BuilderTest, Assign_Var_Complex_InitializerNestedVector) {
     auto* init = vec3<f32>(vec2<f32>(1_f, 2_f), 3_f);
 
-    auto* v = GlobalVar("var", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    auto* v = GlobalVar("var", ty.vec3<f32>(), type::AddressSpace::kPrivate);
 
     auto* assign = Assign("var", init);
 
@@ -134,7 +134,7 @@
 TEST_F(BuilderTest, Assign_Var_Complex_Initializer) {
     auto* init = vec3<f32>(1_f, 2_f, 3_f);
 
-    auto* v = GlobalVar("var", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    auto* v = GlobalVar("var", ty.vec3<f32>(), type::AddressSpace::kPrivate);
 
     auto* assign = Assign("var", init);
 
@@ -209,7 +209,7 @@
 }
 
 TEST_F(BuilderTest, Assign_Vector) {
-    auto* v = GlobalVar("var", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    auto* v = GlobalVar("var", ty.vec3<f32>(), type::AddressSpace::kPrivate);
 
     auto* val = vec3<f32>(1_f, 1_f, 3_f);
     auto* assign = Assign("var", val);
@@ -243,7 +243,7 @@
 TEST_F(BuilderTest, Assign_Vector_MemberByName) {
     // var.y = 1
 
-    auto* v = GlobalVar("var", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    auto* v = GlobalVar("var", ty.vec3<f32>(), type::AddressSpace::kPrivate);
 
     auto* assign = Assign(MemberAccessor("var", "y"), Expr(1_f));
 
@@ -278,7 +278,7 @@
 TEST_F(BuilderTest, Assign_Vector_MemberByIndex) {
     // var[1] = 1
 
-    auto* v = GlobalVar("var", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    auto* v = GlobalVar("var", ty.vec3<f32>(), type::AddressSpace::kPrivate);
 
     auto* assign = Assign(IndexAccessor("var", 1_i), Expr(1_f));
 
diff --git a/src/tint/writer/spirv/builder_binary_expression_test.cc b/src/tint/writer/spirv/builder_binary_expression_test.cc
index f0a5639..7733613 100644
--- a/src/tint/writer/spirv/builder_binary_expression_test.cc
+++ b/src/tint/writer/spirv/builder_binary_expression_test.cc
@@ -1031,8 +1031,8 @@
 }
 
 TEST_F(BuilderTest, Binary_LogicalAnd_WithLoads) {
-    auto* a_var = GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate, Expr(true));
-    auto* b_var = GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate, Expr(false));
+    auto* a_var = GlobalVar("a", ty.bool_(), type::AddressSpace::kPrivate, Expr(true));
+    auto* b_var = GlobalVar("b", ty.bool_(), type::AddressSpace::kPrivate, Expr(false));
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b"));
 
     WrapInFunction(expr);
@@ -1207,8 +1207,8 @@
 }
 
 TEST_F(BuilderTest, Binary_LogicalOr_WithLoads) {
-    auto* a_var = GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate, Expr(true));
-    auto* b_var = GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate, Expr(false));
+    auto* a_var = GlobalVar("a", ty.bool_(), type::AddressSpace::kPrivate, Expr(true));
+    auto* b_var = GlobalVar("b", ty.bool_(), type::AddressSpace::kPrivate, Expr(false));
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, Expr("a"), Expr("b"));
 
@@ -1251,19 +1251,19 @@
     switch (type) {
         case Type::f32:
             builder->GlobalVar(name, builder->ty.vec3<f32>(), builder->vec3<f32>(1_f, 1_f, 1_f),
-                               ast::AddressSpace::kPrivate);
+                               type::AddressSpace::kPrivate);
             break;
         case Type::f16:
             builder->GlobalVar(name, builder->ty.vec3<f16>(), builder->vec3<f16>(1_h, 1_h, 1_h),
-                               ast::AddressSpace::kPrivate);
+                               type::AddressSpace::kPrivate);
             break;
         case Type::i32:
             builder->GlobalVar(name, builder->ty.vec3<i32>(), builder->vec3<i32>(1_i, 1_i, 1_i),
-                               ast::AddressSpace::kPrivate);
+                               type::AddressSpace::kPrivate);
             break;
         case Type::u32:
             builder->GlobalVar(name, builder->ty.vec3<u32>(), builder->vec3<u32>(1_u, 1_u, 1_u),
-                               ast::AddressSpace::kPrivate);
+                               type::AddressSpace::kPrivate);
             break;
     }
     return builder->Expr(name);
@@ -1273,19 +1273,19 @@
     switch (type) {
         case Type::f32:
             builder->GlobalVar(name, builder->ty.f32(), builder->Expr(1_f),
-                               ast::AddressSpace::kPrivate);
+                               type::AddressSpace::kPrivate);
             break;
         case Type::f16:
             builder->GlobalVar(name, builder->ty.f16(), builder->Expr(1_h),
-                               ast::AddressSpace::kPrivate);
+                               type::AddressSpace::kPrivate);
             break;
         case Type::i32:
             builder->GlobalVar(name, builder->ty.i32(), builder->Expr(1_i),
-                               ast::AddressSpace::kPrivate);
+                               type::AddressSpace::kPrivate);
             break;
         case Type::u32:
             builder->GlobalVar(name, builder->ty.u32(), builder->Expr(1_u),
-                               ast::AddressSpace::kPrivate);
+                               type::AddressSpace::kPrivate);
             break;
     }
     return builder->Expr(name);
@@ -1580,11 +1580,11 @@
     switch (type) {
         case Type::f32:
             builder->GlobalVar(name, builder->ty.mat3x4<f32>(), builder->mat3x4<f32>(),
-                               ast::AddressSpace::kPrivate);
+                               type::AddressSpace::kPrivate);
             break;
         case Type::f16:
             builder->GlobalVar(name, builder->ty.mat3x4<f16>(), builder->mat3x4<f16>(),
-                               ast::AddressSpace::kPrivate);
+                               type::AddressSpace::kPrivate);
             break;
     }
     return builder->Expr(name);
@@ -1594,11 +1594,11 @@
     switch (type) {
         case Type::f32:
             builder->GlobalVar(name, builder->ty.mat4x3<f32>(), builder->mat4x3<f32>(),
-                               ast::AddressSpace::kPrivate);
+                               type::AddressSpace::kPrivate);
             break;
         case Type::f16:
             builder->GlobalVar(name, builder->ty.mat4x3<f16>(), builder->mat4x3<f16>(),
-                               ast::AddressSpace::kPrivate);
+                               type::AddressSpace::kPrivate);
     }
     return builder->Expr(name);
 }
diff --git a/src/tint/writer/spirv/builder_builtin_test.cc b/src/tint/writer/spirv/builder_builtin_test.cc
index 9b05980..aa154b0 100644
--- a/src/tint/writer/spirv/builder_builtin_test.cc
+++ b/src/tint/writer/spirv/builder_builtin_test.cc
@@ -15,6 +15,7 @@
 #include "src/tint/ast/call_statement.h"
 #include "src/tint/ast/stage_attribute.h"
 #include "src/tint/type/depth_texture.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/utils/string.h"
 #include "src/tint/writer/spirv/spv_dump.h"
 #include "src/tint/writer/spirv/test_helper.h"
@@ -41,7 +42,7 @@
 // This tests that we do not push OpTypeSampledImage and float_0 type twice.
 TEST_F(BuiltinBuilderTest, Call_TextureSampleCompare_Twice) {
     auto* s = ty.sampler(ast::SamplerKind::kComparisonSampler);
-    auto* t = ty.depth_texture(ast::TextureDimension::k2d);
+    auto* t = ty.depth_texture(type::TextureDimension::k2d);
 
     auto* tex = GlobalVar("texture", t, Binding(0_a), Group(0_a));
     auto* sampler = GlobalVar("sampler", s, Binding(1_a), Group(0_a));
@@ -97,7 +98,7 @@
 }
 
 TEST_F(BuiltinBuilderTest, Call_GLSLMethod_WithLoad_f32) {
-    auto* var = GlobalVar("ident", ty.f32(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("ident", ty.f32(), type::AddressSpace::kPrivate);
     auto* expr = Call("round", "ident");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -133,7 +134,7 @@
 TEST_F(BuiltinBuilderTest, Call_GLSLMethod_WithLoad_f16) {
     Enable(ast::Extension::kF16);
 
-    auto* var = GlobalVar("ident", ty.f16(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("ident", ty.f16(), type::AddressSpace::kPrivate);
     auto* expr = Call("round", "ident");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -172,7 +173,7 @@
 using BuiltinBoolTest = BuiltinBuilderTestWithParam<BuiltinData>;
 TEST_P(BuiltinBoolTest, Call_Bool_Scalar) {
     auto param = GetParam();
-    auto* var = GlobalVar("v", ty.bool_(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("v", ty.bool_(), type::AddressSpace::kPrivate);
     auto* expr = Call(param.name, "v");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -198,7 +199,7 @@
 
 TEST_P(BuiltinBoolTest, Call_Bool_Vector) {
     auto param = GetParam();
-    auto* var = GlobalVar("v", ty.vec3<bool>(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("v", ty.vec3<bool>(), type::AddressSpace::kPrivate);
     auto* expr = Call(param.name, "v");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -231,9 +232,9 @@
                          testing::Values(BuiltinData{"any", "OpAny"}, BuiltinData{"all", "OpAll"}));
 
 TEST_F(BuiltinBuilderTest, Call_Select) {
-    auto* v3 = GlobalVar("v3", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    auto* v3 = GlobalVar("v3", ty.vec3<f32>(), type::AddressSpace::kPrivate);
 
-    auto* bool_v3 = GlobalVar("bool_v3", ty.vec3<bool>(), ast::AddressSpace::kPrivate);
+    auto* bool_v3 = GlobalVar("bool_v3", ty.vec3<bool>(), type::AddressSpace::kPrivate);
     auto* expr = Call("select", "v3", "v3", "bool_v3");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -277,7 +278,7 @@
     auto* s = Structure("my_struct", utils::Vector{
                                          Member("a", ty.array<f32>(4)),
                                      });
-    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(1_a),
               Group(2_a));
     auto* expr = Call("arrayLength", AddressOf(MemberAccessor("b", "a")));
 
@@ -321,7 +322,7 @@
                                          Member("z", ty.f32()),
                                          Member(4, "a", ty.array<f32>(4)),
                                      });
-    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(1_a),
               Group(2_a));
     auto* expr = Call("arrayLength", AddressOf(MemberAccessor("b", "a")));
 
@@ -364,7 +365,7 @@
     auto* s = Structure("my_struct", utils::Vector{
                                          Member("a", ty.array<f32>(4)),
                                      });
-    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(1_a),
               Group(2_a));
 
     auto* p = Let("p", AddressOf("b"));
@@ -423,7 +424,7 @@
     auto* s = Structure("my_struct", utils::Vector{
                                          Member("a", ty.array<f32>(4)),
                                      });
-    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead, Binding(1_a),
               Group(2_a));
 
     auto* p = Let("p", AddressOf(Deref(AddressOf("b"))));
@@ -2099,7 +2100,7 @@
 }
 
 TEST_F(BuiltinBuilderTest, Call_QuantizeToF16_Scalar) {
-    GlobalVar("v", Expr(2_f), ast::AddressSpace::kPrivate);
+    GlobalVar("v", Expr(2_f), type::AddressSpace::kPrivate);
 
     Func("a_func", utils::Empty, ty.void_(),
          utils::Vector{
@@ -2138,7 +2139,7 @@
 }
 
 TEST_F(BuiltinBuilderTest, Call_QuantizeToF16_Vector) {
-    GlobalVar("v", vec3<f32>(2_f), ast::AddressSpace::kPrivate);
+    GlobalVar("v", vec3<f32>(2_f), type::AddressSpace::kPrivate);
 
     Func("a_func", utils::Empty, ty.void_(),
          utils::Vector{
@@ -2205,7 +2206,7 @@
 using BuiltinIntTest = BuiltinBuilderTestWithParam<BuiltinData>;
 TEST_P(BuiltinIntTest, Call_SInt_Scalar) {
     auto param = GetParam();
-    auto* var = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("v", ty.i32(), type::AddressSpace::kPrivate);
     auto* expr = Call(param.name, "v");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -2235,7 +2236,7 @@
 
 TEST_P(BuiltinIntTest, Call_SInt_Vector) {
     auto param = GetParam();
-    auto* var = GlobalVar("v", ty.vec3<i32>(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("v", ty.vec3<i32>(), type::AddressSpace::kPrivate);
     auto* expr = Call(param.name, "v");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -2266,7 +2267,7 @@
 
 TEST_P(BuiltinIntTest, Call_UInt_Scalar) {
     auto param = GetParam();
-    auto* var = GlobalVar("v", ty.u32(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("v", ty.u32(), type::AddressSpace::kPrivate);
     auto* expr = Call(param.name, "v");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -2296,7 +2297,7 @@
 
 TEST_P(BuiltinIntTest, Call_UInt_Vector) {
     auto param = GetParam();
-    auto* var = GlobalVar("v", ty.vec3<u32>(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("v", ty.vec3<u32>(), type::AddressSpace::kPrivate);
     auto* expr = Call(param.name, "v");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -3167,7 +3168,7 @@
 namespace matrix_builtin_tests {
 
 TEST_F(BuiltinBuilderTest, Call_Determinant_f32) {
-    auto* var = GlobalVar("var", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("var", ty.mat3x3<f32>(), type::AddressSpace::kPrivate);
     auto* expr = Call("determinant", "var");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -3204,7 +3205,7 @@
 TEST_F(BuiltinBuilderTest, Call_Determinant_f16) {
     Enable(ast::Extension::kF16);
 
-    auto* var = GlobalVar("var", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("var", ty.mat3x3<f16>(), type::AddressSpace::kPrivate);
     auto* expr = Call("determinant", "var");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -3239,7 +3240,7 @@
 }
 
 TEST_F(BuiltinBuilderTest, Call_Transpose_f32) {
-    auto* var = GlobalVar("var", ty.mat2x3<f32>(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("var", ty.mat2x3<f32>(), type::AddressSpace::kPrivate);
     auto* expr = Call("transpose", "var");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -3277,7 +3278,7 @@
 TEST_F(BuiltinBuilderTest, Call_Transpose_f16) {
     Enable(ast::Extension::kF16);
 
-    auto* var = GlobalVar("var", ty.mat2x3<f16>(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("var", ty.mat2x3<f16>(), type::AddressSpace::kPrivate);
     auto* expr = Call("transpose", "var");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -3318,7 +3319,7 @@
 namespace vector_builtin_tests {
 
 TEST_F(BuiltinBuilderTest, Call_Dot_F32) {
-    auto* var = GlobalVar("v", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("v", ty.vec3<f32>(), type::AddressSpace::kPrivate);
     auto* expr = Call("dot", "v", "v");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -3349,7 +3350,7 @@
 TEST_F(BuiltinBuilderTest, Call_Dot_F16) {
     Enable(ast::Extension::kF16);
 
-    auto* var = GlobalVar("v", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("v", ty.vec3<f16>(), type::AddressSpace::kPrivate);
     auto* expr = Call("dot", "v", "v");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -3378,7 +3379,7 @@
 }
 
 TEST_F(BuiltinBuilderTest, Call_Dot_U32) {
-    auto* var = GlobalVar("v", ty.vec3<u32>(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("v", ty.vec3<u32>(), type::AddressSpace::kPrivate);
     auto* expr = Call("dot", "v", "v");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -3417,7 +3418,7 @@
 }
 
 TEST_F(BuiltinBuilderTest, Call_Dot_I32) {
-    auto* var = GlobalVar("v", ty.vec3<i32>(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("v", ty.vec3<i32>(), type::AddressSpace::kPrivate);
     auto* expr = Call("dot", "v", "v");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -3463,7 +3464,7 @@
 using BuiltinDeriveTest = BuiltinBuilderTestWithParam<BuiltinData>;
 TEST_P(BuiltinDeriveTest, Call_Derivative_Scalar) {
     auto param = GetParam();
-    auto* var = GlobalVar("v", ty.f32(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("v", ty.f32(), type::AddressSpace::kPrivate);
     auto* expr = Call(param.name, "v");
     auto* func = Func("func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -3496,7 +3497,7 @@
 
 TEST_P(BuiltinDeriveTest, Call_Derivative_Vector) {
     auto param = GetParam();
-    auto* var = GlobalVar("v", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("v", ty.vec3<f32>(), type::AddressSpace::kPrivate);
     auto* expr = Call(param.name, "v");
     auto* func = Func("func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -3566,7 +3567,7 @@
                                  Member("u", ty.atomic<u32>()),
                                  Member("i", ty.atomic<i32>()),
                              });
-    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(1_a),
+    GlobalVar("b", ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite, Binding(1_a),
               Group(2_a));
 
     Func("a_func", utils::Empty, ty.void_(),
@@ -3630,7 +3631,7 @@
                                  Member("u", ty.atomic<u32>()),
                                  Member("i", ty.atomic<i32>()),
                              });
-    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(1_a),
+    GlobalVar("b", ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite, Binding(1_a),
               Group(2_a));
 
     Func("a_func", utils::Empty, ty.void_(),
@@ -3702,7 +3703,7 @@
     auto* s = Structure("S", utils::Vector{
                                  Member("v", ty.atomic<i32>()),
                              });
-    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(1_a),
+    GlobalVar("b", ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite, Binding(1_a),
               Group(2_a));
 
     Func("a_func", utils::Empty, ty.void_(),
@@ -3775,7 +3776,7 @@
     auto* s = Structure("S", utils::Vector{
                                  Member("v", ty.atomic<u32>()),
                              });
-    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(1_a),
+    GlobalVar("b", ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite, Binding(1_a),
               Group(2_a));
 
     Func("a_func", utils::Empty, ty.void_(),
@@ -3850,7 +3851,7 @@
                                  Member("u", ty.atomic<u32>()),
                                  Member("i", ty.atomic<i32>()),
                              });
-    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(1_a),
+    GlobalVar("b", ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite, Binding(1_a),
               Group(2_a));
 
     Func("a_func", utils::Empty, ty.void_(),
@@ -3926,7 +3927,7 @@
                                  Member("u", ty.atomic<u32>()),
                                  Member("i", ty.atomic<i32>()),
                              });
-    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(1_a),
+    GlobalVar("b", ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite, Binding(1_a),
               Group(2_a));
 
     Func("a_func", utils::Empty, ty.void_(),
diff --git a/src/tint/writer/spirv/builder_entry_point_test.cc b/src/tint/writer/spirv/builder_entry_point_test.cc
index a064ee3..f48c975 100644
--- a/src/tint/writer/spirv/builder_entry_point_test.cc
+++ b/src/tint/writer/spirv/builder_entry_point_test.cc
@@ -15,7 +15,6 @@
 #include <memory>
 
 #include "gtest/gtest.h"
-#include "src/tint/ast/address_space.h"
 #include "src/tint/ast/builtin_attribute.h"
 #include "src/tint/ast/builtin_value.h"
 #include "src/tint/ast/location_attribute.h"
@@ -23,6 +22,7 @@
 #include "src/tint/ast/stage_attribute.h"
 #include "src/tint/ast/variable.h"
 #include "src/tint/program.h"
+#include "src/tint/type/address_space.h"
 #include "src/tint/type/f32.h"
 #include "src/tint/type/vector.h"
 #include "src/tint/writer/spirv/builder.h"
diff --git a/src/tint/writer/spirv/builder_format_conversion_test.cc b/src/tint/writer/spirv/builder_format_conversion_test.cc
index dbb4f44..cd1322f 100644
--- a/src/tint/writer/spirv/builder_format_conversion_test.cc
+++ b/src/tint/writer/spirv/builder_format_conversion_test.cc
@@ -19,7 +19,7 @@
 namespace {
 
 struct TestData {
-    ast::TexelFormat ast_format;
+    type::TexelFormat ast_format;
     SpvImageFormat_ spv_format;
     bool extended_format = false;
 };
@@ -49,42 +49,42 @@
                          ImageFormatConversionTest,
                          testing::Values(
                              /* WGSL unsupported formats
-                       TestData{ast::TexelFormat::kR8Unorm, SpvImageFormatR8, true},
-                       TestData{ast::TexelFormat::kR8Snorm, SpvImageFormatR8Snorm, true},
-                       TestData{ast::TexelFormat::kR8Uint, SpvImageFormatR8ui, true},
-                       TestData{ast::TexelFormat::kR8Sint, SpvImageFormatR8i, true},
-                       TestData{ast::TexelFormat::kR16Uint, SpvImageFormatR16ui, true},
-                       TestData{ast::TexelFormat::kR16Sint, SpvImageFormatR16i, true},
-                       TestData{ast::TexelFormat::kR16Float, SpvImageFormatR16f, true},
-                       TestData{ast::TexelFormat::kRg8Unorm, SpvImageFormatRg8, true},
-                       TestData{ast::TexelFormat::kRg8Snorm, SpvImageFormatRg8Snorm, true},
-                       TestData{ast::TexelFormat::kRg8Uint, SpvImageFormatRg8ui, true},
-                       TestData{ast::TexelFormat::kRg8Sint, SpvImageFormatRg8i, true},
-                       TestData{ast::TexelFormat::kRg16Uint, SpvImageFormatRg16ui, true},
-                       TestData{ast::TexelFormat::kRg16Sint, SpvImageFormatRg16i, true},
-                       TestData{ast::TexelFormat::kRg16Float, SpvImageFormatRg16f, true},
-                       TestData{ast::TexelFormat::kRgba8UnormSrgb, SpvImageFormatUnknown},
-                       TestData{ast::TexelFormat::kBgra8Unorm, SpvImageFormatUnknown},
-                       TestData{ast::TexelFormat::kBgra8UnormSrgb, SpvImageFormatUnknown},
-                       TestData{ast::TexelFormat::kRgb10A2Unorm, SpvImageFormatRgb10A2, true},
-                       TestData{ast::TexelFormat::kRg11B10Float, SpvImageFormatR11fG11fB10f, true},
+                       TestData{type::TexelFormat::kR8Unorm, SpvImageFormatR8, true},
+                       TestData{type::TexelFormat::kR8Snorm, SpvImageFormatR8Snorm, true},
+                       TestData{type::TexelFormat::kR8Uint, SpvImageFormatR8ui, true},
+                       TestData{type::TexelFormat::kR8Sint, SpvImageFormatR8i, true},
+                       TestData{type::TexelFormat::kR16Uint, SpvImageFormatR16ui, true},
+                       TestData{type::TexelFormat::kR16Sint, SpvImageFormatR16i, true},
+                       TestData{type::TexelFormat::kR16Float, SpvImageFormatR16f, true},
+                       TestData{type::TexelFormat::kRg8Unorm, SpvImageFormatRg8, true},
+                       TestData{type::TexelFormat::kRg8Snorm, SpvImageFormatRg8Snorm, true},
+                       TestData{type::TexelFormat::kRg8Uint, SpvImageFormatRg8ui, true},
+                       TestData{type::TexelFormat::kRg8Sint, SpvImageFormatRg8i, true},
+                       TestData{type::TexelFormat::kRg16Uint, SpvImageFormatRg16ui, true},
+                       TestData{type::TexelFormat::kRg16Sint, SpvImageFormatRg16i, true},
+                       TestData{type::TexelFormat::kRg16Float, SpvImageFormatRg16f, true},
+                       TestData{type::TexelFormat::kRgba8UnormSrgb, SpvImageFormatUnknown},
+                       TestData{type::TexelFormat::kBgra8Unorm, SpvImageFormatUnknown},
+                       TestData{type::TexelFormat::kBgra8UnormSrgb, SpvImageFormatUnknown},
+                       TestData{type::TexelFormat::kRgb10A2Unorm, SpvImageFormatRgb10A2, true},
+                       TestData{type::TexelFormat::kRg11B10Float, SpvImageFormatR11fG11fB10f, true},
                      */
-                             TestData{ast::TexelFormat::kR32Uint, SpvImageFormatR32ui},
-                             TestData{ast::TexelFormat::kR32Sint, SpvImageFormatR32i},
-                             TestData{ast::TexelFormat::kR32Float, SpvImageFormatR32f},
-                             TestData{ast::TexelFormat::kRgba8Unorm, SpvImageFormatRgba8},
-                             TestData{ast::TexelFormat::kRgba8Snorm, SpvImageFormatRgba8Snorm},
-                             TestData{ast::TexelFormat::kRgba8Uint, SpvImageFormatRgba8ui},
-                             TestData{ast::TexelFormat::kRgba8Sint, SpvImageFormatRgba8i},
-                             TestData{ast::TexelFormat::kRg32Uint, SpvImageFormatRg32ui, true},
-                             TestData{ast::TexelFormat::kRg32Sint, SpvImageFormatRg32i, true},
-                             TestData{ast::TexelFormat::kRg32Float, SpvImageFormatRg32f, true},
-                             TestData{ast::TexelFormat::kRgba16Uint, SpvImageFormatRgba16ui},
-                             TestData{ast::TexelFormat::kRgba16Sint, SpvImageFormatRgba16i},
-                             TestData{ast::TexelFormat::kRgba16Float, SpvImageFormatRgba16f},
-                             TestData{ast::TexelFormat::kRgba32Uint, SpvImageFormatRgba32ui},
-                             TestData{ast::TexelFormat::kRgba32Sint, SpvImageFormatRgba32i},
-                             TestData{ast::TexelFormat::kRgba32Float, SpvImageFormatRgba32f}));
+                             TestData{type::TexelFormat::kR32Uint, SpvImageFormatR32ui},
+                             TestData{type::TexelFormat::kR32Sint, SpvImageFormatR32i},
+                             TestData{type::TexelFormat::kR32Float, SpvImageFormatR32f},
+                             TestData{type::TexelFormat::kRgba8Unorm, SpvImageFormatRgba8},
+                             TestData{type::TexelFormat::kRgba8Snorm, SpvImageFormatRgba8Snorm},
+                             TestData{type::TexelFormat::kRgba8Uint, SpvImageFormatRgba8ui},
+                             TestData{type::TexelFormat::kRgba8Sint, SpvImageFormatRgba8i},
+                             TestData{type::TexelFormat::kRg32Uint, SpvImageFormatRg32ui, true},
+                             TestData{type::TexelFormat::kRg32Sint, SpvImageFormatRg32i, true},
+                             TestData{type::TexelFormat::kRg32Float, SpvImageFormatRg32f, true},
+                             TestData{type::TexelFormat::kRgba16Uint, SpvImageFormatRgba16ui},
+                             TestData{type::TexelFormat::kRgba16Sint, SpvImageFormatRgba16i},
+                             TestData{type::TexelFormat::kRgba16Float, SpvImageFormatRgba16f},
+                             TestData{type::TexelFormat::kRgba32Uint, SpvImageFormatRgba32ui},
+                             TestData{type::TexelFormat::kRgba32Sint, SpvImageFormatRgba32i},
+                             TestData{type::TexelFormat::kRgba32Float, SpvImageFormatRgba32f}));
 
 }  // namespace
 }  // namespace tint::writer::spirv
diff --git a/src/tint/writer/spirv/builder_function_test.cc b/src/tint/writer/spirv/builder_function_test.cc
index efaefed..7ee1369 100644
--- a/src/tint/writer/spirv/builder_function_test.cc
+++ b/src/tint/writer/spirv/builder_function_test.cc
@@ -61,7 +61,7 @@
 }
 
 TEST_F(BuilderTest, Function_Terminator_ReturnValue) {
-    GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.f32(), type::AddressSpace::kPrivate);
 
     Func("a_func", utils::Empty, ty.f32(), utils::Vector{Return("a")}, utils::Empty);
 
@@ -198,8 +198,8 @@
 
     auto* s = Structure("Data", utils::Vector{Member("d", ty.f32())});
 
-    GlobalVar("data", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(0_a),
-              Group(0_a));
+    GlobalVar("data", ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite,
+              Binding(0_a), Group(0_a));
 
     {
         auto* var = Var("v", ty.f32(), MemberAccessor("data", "d"));
diff --git a/src/tint/writer/spirv/builder_function_variable_test.cc b/src/tint/writer/spirv/builder_function_variable_test.cc
index 4f50388..47f1ed2 100644
--- a/src/tint/writer/spirv/builder_function_variable_test.cc
+++ b/src/tint/writer/spirv/builder_function_variable_test.cc
@@ -23,7 +23,7 @@
 using BuilderTest = TestHelper;
 
 TEST_F(BuilderTest, FunctionVar_NoAddressSpace) {
-    auto* v = Var("var", ty.f32(), ast::AddressSpace::kFunction);
+    auto* v = Var("var", ty.f32(), type::AddressSpace::kFunction);
     WrapInFunction(v);
 
     spirv::Builder& b = Build();
@@ -45,7 +45,7 @@
 
 TEST_F(BuilderTest, FunctionVar_WithConstantInitializer) {
     auto* init = vec3<f32>(1_f, 1_f, 3_f);
-    auto* v = Var("var", ty.vec3<f32>(), ast::AddressSpace::kFunction, init);
+    auto* v = Var("var", ty.vec3<f32>(), type::AddressSpace::kFunction, init);
     WrapInFunction(v);
 
     spirv::Builder& b = Build();
diff --git a/src/tint/writer/spirv/builder_global_variable_test.cc b/src/tint/writer/spirv/builder_global_variable_test.cc
index 7d3ec59..e6f4733 100644
--- a/src/tint/writer/spirv/builder_global_variable_test.cc
+++ b/src/tint/writer/spirv/builder_global_variable_test.cc
@@ -14,6 +14,7 @@
 
 #include "src/tint/ast/id_attribute.h"
 #include "src/tint/ast/stage_attribute.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/writer/spirv/spv_dump.h"
 #include "src/tint/writer/spirv/test_helper.h"
 
@@ -25,7 +26,7 @@
 using BuilderTest = TestHelper;
 
 TEST_F(BuilderTest, GlobalVar_WithAddressSpace) {
-    auto* v = GlobalVar("var", ty.f32(), ast::AddressSpace::kPrivate);
+    auto* v = GlobalVar("var", ty.f32(), type::AddressSpace::kPrivate);
 
     spirv::Builder& b = Build();
 
@@ -42,7 +43,7 @@
 TEST_F(BuilderTest, GlobalVar_WithInitializer) {
     auto* init = vec3<f32>(1_f, 1_f, 3_f);
 
-    auto* v = GlobalVar("var", ty.vec3<f32>(), ast::AddressSpace::kPrivate, init);
+    auto* v = GlobalVar("var", ty.vec3<f32>(), type::AddressSpace::kPrivate, init);
 
     spirv::Builder& b = Build();
 
@@ -66,7 +67,7 @@
     // var v = c;
 
     auto* c = GlobalConst("c", Expr(42_a));
-    GlobalVar("v", ast::AddressSpace::kPrivate, Expr(c));
+    GlobalVar("v", type::AddressSpace::kPrivate, Expr(c));
 
     spirv::Builder& b = SanitizeAndBuild();
 
@@ -91,7 +92,7 @@
     // var v = c;
 
     auto* c = GlobalConst("c", vec3<f32>(1_f, 2_f, 3_f));
-    GlobalVar("v", ast::AddressSpace::kPrivate, Expr(c));
+    GlobalVar("v", type::AddressSpace::kPrivate, Expr(c));
 
     spirv::Builder& b = SanitizeAndBuild();
 
@@ -121,7 +122,7 @@
     Enable(ast::Extension::kF16);
 
     auto* c = GlobalConst("c", vec3<f16>(1_h, 2_h, 3_h));
-    GlobalVar("v", ast::AddressSpace::kPrivate, Expr(c));
+    GlobalVar("v", type::AddressSpace::kPrivate, Expr(c));
 
     spirv::Builder& b = SanitizeAndBuild();
 
@@ -150,7 +151,7 @@
     // var v = c;
 
     auto* c = GlobalConst("c", Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
-    GlobalVar("v", ast::AddressSpace::kPrivate, Expr(c));
+    GlobalVar("v", type::AddressSpace::kPrivate, Expr(c));
 
     spirv::Builder& b = SanitizeAndBuild();
 
@@ -179,7 +180,7 @@
     // var v = c;
 
     auto* c = GlobalConst("c", Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
-    GlobalVar("v", ast::AddressSpace::kPrivate, Expr(c));
+    GlobalVar("v", type::AddressSpace::kPrivate, Expr(c));
 
     spirv::Builder& b = SanitizeAndBuild();
 
@@ -208,7 +209,7 @@
     // var v = c;
 
     auto* c = GlobalConst("c", vec3<f32>(vec2<f32>(1_f, 2_f), 3_f));
-    GlobalVar("v", ast::AddressSpace::kPrivate, Expr(c));
+    GlobalVar("v", type::AddressSpace::kPrivate, Expr(c));
 
     spirv::Builder& b = SanitizeAndBuild();
 
@@ -251,7 +252,7 @@
 
 struct BuiltinData {
     ast::BuiltinValue builtin;
-    ast::AddressSpace storage;
+    type::AddressSpace storage;
     SpvBuiltIn result;
 };
 inline std::ostream& operator<<(std::ostream& out, BuiltinData data) {
@@ -270,30 +271,32 @@
     BuilderTest_Type,
     BuiltinDataTest,
     testing::Values(
-        BuiltinData{ast::BuiltinValue::kUndefined, ast::AddressSpace::kNone, SpvBuiltInMax},
-        BuiltinData{ast::BuiltinValue::kPosition, ast::AddressSpace::kIn, SpvBuiltInFragCoord},
-        BuiltinData{ast::BuiltinValue::kPosition, ast::AddressSpace::kOut, SpvBuiltInPosition},
+        BuiltinData{ast::BuiltinValue::kUndefined, type::AddressSpace::kNone, SpvBuiltInMax},
+        BuiltinData{ast::BuiltinValue::kPosition, type::AddressSpace::kIn, SpvBuiltInFragCoord},
+        BuiltinData{ast::BuiltinValue::kPosition, type::AddressSpace::kOut, SpvBuiltInPosition},
         BuiltinData{
             ast::BuiltinValue::kVertexIndex,
-            ast::AddressSpace::kIn,
+            type::AddressSpace::kIn,
             SpvBuiltInVertexIndex,
         },
-        BuiltinData{ast::BuiltinValue::kInstanceIndex, ast::AddressSpace::kIn,
+        BuiltinData{ast::BuiltinValue::kInstanceIndex, type::AddressSpace::kIn,
                     SpvBuiltInInstanceIndex},
-        BuiltinData{ast::BuiltinValue::kFrontFacing, ast::AddressSpace::kIn, SpvBuiltInFrontFacing},
-        BuiltinData{ast::BuiltinValue::kFragDepth, ast::AddressSpace::kOut, SpvBuiltInFragDepth},
-        BuiltinData{ast::BuiltinValue::kLocalInvocationId, ast::AddressSpace::kIn,
+        BuiltinData{ast::BuiltinValue::kFrontFacing, type::AddressSpace::kIn,
+                    SpvBuiltInFrontFacing},
+        BuiltinData{ast::BuiltinValue::kFragDepth, type::AddressSpace::kOut, SpvBuiltInFragDepth},
+        BuiltinData{ast::BuiltinValue::kLocalInvocationId, type::AddressSpace::kIn,
                     SpvBuiltInLocalInvocationId},
-        BuiltinData{ast::BuiltinValue::kLocalInvocationIndex, ast::AddressSpace::kIn,
+        BuiltinData{ast::BuiltinValue::kLocalInvocationIndex, type::AddressSpace::kIn,
                     SpvBuiltInLocalInvocationIndex},
-        BuiltinData{ast::BuiltinValue::kGlobalInvocationId, ast::AddressSpace::kIn,
+        BuiltinData{ast::BuiltinValue::kGlobalInvocationId, type::AddressSpace::kIn,
                     SpvBuiltInGlobalInvocationId},
-        BuiltinData{ast::BuiltinValue::kWorkgroupId, ast::AddressSpace::kIn, SpvBuiltInWorkgroupId},
-        BuiltinData{ast::BuiltinValue::kNumWorkgroups, ast::AddressSpace::kIn,
+        BuiltinData{ast::BuiltinValue::kWorkgroupId, type::AddressSpace::kIn,
+                    SpvBuiltInWorkgroupId},
+        BuiltinData{ast::BuiltinValue::kNumWorkgroups, type::AddressSpace::kIn,
                     SpvBuiltInNumWorkgroups},
-        BuiltinData{ast::BuiltinValue::kSampleIndex, ast::AddressSpace::kIn, SpvBuiltInSampleId},
-        BuiltinData{ast::BuiltinValue::kSampleMask, ast::AddressSpace::kIn, SpvBuiltInSampleMask},
-        BuiltinData{ast::BuiltinValue::kSampleMask, ast::AddressSpace::kOut,
+        BuiltinData{ast::BuiltinValue::kSampleIndex, type::AddressSpace::kIn, SpvBuiltInSampleId},
+        BuiltinData{ast::BuiltinValue::kSampleMask, type::AddressSpace::kIn, SpvBuiltInSampleMask},
+        BuiltinData{ast::BuiltinValue::kSampleMask, type::AddressSpace::kOut,
                     SpvBuiltInSampleMask}));
 
 TEST_F(BuilderTest, GlobalVar_DeclReadOnly) {
@@ -307,7 +310,7 @@
                                  Member("b", ty.i32()),
                              });
 
-    GlobalVar("b", ty.Of(A), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("b", ty.Of(A), type::AddressSpace::kStorage, type::Access::kRead, Binding(0_a),
               Group(0_a));
 
     spirv::Builder& b = SanitizeAndBuild();
@@ -349,7 +352,7 @@
 
     auto* A = Structure("A", utils::Vector{Member("a", ty.i32())});
     auto* B = Alias("B", ty.Of(A));
-    GlobalVar("b", ty.Of(B), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("b", ty.Of(B), type::AddressSpace::kStorage, type::Access::kRead, Binding(0_a),
               Group(0_a));
 
     spirv::Builder& b = SanitizeAndBuild();
@@ -389,7 +392,7 @@
 
     auto* A = Structure("A", utils::Vector{Member("a", ty.i32())});
     auto* B = Alias("B", ty.Of(A));
-    GlobalVar("b", ty.Of(B), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("b", ty.Of(B), type::AddressSpace::kStorage, type::Access::kRead, Binding(0_a),
               Group(0_a));
 
     spirv::Builder& b = SanitizeAndBuild();
@@ -428,9 +431,9 @@
     // var<storage, read_write> c : A
 
     auto* A = Structure("A", utils::Vector{Member("a", ty.i32())});
-    GlobalVar("b", ty.Of(A), ast::AddressSpace::kStorage, ast::Access::kRead, Group(0_a),
+    GlobalVar("b", ty.Of(A), type::AddressSpace::kStorage, type::Access::kRead, Group(0_a),
               Binding(0_a));
-    GlobalVar("c", ty.Of(A), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Group(1_a),
+    GlobalVar("c", ty.Of(A), type::AddressSpace::kStorage, type::Access::kReadWrite, Group(1_a),
               Binding(0_a));
 
     spirv::Builder& b = SanitizeAndBuild();
@@ -469,8 +472,8 @@
 TEST_F(BuilderTest, GlobalVar_TextureStorageWriteOnly) {
     // var<uniform_constant> a : texture_storage_2d<r32uint, write>;
 
-    auto* type = ty.storage_texture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Uint,
-                                    ast::Access::kWrite);
+    auto* type = ty.storage_texture(type::TextureDimension::k2d, type::TexelFormat::kR32Uint,
+                                    type::Access::kWrite);
 
     auto* var_a = GlobalVar("a", type, Binding(0_a), Group(0_a));
 
@@ -491,16 +494,16 @@
 
 TEST_F(BuilderTest, GlobalVar_WorkgroupWithZeroInit) {
     auto* type_scalar = ty.i32();
-    auto* var_scalar = GlobalVar("a", type_scalar, ast::AddressSpace::kWorkgroup);
+    auto* var_scalar = GlobalVar("a", type_scalar, type::AddressSpace::kWorkgroup);
 
     auto* type_array = ty.array<f32, 16>();
-    auto* var_array = GlobalVar("b", type_array, ast::AddressSpace::kWorkgroup);
+    auto* var_array = GlobalVar("b", type_array, type::AddressSpace::kWorkgroup);
 
     auto* type_struct = Structure("C", utils::Vector{
                                            Member("a", ty.i32()),
                                            Member("b", ty.i32()),
                                        });
-    auto* var_struct = GlobalVar("c", ty.Of(type_struct), ast::AddressSpace::kWorkgroup);
+    auto* var_struct = GlobalVar("c", ty.Of(type_struct), type::AddressSpace::kWorkgroup);
 
     program = std::make_unique<Program>(std::move(*this));
 
diff --git a/src/tint/writer/spirv/builder_ident_expression_test.cc b/src/tint/writer/spirv/builder_ident_expression_test.cc
index 5d01db3..4db5d42 100644
--- a/src/tint/writer/spirv/builder_ident_expression_test.cc
+++ b/src/tint/writer/spirv/builder_ident_expression_test.cc
@@ -41,7 +41,7 @@
 }
 
 TEST_F(BuilderTest, IdentifierExpression_GlobalVar) {
-    auto* v = GlobalVar("var", ty.f32(), ast::AddressSpace::kPrivate);
+    auto* v = GlobalVar("var", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* expr = Expr("var");
     WrapInFunction(expr);
@@ -85,7 +85,7 @@
 }
 
 TEST_F(BuilderTest, IdentifierExpression_FunctionVar) {
-    auto* v = Var("var", ty.f32(), ast::AddressSpace::kFunction);
+    auto* v = Var("var", ty.f32(), type::AddressSpace::kFunction);
     auto* expr = Expr("var");
     WrapInFunction(v, expr);
 
@@ -109,7 +109,7 @@
 }
 
 TEST_F(BuilderTest, IdentifierExpression_Load) {
-    auto* var = GlobalVar("var", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("var", ty.i32(), type::AddressSpace::kPrivate);
     auto* expr = Add("var", "var");
     WrapInFunction(expr);
 
diff --git a/src/tint/writer/spirv/builder_if_test.cc b/src/tint/writer/spirv/builder_if_test.cc
index a83b0cf..6462200 100644
--- a/src/tint/writer/spirv/builder_if_test.cc
+++ b/src/tint/writer/spirv/builder_if_test.cc
@@ -68,7 +68,7 @@
     //   v = 2;
     // }
 
-    auto* var = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("v", ty.i32(), type::AddressSpace::kPrivate);
     auto* body = Block(Assign("v", 2_i));
     auto* expr = If(true, body);
     WrapInFunction(expr);
@@ -104,7 +104,7 @@
     //   v = 3i;
     // }
 
-    auto* var = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("v", ty.i32(), type::AddressSpace::kPrivate);
     auto* body = Block(Assign("v", 2_i));
     auto* else_body = Block(Assign("v", 3_i));
 
@@ -146,7 +146,7 @@
     //   v = 3i;
     // }
 
-    auto* var = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("v", ty.i32(), type::AddressSpace::kPrivate);
     auto* body = Block(Assign("v", 2_i));
     auto* else_body = Block(Assign("v", 3_i));
 
@@ -197,7 +197,7 @@
     //   v = 5i;
     // }
 
-    auto* var = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("v", ty.i32(), type::AddressSpace::kPrivate);
     auto* body = Block(Assign("v", 2_i));
     auto* elseif_1_body = Block(Assign("v", 3_i));
     auto* elseif_2_body = Block(Assign("v", 4_i));
@@ -562,7 +562,7 @@
     // if (a) {
     // }
 
-    auto* var = GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("a", ty.bool_(), type::AddressSpace::kPrivate);
     auto* fn = Func("f", utils::Empty, ty.void_(),
                     utils::Vector{
                         If("a", Block()),
diff --git a/src/tint/writer/spirv/builder_initializer_expression_test.cc b/src/tint/writer/spirv/builder_initializer_expression_test.cc
index 07277c5..b8a1029 100644
--- a/src/tint/writer/spirv/builder_initializer_expression_test.cc
+++ b/src/tint/writer/spirv/builder_initializer_expression_test.cc
@@ -24,7 +24,7 @@
 
 TEST_F(SpvBuilderInitializerTest, Const) {
     auto* c = Expr(42.2_f);
-    auto* g = GlobalVar("g", ty.f32(), c, ast::AddressSpace::kPrivate);
+    auto* g = GlobalVar("g", ty.f32(), c, type::AddressSpace::kPrivate);
 
     spirv::Builder& b = Build();
 
@@ -1935,7 +1935,7 @@
 
 TEST_F(SpvBuilderInitializerTest, Type_GlobalVar_F32_With_F32) {
     auto* ctor = Construct<f32>(2_f);
-    GlobalVar("g", ty.f32(), ast::AddressSpace::kPrivate, ctor);
+    GlobalVar("g", ty.f32(), type::AddressSpace::kPrivate, ctor);
 
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
@@ -1954,7 +1954,7 @@
     Enable(ast::Extension::kF16);
 
     auto* ctor = Construct<f16>(2_h);
-    GlobalVar("g", ty.f16(), ast::AddressSpace::kPrivate, ctor);
+    GlobalVar("g", ty.f16(), type::AddressSpace::kPrivate, ctor);
 
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
@@ -2015,7 +2015,7 @@
 
 TEST_F(SpvBuilderInitializerTest, Type_GlobalVar_U32_With_F32) {
     auto* ctor = Construct<u32>(1.5_f);
-    GlobalVar("g", ty.u32(), ast::AddressSpace::kPrivate, ctor);
+    GlobalVar("g", ty.u32(), type::AddressSpace::kPrivate, ctor);
 
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
@@ -2034,7 +2034,7 @@
     Enable(ast::Extension::kF16);
 
     auto* ctor = Construct<u32>(1.5_h);
-    GlobalVar("g", ty.u32(), ast::AddressSpace::kPrivate, ctor);
+    GlobalVar("g", ty.u32(), type::AddressSpace::kPrivate, ctor);
 
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
@@ -2099,7 +2099,7 @@
 
 TEST_F(SpvBuilderInitializerTest, Type_GlobalVar_Vec2_With_F32) {
     auto* cast = vec2<f32>(2_f);
-    auto* g = GlobalVar("g", ty.vec2<f32>(), ast::AddressSpace::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec2<f32>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2117,7 +2117,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec2<f16>(2_h);
-    auto* g = GlobalVar("g", ty.vec2<f16>(), ast::AddressSpace::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec2<f16>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2181,7 +2181,7 @@
 
 TEST_F(SpvBuilderInitializerTest, Type_GlobalVar_Vec2_F32_With_Vec2) {
     auto* cast = vec2<f32>(vec2<f32>(2_f, 2_f));
-    GlobalVar("a", ty.vec2<f32>(), ast::AddressSpace::kPrivate, cast);
+    GlobalVar("a", ty.vec2<f32>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
@@ -2203,7 +2203,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec2<f16>(vec2<f16>(2_h, 2_h));
-    GlobalVar("a", ty.vec2<f16>(), ast::AddressSpace::kPrivate, cast);
+    GlobalVar("a", ty.vec2<f16>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
@@ -2271,7 +2271,7 @@
 
 TEST_F(SpvBuilderInitializerTest, Type_GlobalVar_Vec3_F32_With_Vec3) {
     auto* cast = vec3<f32>(vec3<f32>(2_f, 2_f, 2_f));
-    GlobalVar("a", ty.vec3<f32>(), ast::AddressSpace::kPrivate, cast);
+    GlobalVar("a", ty.vec3<f32>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
@@ -2293,7 +2293,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec3<f16>(vec3<f16>(2_h, 2_h, 2_h));
-    GlobalVar("a", ty.vec3<f16>(), ast::AddressSpace::kPrivate, cast);
+    GlobalVar("a", ty.vec3<f16>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
@@ -2361,7 +2361,7 @@
 
 TEST_F(SpvBuilderInitializerTest, Type_GlobalVar_Vec4_F32_With_Vec4) {
     auto* cast = vec4<f32>(vec4<f32>(2_f, 2_f, 2_f, 2_f));
-    GlobalVar("a", ty.vec4<f32>(), ast::AddressSpace::kPrivate, cast);
+    GlobalVar("a", ty.vec4<f32>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
@@ -2383,7 +2383,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec4<f16>(vec4<f16>(2_h, 2_h, 2_h, 2_h));
-    GlobalVar("a", ty.vec4<f16>(), ast::AddressSpace::kPrivate, cast);
+    GlobalVar("a", ty.vec4<f16>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
@@ -2451,7 +2451,7 @@
 
 TEST_F(SpvBuilderInitializerTest, Type_GlobalVar_Vec3_With_F32) {
     auto* cast = vec3<f32>(2_f);
-    auto* g = GlobalVar("g", ty.vec3<f32>(), ast::AddressSpace::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec3<f32>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2469,7 +2469,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec3<f16>(2_h);
-    auto* g = GlobalVar("g", ty.vec3<f16>(), ast::AddressSpace::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec3<f16>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2533,7 +2533,7 @@
 
 TEST_F(SpvBuilderInitializerTest, Type_GlobalVar_Vec3_With_F32_Vec2) {
     auto* cast = vec3<f32>(2_f, vec2<f32>(2_f, 2_f));
-    auto* g = GlobalVar("g", ty.vec3<f32>(), ast::AddressSpace::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec3<f32>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2551,7 +2551,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec3<f16>(2_h, vec2<f16>(2_h, 2_h));
-    auto* g = GlobalVar("g", ty.vec3<f16>(), ast::AddressSpace::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec3<f16>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2615,7 +2615,7 @@
 
 TEST_F(SpvBuilderInitializerTest, Type_GlobalVar_Vec3_With_Vec2_F32) {
     auto* cast = vec3<f32>(vec2<f32>(2_f, 2_f), 2_f);
-    auto* g = GlobalVar("g", ty.vec3<f32>(), ast::AddressSpace::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec3<f32>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2633,7 +2633,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec3<f16>(vec2<f16>(2_h, 2_h), 2_h);
-    auto* g = GlobalVar("g", ty.vec3<f16>(), ast::AddressSpace::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec3<f16>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2697,7 +2697,7 @@
 
 TEST_F(SpvBuilderInitializerTest, Type_GlobalVar_Vec4_With_F32) {
     auto* cast = vec4<f32>(2_f);
-    auto* g = GlobalVar("g", ty.vec4<f32>(), ast::AddressSpace::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f32>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2715,7 +2715,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec4<f16>(2_h);
-    auto* g = GlobalVar("g", ty.vec4<f16>(), ast::AddressSpace::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f16>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2779,7 +2779,7 @@
 
 TEST_F(SpvBuilderInitializerTest, Type_GlobalVar_Vec4_With_F32_F32_Vec2) {
     auto* cast = vec4<f32>(2_f, 2_f, vec2<f32>(2_f, 2_f));
-    auto* g = GlobalVar("g", ty.vec4<f32>(), ast::AddressSpace::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f32>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2797,7 +2797,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec4<f16>(2_h, 2_h, vec2<f16>(2_h, 2_h));
-    auto* g = GlobalVar("g", ty.vec4<f16>(), ast::AddressSpace::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f16>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2861,7 +2861,7 @@
 
 TEST_F(SpvBuilderInitializerTest, Type_GlobalVar_Vec4_With_F32_Vec2_F32) {
     auto* cast = vec4<f32>(2_f, vec2<f32>(2_f, 2_f), 2_f);
-    auto* g = GlobalVar("g", ty.vec4<f32>(), ast::AddressSpace::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f32>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2879,7 +2879,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec4<f16>(2_h, vec2<f16>(2_h, 2_h), 2_h);
-    auto* g = GlobalVar("g", ty.vec4<f16>(), ast::AddressSpace::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f16>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2943,7 +2943,7 @@
 
 TEST_F(SpvBuilderInitializerTest, Type_GlobalVar_Vec4_With_Vec2_F32_F32) {
     auto* cast = vec4<f32>(vec2<f32>(2_f, 2_f), 2_f, 2_f);
-    auto* g = GlobalVar("g", ty.vec4<f32>(), ast::AddressSpace::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f32>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2961,7 +2961,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec4<f16>(vec2<f16>(2_h, 2_h), 2_h, 2_h);
-    auto* g = GlobalVar("g", ty.vec4<f16>(), ast::AddressSpace::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f16>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -3025,7 +3025,7 @@
 
 TEST_F(SpvBuilderInitializerTest, Type_GlobalVar_Vec4_F32_With_Vec2_Vec2) {
     auto* cast = vec4<f32>(vec2<f32>(2_f, 2_f), vec2<f32>(2_f, 2_f));
-    auto* g = GlobalVar("g", ty.vec4<f32>(), ast::AddressSpace::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f32>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -3043,7 +3043,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec4<f16>(vec2<f16>(2_h, 2_h), vec2<f16>(2_h, 2_h));
-    auto* g = GlobalVar("g", ty.vec4<f16>(), ast::AddressSpace::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f16>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -3082,7 +3082,7 @@
 
 TEST_F(SpvBuilderInitializerTest, Type_GlobalVar_Vec4_With_F32_Vec3) {
     auto* cast = vec4<f32>(2_f, vec3<f32>(2_f, 2_f, 2_f));
-    auto* g = GlobalVar("g", ty.vec4<f32>(), ast::AddressSpace::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f32>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -3100,7 +3100,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec4<f16>(2_h, vec3<f16>(2_h, 2_h, 2_h));
-    auto* g = GlobalVar("g", ty.vec4<f16>(), ast::AddressSpace::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f16>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -3164,7 +3164,7 @@
 
 TEST_F(SpvBuilderInitializerTest, Type_GlobalVar_Vec4_With_Vec3_F32) {
     auto* cast = vec4<f32>(vec3<f32>(2_f, 2_f, 2_f), 2_f);
-    auto* g = GlobalVar("g", ty.vec4<f32>(), ast::AddressSpace::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f32>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -3182,7 +3182,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec4<f16>(vec3<f16>(2_h, 2_h, 2_h), 2_h);
-    auto* g = GlobalVar("g", ty.vec4<f16>(), ast::AddressSpace::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f16>(), type::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -4204,7 +4204,7 @@
 }
 
 TEST_F(SpvBuilderInitializerTest, Type_Convert_Vectors_U32_to_I32) {
-    auto* var = GlobalVar("i", ty.vec3<u32>(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("i", ty.vec3<u32>(), type::AddressSpace::kPrivate);
 
     auto* cast = vec3<i32>("i");
     WrapInFunction(cast);
@@ -4230,7 +4230,7 @@
 }
 
 TEST_F(SpvBuilderInitializerTest, Type_Convert_Vectors_F32_to_I32) {
-    auto* var = GlobalVar("i", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("i", ty.vec3<f32>(), type::AddressSpace::kPrivate);
 
     auto* cast = vec3<i32>("i");
     WrapInFunction(cast);
@@ -4258,7 +4258,7 @@
 TEST_F(SpvBuilderInitializerTest, Type_Convert_Vectors_F16_to_I32) {
     Enable(ast::Extension::kF16);
 
-    auto* var = GlobalVar("i", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("i", ty.vec3<f16>(), type::AddressSpace::kPrivate);
 
     auto* cast = vec3<i32>("i");
     WrapInFunction(cast);
@@ -4284,7 +4284,7 @@
 }
 
 TEST_F(SpvBuilderInitializerTest, Type_Convert_Vectors_I32_to_U32) {
-    auto* var = GlobalVar("i", ty.vec3<i32>(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("i", ty.vec3<i32>(), type::AddressSpace::kPrivate);
 
     auto* cast = vec3<u32>("i");
     WrapInFunction(cast);
@@ -4310,7 +4310,7 @@
 }
 
 TEST_F(SpvBuilderInitializerTest, Type_Convert_Vectors_F32_to_U32) {
-    auto* var = GlobalVar("i", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("i", ty.vec3<f32>(), type::AddressSpace::kPrivate);
 
     auto* cast = vec3<u32>("i");
     WrapInFunction(cast);
@@ -4338,7 +4338,7 @@
 TEST_F(SpvBuilderInitializerTest, Type_Convert_Vectors_F16_to_U32) {
     Enable(ast::Extension::kF16);
 
-    auto* var = GlobalVar("i", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("i", ty.vec3<f16>(), type::AddressSpace::kPrivate);
 
     auto* cast = vec3<u32>("i");
     WrapInFunction(cast);
@@ -4364,7 +4364,7 @@
 }
 
 TEST_F(SpvBuilderInitializerTest, Type_Convert_Vectors_I32_to_F32) {
-    auto* var = GlobalVar("i", ty.vec3<i32>(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("i", ty.vec3<i32>(), type::AddressSpace::kPrivate);
 
     auto* cast = vec3<f32>("i");
     WrapInFunction(cast);
@@ -4390,7 +4390,7 @@
 }
 
 TEST_F(SpvBuilderInitializerTest, Type_Convert_Vectors_U32_to_F32) {
-    auto* var = GlobalVar("i", ty.vec3<u32>(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("i", ty.vec3<u32>(), type::AddressSpace::kPrivate);
 
     auto* cast = vec3<f32>("i");
     WrapInFunction(cast);
@@ -4418,7 +4418,7 @@
 TEST_F(SpvBuilderInitializerTest, Type_Convert_Vectors_F16_to_F32) {
     Enable(ast::Extension::kF16);
 
-    auto* var = GlobalVar("i", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("i", ty.vec3<f16>(), type::AddressSpace::kPrivate);
 
     auto* cast = vec3<f32>("i");
     WrapInFunction(cast);
@@ -4446,7 +4446,7 @@
 TEST_F(SpvBuilderInitializerTest, Type_Convert_Vectors_I32_to_F16) {
     Enable(ast::Extension::kF16);
 
-    auto* var = GlobalVar("i", ty.vec3<i32>(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("i", ty.vec3<i32>(), type::AddressSpace::kPrivate);
 
     auto* cast = vec3<f16>("i");
     WrapInFunction(cast);
@@ -4474,7 +4474,7 @@
 TEST_F(SpvBuilderInitializerTest, Type_Convert_Vectors_U32_to_F16) {
     Enable(ast::Extension::kF16);
 
-    auto* var = GlobalVar("i", ty.vec3<u32>(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("i", ty.vec3<u32>(), type::AddressSpace::kPrivate);
 
     auto* cast = vec3<f16>("i");
     WrapInFunction(cast);
@@ -4502,7 +4502,7 @@
 TEST_F(SpvBuilderInitializerTest, Type_Convert_Vectors_F32_to_F16) {
     Enable(ast::Extension::kF16);
 
-    auto* var = GlobalVar("i", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("i", ty.vec3<f32>(), type::AddressSpace::kPrivate);
 
     auto* cast = vec3<f16>("i");
     WrapInFunction(cast);
@@ -4590,9 +4590,9 @@
 TEST_F(SpvBuilderInitializerTest, IsInitializerConst_Vector_WithIdent) {
     // vec3<f32>(a, b, c)  -> false
 
-    GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.f32(), ast::AddressSpace::kPrivate);
-    GlobalVar("c", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.f32(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.f32(), type::AddressSpace::kPrivate);
+    GlobalVar("c", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* t = vec3<f32>("a", "b", "c");
     WrapInFunction(t);
@@ -4662,8 +4662,8 @@
                                          Member("b", ty.vec3<f32>()),
                                      });
 
-    GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
-    GlobalVar("b", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.f32(), type::AddressSpace::kPrivate);
+    GlobalVar("b", ty.vec3<f32>(), type::AddressSpace::kPrivate);
 
     auto* t = Construct(ty.Of(s), "a", "b");
     WrapInFunction(t);
diff --git a/src/tint/writer/spirv/builder_loop_test.cc b/src/tint/writer/spirv/builder_loop_test.cc
index 9d19bde..ef8dfa8 100644
--- a/src/tint/writer/spirv/builder_loop_test.cc
+++ b/src/tint/writer/spirv/builder_loop_test.cc
@@ -54,7 +54,7 @@
     //   break;
     // }
 
-    auto* var = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("v", ty.i32(), type::AddressSpace::kPrivate);
     auto* body = Block(Assign("v", 2_i),  //
                        Break());
 
@@ -96,7 +96,7 @@
     //   }
     // }
 
-    auto* var = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* var = GlobalVar("v", ty.i32(), type::AddressSpace::kPrivate);
     auto* body = Block(Assign("v", 2_i),  //
                        Break());
     auto* continuing = Block(Assign("v", 3_i));
diff --git a/src/tint/writer/spirv/builder_switch_test.cc b/src/tint/writer/spirv/builder_switch_test.cc
index 6cf8fad..a04a194 100644
--- a/src/tint/writer/spirv/builder_switch_test.cc
+++ b/src/tint/writer/spirv/builder_switch_test.cc
@@ -56,8 +56,8 @@
     //   default: {}
     // }
 
-    auto* v = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
-    auto* a = GlobalVar("a", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* v = GlobalVar("v", ty.i32(), type::AddressSpace::kPrivate);
+    auto* a = GlobalVar("a", ty.i32(), type::AddressSpace::kPrivate);
 
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -113,8 +113,8 @@
     //   default: {}
     // }
 
-    auto* v = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
-    auto* a = GlobalVar("a", ty.u32(), ast::AddressSpace::kPrivate);
+    auto* v = GlobalVar("v", ty.i32(), type::AddressSpace::kPrivate);
+    auto* a = GlobalVar("a", ty.u32(), type::AddressSpace::kPrivate);
 
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -170,8 +170,8 @@
     //     v = 1i;
     //  }
 
-    auto* v = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
-    auto* a = GlobalVar("a", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* v = GlobalVar("v", ty.i32(), type::AddressSpace::kPrivate);
+    auto* a = GlobalVar("a", ty.i32(), type::AddressSpace::kPrivate);
 
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -220,8 +220,8 @@
     //      v = 3i;
     //  }
 
-    auto* v = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
-    auto* a = GlobalVar("a", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* v = GlobalVar("v", ty.i32(), type::AddressSpace::kPrivate);
+    auto* a = GlobalVar("a", ty.i32(), type::AddressSpace::kPrivate);
 
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -280,8 +280,8 @@
     //      v = 2i;
     //  }
 
-    auto* v = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
-    auto* a = GlobalVar("a", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* v = GlobalVar("v", ty.i32(), type::AddressSpace::kPrivate);
+    auto* a = GlobalVar("a", ty.i32(), type::AddressSpace::kPrivate);
 
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{Switch(Expr("a"),                      //
@@ -337,8 +337,8 @@
     //   default: {}
     // }
 
-    auto* v = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
-    auto* a = GlobalVar("a", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* v = GlobalVar("v", ty.i32(), type::AddressSpace::kPrivate);
+    auto* a = GlobalVar("a", ty.i32(), type::AddressSpace::kPrivate);
 
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
diff --git a/src/tint/writer/spirv/builder_type_test.cc b/src/tint/writer/spirv/builder_type_test.cc
index d698593..64f6f98 100644
--- a/src/tint/writer/spirv/builder_type_test.cc
+++ b/src/tint/writer/spirv/builder_type_test.cc
@@ -15,6 +15,7 @@
 #include "src/tint/type/depth_texture.h"
 #include "src/tint/type/multisampled_texture.h"
 #include "src/tint/type/sampled_texture.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/writer/spirv/spv_dump.h"
 #include "src/tint/writer/spirv/test_helper.h"
 
@@ -28,7 +29,7 @@
 TEST_F(BuilderTest_Type, GenerateRuntimeArray) {
     auto* ary = ty.array(ty.i32());
     auto* str = Structure("S", utils::Vector{Member("x", ary)});
-    GlobalVar("a", ty.Of(str), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("a", ty.Of(str), type::AddressSpace::kStorage, type::Access::kRead, Binding(0_a),
               Group(0_a));
 
     spirv::Builder& b = Build();
@@ -45,7 +46,7 @@
 TEST_F(BuilderTest_Type, ReturnsGeneratedRuntimeArray) {
     auto* ary = ty.array(ty.i32());
     auto* str = Structure("S", utils::Vector{Member("x", ary)});
-    GlobalVar("a", ty.Of(str), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("a", ty.Of(str), type::AddressSpace::kStorage, type::Access::kRead, Binding(0_a),
               Group(0_a));
 
     spirv::Builder& b = Build();
@@ -61,7 +62,7 @@
 
 TEST_F(BuilderTest_Type, GenerateArray) {
     auto* ary = ty.array(ty.i32(), 4_u);
-    GlobalVar("a", ary, ast::AddressSpace::kPrivate);
+    GlobalVar("a", ary, type::AddressSpace::kPrivate);
 
     spirv::Builder& b = Build();
 
@@ -78,7 +79,7 @@
 
 TEST_F(BuilderTest_Type, GenerateArray_WithStride) {
     auto* ary = ty.array(ty.i32(), 4_u, 16u);
-    GlobalVar("a", ary, ast::AddressSpace::kPrivate);
+    GlobalVar("a", ary, type::AddressSpace::kPrivate);
 
     spirv::Builder& b = Build();
 
@@ -98,7 +99,7 @@
 
 TEST_F(BuilderTest_Type, ReturnsGeneratedArray) {
     auto* ary = ty.array(ty.i32(), 4_u);
-    GlobalVar("a", ary, ast::AddressSpace::kPrivate);
+    GlobalVar("a", ary, type::AddressSpace::kPrivate);
 
     spirv::Builder& b = Build();
 
@@ -293,7 +294,7 @@
 
 TEST_F(BuilderTest_Type, GeneratePtr) {
     auto* i32 = create<type::I32>();
-    auto* ptr = create<type::Pointer>(i32, ast::AddressSpace::kOut, ast::Access::kReadWrite);
+    auto* ptr = create<type::Pointer>(i32, type::AddressSpace::kOut, type::Access::kReadWrite);
 
     spirv::Builder& b = Build();
 
@@ -308,7 +309,7 @@
 
 TEST_F(BuilderTest_Type, ReturnsGeneratedPtr) {
     auto* i32 = create<type::I32>();
-    auto* ptr = create<type::Pointer>(i32, ast::AddressSpace::kOut, ast::Access::kReadWrite);
+    auto* ptr = create<type::Pointer>(i32, type::AddressSpace::kOut, type::Access::kReadWrite);
 
     spirv::Builder& b = Build();
 
@@ -602,7 +603,7 @@
 }
 
 struct PtrData {
-    ast::AddressSpace ast_class;
+    type::AddressSpace ast_class;
     SpvStorageClass result;
 };
 inline std::ostream& operator<<(std::ostream& out, PtrData data) {
@@ -620,18 +621,18 @@
 INSTANTIATE_TEST_SUITE_P(
     BuilderTest_Type,
     PtrDataTest,
-    testing::Values(PtrData{ast::AddressSpace::kNone, SpvStorageClassMax},
-                    PtrData{ast::AddressSpace::kIn, SpvStorageClassInput},
-                    PtrData{ast::AddressSpace::kOut, SpvStorageClassOutput},
-                    PtrData{ast::AddressSpace::kUniform, SpvStorageClassUniform},
-                    PtrData{ast::AddressSpace::kWorkgroup, SpvStorageClassWorkgroup},
-                    PtrData{ast::AddressSpace::kHandle, SpvStorageClassUniformConstant},
-                    PtrData{ast::AddressSpace::kStorage, SpvStorageClassStorageBuffer},
-                    PtrData{ast::AddressSpace::kPrivate, SpvStorageClassPrivate},
-                    PtrData{ast::AddressSpace::kFunction, SpvStorageClassFunction}));
+    testing::Values(PtrData{type::AddressSpace::kNone, SpvStorageClassMax},
+                    PtrData{type::AddressSpace::kIn, SpvStorageClassInput},
+                    PtrData{type::AddressSpace::kOut, SpvStorageClassOutput},
+                    PtrData{type::AddressSpace::kUniform, SpvStorageClassUniform},
+                    PtrData{type::AddressSpace::kWorkgroup, SpvStorageClassWorkgroup},
+                    PtrData{type::AddressSpace::kHandle, SpvStorageClassUniformConstant},
+                    PtrData{type::AddressSpace::kStorage, SpvStorageClassStorageBuffer},
+                    PtrData{type::AddressSpace::kPrivate, SpvStorageClassPrivate},
+                    PtrData{type::AddressSpace::kFunction, SpvStorageClassFunction}));
 
 TEST_F(BuilderTest_Type, DepthTexture_Generate_2d) {
-    auto* two_d = create<type::DepthTexture>(ast::TextureDimension::k2d);
+    auto* two_d = create<type::DepthTexture>(type::TextureDimension::k2d);
 
     spirv::Builder& b = Build();
 
@@ -645,7 +646,7 @@
 }
 
 TEST_F(BuilderTest_Type, DepthTexture_Generate_2dArray) {
-    auto* two_d_array = create<type::DepthTexture>(ast::TextureDimension::k2dArray);
+    auto* two_d_array = create<type::DepthTexture>(type::TextureDimension::k2dArray);
 
     spirv::Builder& b = Build();
 
@@ -659,7 +660,7 @@
 }
 
 TEST_F(BuilderTest_Type, DepthTexture_Generate_Cube) {
-    auto* cube = create<type::DepthTexture>(ast::TextureDimension::kCube);
+    auto* cube = create<type::DepthTexture>(type::TextureDimension::kCube);
 
     spirv::Builder& b = Build();
 
@@ -674,7 +675,7 @@
 }
 
 TEST_F(BuilderTest_Type, DepthTexture_Generate_CubeArray) {
-    auto* cube_array = create<type::DepthTexture>(ast::TextureDimension::kCubeArray);
+    auto* cube_array = create<type::DepthTexture>(type::TextureDimension::kCubeArray);
 
     spirv::Builder& b = Build();
 
@@ -692,7 +693,7 @@
 
 TEST_F(BuilderTest_Type, MultisampledTexture_Generate_2d_i32) {
     auto* i32 = create<type::I32>();
-    auto* ms = create<type::MultisampledTexture>(ast::TextureDimension::k2d, i32);
+    auto* ms = create<type::MultisampledTexture>(type::TextureDimension::k2d, i32);
 
     spirv::Builder& b = Build();
 
@@ -705,7 +706,7 @@
 
 TEST_F(BuilderTest_Type, MultisampledTexture_Generate_2d_u32) {
     auto* u32 = create<type::U32>();
-    auto* ms = create<type::MultisampledTexture>(ast::TextureDimension::k2d, u32);
+    auto* ms = create<type::MultisampledTexture>(type::TextureDimension::k2d, u32);
 
     spirv::Builder& b = Build();
 
@@ -719,7 +720,7 @@
 
 TEST_F(BuilderTest_Type, MultisampledTexture_Generate_2d_f32) {
     auto* f32 = create<type::F32>();
-    auto* ms = create<type::MultisampledTexture>(ast::TextureDimension::k2d, f32);
+    auto* ms = create<type::MultisampledTexture>(type::TextureDimension::k2d, f32);
 
     spirv::Builder& b = Build();
 
@@ -732,7 +733,7 @@
 }
 
 TEST_F(BuilderTest_Type, SampledTexture_Generate_1d_i32) {
-    auto* s = create<type::SampledTexture>(ast::TextureDimension::k1d, create<type::I32>());
+    auto* s = create<type::SampledTexture>(type::TextureDimension::k1d, create<type::I32>());
 
     spirv::Builder& b = Build();
 
@@ -750,7 +751,7 @@
 
 TEST_F(BuilderTest_Type, SampledTexture_Generate_1d_u32) {
     auto* u32 = create<type::U32>();
-    auto* s = create<type::SampledTexture>(ast::TextureDimension::k1d, u32);
+    auto* s = create<type::SampledTexture>(type::TextureDimension::k1d, u32);
 
     spirv::Builder& b = Build();
 
@@ -768,7 +769,7 @@
 
 TEST_F(BuilderTest_Type, SampledTexture_Generate_1d_f32) {
     auto* f32 = create<type::F32>();
-    auto* s = create<type::SampledTexture>(ast::TextureDimension::k1d, f32);
+    auto* s = create<type::SampledTexture>(type::TextureDimension::k1d, f32);
 
     spirv::Builder& b = Build();
 
@@ -786,7 +787,7 @@
 
 TEST_F(BuilderTest_Type, SampledTexture_Generate_2d) {
     auto* f32 = create<type::F32>();
-    auto* s = create<type::SampledTexture>(ast::TextureDimension::k2d, f32);
+    auto* s = create<type::SampledTexture>(type::TextureDimension::k2d, f32);
 
     spirv::Builder& b = Build();
 
@@ -800,7 +801,7 @@
 
 TEST_F(BuilderTest_Type, SampledTexture_Generate_2d_array) {
     auto* f32 = create<type::F32>();
-    auto* s = create<type::SampledTexture>(ast::TextureDimension::k2dArray, f32);
+    auto* s = create<type::SampledTexture>(type::TextureDimension::k2dArray, f32);
 
     spirv::Builder& b = Build();
 
@@ -814,7 +815,7 @@
 
 TEST_F(BuilderTest_Type, SampledTexture_Generate_3d) {
     auto* f32 = create<type::F32>();
-    auto* s = create<type::SampledTexture>(ast::TextureDimension::k3d, f32);
+    auto* s = create<type::SampledTexture>(type::TextureDimension::k3d, f32);
 
     spirv::Builder& b = Build();
 
@@ -828,7 +829,7 @@
 
 TEST_F(BuilderTest_Type, SampledTexture_Generate_Cube) {
     auto* f32 = create<type::F32>();
-    auto* s = create<type::SampledTexture>(ast::TextureDimension::kCube, f32);
+    auto* s = create<type::SampledTexture>(type::TextureDimension::kCube, f32);
 
     spirv::Builder& b = Build();
 
@@ -843,7 +844,7 @@
 
 TEST_F(BuilderTest_Type, SampledTexture_Generate_CubeArray) {
     auto* f32 = create<type::F32>();
-    auto* s = create<type::SampledTexture>(ast::TextureDimension::kCubeArray, f32);
+    auto* s = create<type::SampledTexture>(type::TextureDimension::kCubeArray, f32);
 
     spirv::Builder& b = Build();
 
@@ -859,8 +860,8 @@
 }
 
 TEST_F(BuilderTest_Type, StorageTexture_Generate_1d) {
-    auto* s = ty.storage_texture(ast::TextureDimension::k1d, ast::TexelFormat::kR32Float,
-                                 ast::Access::kWrite);
+    auto* s = ty.storage_texture(type::TextureDimension::k1d, type::TexelFormat::kR32Float,
+                                 type::Access::kWrite);
 
     GlobalVar("test_var", s, Binding(0_a), Group(0_a));
 
@@ -874,8 +875,8 @@
 }
 
 TEST_F(BuilderTest_Type, StorageTexture_Generate_2d) {
-    auto* s = ty.storage_texture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Float,
-                                 ast::Access::kWrite);
+    auto* s = ty.storage_texture(type::TextureDimension::k2d, type::TexelFormat::kR32Float,
+                                 type::Access::kWrite);
 
     GlobalVar("test_var", s, Binding(0_a), Group(0_a));
 
@@ -889,8 +890,8 @@
 }
 
 TEST_F(BuilderTest_Type, StorageTexture_Generate_2dArray) {
-    auto* s = ty.storage_texture(ast::TextureDimension::k2dArray, ast::TexelFormat::kR32Float,
-                                 ast::Access::kWrite);
+    auto* s = ty.storage_texture(type::TextureDimension::k2dArray, type::TexelFormat::kR32Float,
+                                 type::Access::kWrite);
 
     GlobalVar("test_var", s, Binding(0_a), Group(0_a));
 
@@ -904,8 +905,8 @@
 }
 
 TEST_F(BuilderTest_Type, StorageTexture_Generate_3d) {
-    auto* s = ty.storage_texture(ast::TextureDimension::k3d, ast::TexelFormat::kR32Float,
-                                 ast::Access::kWrite);
+    auto* s = ty.storage_texture(type::TextureDimension::k3d, type::TexelFormat::kR32Float,
+                                 type::Access::kWrite);
 
     GlobalVar("test_var", s, Binding(0_a), Group(0_a));
 
@@ -919,8 +920,8 @@
 }
 
 TEST_F(BuilderTest_Type, StorageTexture_Generate_SampledTypeFloat_Format_r32float) {
-    auto* s = ty.storage_texture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Float,
-                                 ast::Access::kWrite);
+    auto* s = ty.storage_texture(type::TextureDimension::k2d, type::TexelFormat::kR32Float,
+                                 type::Access::kWrite);
 
     GlobalVar("test_var", s, Binding(0_a), Group(0_a));
 
@@ -934,8 +935,8 @@
 }
 
 TEST_F(BuilderTest_Type, StorageTexture_Generate_SampledTypeSint_Format_r32sint) {
-    auto* s = ty.storage_texture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Sint,
-                                 ast::Access::kWrite);
+    auto* s = ty.storage_texture(type::TextureDimension::k2d, type::TexelFormat::kR32Sint,
+                                 type::Access::kWrite);
 
     GlobalVar("test_var", s, Binding(0_a), Group(0_a));
 
@@ -949,8 +950,8 @@
 }
 
 TEST_F(BuilderTest_Type, StorageTexture_Generate_SampledTypeUint_Format_r32uint) {
-    auto* s = ty.storage_texture(ast::TextureDimension::k2d, ast::TexelFormat::kR32Uint,
-                                 ast::Access::kWrite);
+    auto* s = ty.storage_texture(type::TextureDimension::k2d, type::TexelFormat::kR32Uint,
+                                 type::Access::kWrite);
 
     GlobalVar("test_var", s, Binding(0_a), Group(0_a));
 
diff --git a/src/tint/writer/wgsl/generator_impl.cc b/src/tint/writer/wgsl/generator_impl.cc
index f02d96c..0c20af7 100644
--- a/src/tint/writer/wgsl/generator_impl.cc
+++ b/src/tint/writer/wgsl/generator_impl.cc
@@ -16,7 +16,6 @@
 
 #include <algorithm>
 
-#include "src/tint/ast/access.h"
 #include "src/tint/ast/alias.h"
 #include "src/tint/ast/array.h"
 #include "src/tint/ast/atomic.h"
@@ -51,6 +50,8 @@
 #include "src/tint/ast/workgroup_attribute.h"
 #include "src/tint/sem/struct.h"
 #include "src/tint/sem/switch_statement.h"
+#include "src/tint/type/access.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/utils/math.h"
 #include "src/tint/utils/scoped_assignment.h"
 #include "src/tint/writer/float_to_string.h"
@@ -349,9 +350,9 @@
     return true;
 }
 
-bool GeneratorImpl::EmitImageFormat(std::ostream& out, const ast::TexelFormat fmt) {
+bool GeneratorImpl::EmitImageFormat(std::ostream& out, const type::TexelFormat fmt) {
     switch (fmt) {
-        case ast::TexelFormat::kUndefined:
+        case type::TexelFormat::kUndefined:
             diagnostics_.add_error(diag::System::Writer, "unknown image format");
             return false;
         default:
@@ -360,15 +361,15 @@
     return true;
 }
 
-bool GeneratorImpl::EmitAccess(std::ostream& out, const ast::Access access) {
+bool GeneratorImpl::EmitAccess(std::ostream& out, const type::Access access) {
     switch (access) {
-        case ast::Access::kRead:
+        case type::Access::kRead:
             out << "read";
             return true;
-        case ast::Access::kWrite:
+        case type::Access::kWrite:
             out << "write";
             return true;
-        case ast::Access::kReadWrite:
+        case type::Access::kReadWrite:
             out << "read_write";
             return true;
         default:
@@ -438,7 +439,7 @@
             if (!EmitType(out, ptr->type)) {
                 return false;
             }
-            if (ptr->access != ast::Access::kUndefined) {
+            if (ptr->access != type::Access::kUndefined) {
                 out << ", ";
                 if (!EmitAccess(out, ptr->access)) {
                     return false;
@@ -500,22 +501,22 @@
             }
 
             switch (texture->dim) {
-                case ast::TextureDimension::k1d:
+                case type::TextureDimension::k1d:
                     out << "1d";
                     break;
-                case ast::TextureDimension::k2d:
+                case type::TextureDimension::k2d:
                     out << "2d";
                     break;
-                case ast::TextureDimension::k2dArray:
+                case type::TextureDimension::k2dArray:
                     out << "2d_array";
                     break;
-                case ast::TextureDimension::k3d:
+                case type::TextureDimension::k3d:
                     out << "3d";
                     break;
-                case ast::TextureDimension::kCube:
+                case type::TextureDimension::kCube:
                     out << "cube";
                     break;
-                case ast::TextureDimension::kCubeArray:
+                case type::TextureDimension::kCubeArray:
                     out << "cube_array";
                     break;
                 default:
@@ -668,9 +669,9 @@
             out << "var";
             auto address_space = var->declared_address_space;
             auto ac = var->declared_access;
-            if (address_space != ast::AddressSpace::kNone || ac != ast::Access::kUndefined) {
+            if (address_space != type::AddressSpace::kNone || ac != type::Access::kUndefined) {
                 out << "<" << address_space;
-                if (ac != ast::Access::kUndefined) {
+                if (ac != type::Access::kUndefined) {
                     out << ", ";
                     if (!EmitAccess(out, ac)) {
                         return false;
diff --git a/src/tint/writer/wgsl/generator_impl.h b/src/tint/writer/wgsl/generator_impl.h
index 71c3bd1..f314efb 100644
--- a/src/tint/writer/wgsl/generator_impl.h
+++ b/src/tint/writer/wgsl/generator_impl.h
@@ -198,12 +198,12 @@
     /// @param out the output of the expression stream
     /// @param fmt the format to generate
     /// @returns true if the format is emitted
-    bool EmitImageFormat(std::ostream& out, const ast::TexelFormat fmt);
+    bool EmitImageFormat(std::ostream& out, const type::TexelFormat fmt);
     /// Handles emitting an access control
     /// @param out the output of the expression stream
     /// @param access the access to generate
     /// @returns true if the access is emitted
-    bool EmitAccess(std::ostream& out, const ast::Access access);
+    bool EmitAccess(std::ostream& out, const type::Access access);
     /// Handles a unary op expression
     /// @param out the output of the expression stream
     /// @param expr the expression to emit
diff --git a/src/tint/writer/wgsl/generator_impl_array_accessor_test.cc b/src/tint/writer/wgsl/generator_impl_array_accessor_test.cc
index 652f598..ed05a2d 100644
--- a/src/tint/writer/wgsl/generator_impl_array_accessor_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_array_accessor_test.cc
@@ -22,7 +22,7 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, IndexAccessor) {
-    GlobalVar("ary", ty.array<i32, 10>(), ast::AddressSpace::kPrivate);
+    GlobalVar("ary", ty.array<i32, 10>(), type::AddressSpace::kPrivate);
     auto* expr = IndexAccessor("ary", 5_i);
     WrapInFunction(expr);
 
@@ -34,7 +34,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, IndexAccessor_OfDref) {
-    GlobalVar("ary", ty.array<i32, 10>(), ast::AddressSpace::kPrivate);
+    GlobalVar("ary", ty.array<i32, 10>(), type::AddressSpace::kPrivate);
 
     auto* p = Let("p", AddressOf("ary"));
     auto* expr = IndexAccessor(Deref("p"), 5_i);
diff --git a/src/tint/writer/wgsl/generator_impl_assign_test.cc b/src/tint/writer/wgsl/generator_impl_assign_test.cc
index 85d4d90..3a6dd1a 100644
--- a/src/tint/writer/wgsl/generator_impl_assign_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_assign_test.cc
@@ -20,8 +20,8 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, Emit_Assign) {
-    auto* lhs = GlobalVar("lhs", ty.i32(), ast::AddressSpace::kPrivate);
-    auto* rhs = GlobalVar("rhs", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* lhs = GlobalVar("lhs", ty.i32(), type::AddressSpace::kPrivate);
+    auto* rhs = GlobalVar("rhs", ty.i32(), type::AddressSpace::kPrivate);
     auto* assign = Assign(lhs, rhs);
     WrapInFunction(assign);
 
diff --git a/src/tint/writer/wgsl/generator_impl_binary_test.cc b/src/tint/writer/wgsl/generator_impl_binary_test.cc
index d069fe6..8368ad8 100644
--- a/src/tint/writer/wgsl/generator_impl_binary_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_binary_test.cc
@@ -37,8 +37,8 @@
         }
     };
 
-    GlobalVar("left", op_ty(), ast::AddressSpace::kPrivate);
-    GlobalVar("right", op_ty(), ast::AddressSpace::kPrivate);
+    GlobalVar("left", op_ty(), type::AddressSpace::kPrivate);
+    GlobalVar("right", op_ty(), type::AddressSpace::kPrivate);
     auto* left = Expr("left");
     auto* right = Expr("right");
 
diff --git a/src/tint/writer/wgsl/generator_impl_call_test.cc b/src/tint/writer/wgsl/generator_impl_call_test.cc
index 6b22d2a..39a287c 100644
--- a/src/tint/writer/wgsl/generator_impl_call_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_call_test.cc
@@ -48,8 +48,8 @@
          utils::Vector{
              Return(1.23_f),
          });
-    GlobalVar("param1", ty.f32(), ast::AddressSpace::kPrivate);
-    GlobalVar("param2", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("param1", ty.f32(), type::AddressSpace::kPrivate);
+    GlobalVar("param2", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* call = Call("my_func", "param1", "param2");
     WrapInFunction(call);
@@ -68,8 +68,8 @@
              Param(Sym(), ty.f32()),
          },
          ty.void_(), utils::Empty, utils::Empty);
-    GlobalVar("param1", ty.f32(), ast::AddressSpace::kPrivate);
-    GlobalVar("param2", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("param1", ty.f32(), type::AddressSpace::kPrivate);
+    GlobalVar("param2", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* call = Call("my_func", "param1", "param2");
     auto* stmt = CallStmt(call);
diff --git a/src/tint/writer/wgsl/generator_impl_function_test.cc b/src/tint/writer/wgsl/generator_impl_function_test.cc
index e785520..6550b6a 100644
--- a/src/tint/writer/wgsl/generator_impl_function_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_function_test.cc
@@ -179,8 +179,8 @@
                                     Member("d", ty.f32()),
                                 });
 
-    GlobalVar("data", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(0_a),
-              Group(0_a));
+    GlobalVar("data", ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite,
+              Binding(0_a), Group(0_a));
 
     {
         auto* var = Var("v", ty.f32(), MemberAccessor("data", "d"));
diff --git a/src/tint/writer/wgsl/generator_impl_global_decl_test.cc b/src/tint/writer/wgsl/generator_impl_global_decl_test.cc
index 939b5b3..65366c8 100644
--- a/src/tint/writer/wgsl/generator_impl_global_decl_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_global_decl_test.cc
@@ -15,6 +15,7 @@
 #include "src/tint/ast/stage_attribute.h"
 #include "src/tint/ast/variable_decl_statement.h"
 #include "src/tint/type/sampled_texture.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/writer/wgsl/test_helper.h"
 
 using namespace tint::number_suffixes;  // NOLINT
@@ -28,7 +29,7 @@
     auto* func_var = Var("a", ty.f32());
     WrapInFunction(func_var);
 
-    GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.f32(), type::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
@@ -45,7 +46,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_GlobalsInterleaved) {
-    GlobalVar("a0", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("a0", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* s0 = Structure("S0", utils::Vector{
                                    Member("a", ty.i32()),
@@ -57,7 +58,7 @@
          },
          utils::Empty);
 
-    GlobalVar("a1", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("a1", ty.f32(), type::AddressSpace::kPrivate);
 
     auto* s1 = Structure("S1", utils::Vector{
                                    Member("a", ty.i32()),
@@ -116,7 +117,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_Global_Texture) {
-    auto* st = ty.sampled_texture(ast::TextureDimension::k1d, ty.f32());
+    auto* st = ty.sampled_texture(type::TextureDimension::k1d, ty.f32());
     GlobalVar("t", st, Group(0_a), Binding(0_a));
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/wgsl/generator_impl_identifier_test.cc b/src/tint/writer/wgsl/generator_impl_identifier_test.cc
index 25e2a7a..e0b167f 100644
--- a/src/tint/writer/wgsl/generator_impl_identifier_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_identifier_test.cc
@@ -20,7 +20,7 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, EmitIdentifierExpression_Single) {
-    GlobalVar("glsl", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("glsl", ty.f32(), type::AddressSpace::kPrivate);
     auto* i = Expr("glsl");
     WrapInFunction(i);
 
diff --git a/src/tint/writer/wgsl/generator_impl_if_test.cc b/src/tint/writer/wgsl/generator_impl_if_test.cc
index eeaa75f..0831f89 100644
--- a/src/tint/writer/wgsl/generator_impl_if_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_if_test.cc
@@ -20,7 +20,7 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, Emit_If) {
-    GlobalVar("cond", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("cond", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* cond = Expr("cond");
     auto* body = Block(Return());
@@ -39,8 +39,8 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_IfWithElseIf) {
-    GlobalVar("cond", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("else_cond", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("cond", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("else_cond", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* else_cond = Expr("else_cond");
     auto* else_body = Block(Return());
@@ -64,7 +64,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_IfWithElse) {
-    GlobalVar("cond", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("cond", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* else_body = Block(Return());
 
@@ -87,8 +87,8 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_IfWithMultiple) {
-    GlobalVar("cond", ty.bool_(), ast::AddressSpace::kPrivate);
-    GlobalVar("else_cond", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("cond", ty.bool_(), type::AddressSpace::kPrivate);
+    GlobalVar("else_cond", ty.bool_(), type::AddressSpace::kPrivate);
 
     auto* else_cond = Expr("else_cond");
 
diff --git a/src/tint/writer/wgsl/generator_impl_loop_test.cc b/src/tint/writer/wgsl/generator_impl_loop_test.cc
index ac3f808..f4d6f46 100644
--- a/src/tint/writer/wgsl/generator_impl_loop_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_loop_test.cc
@@ -96,7 +96,7 @@
     // for({ignore(1i); ignore(2i);}; ; ) {
     //   return;
     // }
-    GlobalVar("a", ty.atomic<i32>(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("a", ty.atomic<i32>(), type::AddressSpace::kWorkgroup);
     auto* multi_stmt = Block(Ignore(1_i), Ignore(2_i));
     auto* f = For(multi_stmt, nullptr, nullptr, Block(Return()));
     WrapInFunction(f);
@@ -160,7 +160,7 @@
     //   return;
     // }
 
-    GlobalVar("a", ty.atomic<i32>(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("a", ty.atomic<i32>(), type::AddressSpace::kWorkgroup);
     auto* multi_stmt = Block(Ignore(1_i), Ignore(2_i));
     auto* f = For(nullptr, nullptr, multi_stmt, Block(Return()));
     WrapInFunction(f);
@@ -203,7 +203,7 @@
     // for({ ignore(1i); ignore(2i); }; true; { ignore(3i); ignore(4i); }) {
     //   return;
     // }
-    GlobalVar("a", ty.atomic<i32>(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("a", ty.atomic<i32>(), type::AddressSpace::kWorkgroup);
     auto* multi_stmt_a = Block(Ignore(1_i), Ignore(2_i));
     auto* multi_stmt_b = Block(Ignore(3_i), Ignore(4_i));
     auto* f = For(multi_stmt_a, Expr(true), multi_stmt_b, Block(Return()));
diff --git a/src/tint/writer/wgsl/generator_impl_member_accessor_test.cc b/src/tint/writer/wgsl/generator_impl_member_accessor_test.cc
index 9bb695d..5f7ebb5 100644
--- a/src/tint/writer/wgsl/generator_impl_member_accessor_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_member_accessor_test.cc
@@ -21,7 +21,7 @@
 
 TEST_F(WgslGeneratorImplTest, EmitExpression_MemberAccessor) {
     auto* s = Structure("Data", utils::Vector{Member("mem", ty.f32())});
-    GlobalVar("str", ty.Of(s), ast::AddressSpace::kPrivate);
+    GlobalVar("str", ty.Of(s), type::AddressSpace::kPrivate);
 
     auto* expr = MemberAccessor("str", "mem");
     WrapInFunction(expr);
@@ -35,7 +35,7 @@
 
 TEST_F(WgslGeneratorImplTest, EmitExpression_MemberAccessor_OfDref) {
     auto* s = Structure("Data", utils::Vector{Member("mem", ty.f32())});
-    GlobalVar("str", ty.Of(s), ast::AddressSpace::kPrivate);
+    GlobalVar("str", ty.Of(s), type::AddressSpace::kPrivate);
 
     auto* p = Let("p", AddressOf("str"));
     auto* expr = MemberAccessor(Deref("p"), "mem");
diff --git a/src/tint/writer/wgsl/generator_impl_switch_test.cc b/src/tint/writer/wgsl/generator_impl_switch_test.cc
index 7a39079..24dbae1 100644
--- a/src/tint/writer/wgsl/generator_impl_switch_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_switch_test.cc
@@ -22,7 +22,7 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, Emit_Switch) {
-    GlobalVar("cond", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("cond", ty.i32(), type::AddressSpace::kPrivate);
 
     auto* def_body = Block(create<ast::BreakStatement>());
     auto* def = Case(DefaultCaseSelector(), def_body);
@@ -56,7 +56,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_Switch_MixedDefault) {
-    GlobalVar("cond", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("cond", ty.i32(), type::AddressSpace::kPrivate);
 
     auto* def_body = Block(create<ast::BreakStatement>());
     auto* def = Case(utils::Vector{CaseSelector(5_i), DefaultCaseSelector()}, def_body);
diff --git a/src/tint/writer/wgsl/generator_impl_type_test.cc b/src/tint/writer/wgsl/generator_impl_type_test.cc
index a1c3505..8725d0e 100644
--- a/src/tint/writer/wgsl/generator_impl_type_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_type_test.cc
@@ -15,6 +15,7 @@
 #include "src/tint/type/depth_texture.h"
 #include "src/tint/type/multisampled_texture.h"
 #include "src/tint/type/sampled_texture.h"
+#include "src/tint/type/texture_dimension.h"
 #include "src/tint/writer/wgsl/test_helper.h"
 
 using namespace tint::number_suffixes;  // NOLINT
@@ -140,7 +141,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitType_Pointer) {
-    auto* p = ty.pointer<f32>(ast::AddressSpace::kWorkgroup);
+    auto* p = ty.pointer<f32>(type::AddressSpace::kWorkgroup);
     Alias("make_type_reachable", p);
 
     GeneratorImpl& gen = Build();
@@ -151,7 +152,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitType_PointerAccessMode) {
-    auto* p = ty.pointer<f32>(ast::AddressSpace::kStorage, ast::Access::kReadWrite);
+    auto* p = ty.pointer<f32>(type::AddressSpace::kStorage, type::Access::kReadWrite);
     Alias("make_type_reachable", p);
 
     GeneratorImpl& gen = Build();
@@ -329,7 +330,7 @@
 }
 
 struct TextureData {
-    ast::TextureDimension dim;
+    type::TextureDimension dim;
     const char* name;
 };
 inline std::ostream& operator<<(std::ostream& out, TextureData data) {
@@ -353,10 +354,10 @@
 INSTANTIATE_TEST_SUITE_P(
     WgslGeneratorImplTest,
     WgslGenerator_DepthTextureTest,
-    testing::Values(TextureData{ast::TextureDimension::k2d, "texture_depth_2d"},
-                    TextureData{ast::TextureDimension::k2dArray, "texture_depth_2d_array"},
-                    TextureData{ast::TextureDimension::kCube, "texture_depth_cube"},
-                    TextureData{ast::TextureDimension::kCubeArray, "texture_depth_cube_array"}));
+    testing::Values(TextureData{type::TextureDimension::k2d, "texture_depth_2d"},
+                    TextureData{type::TextureDimension::k2dArray, "texture_depth_2d_array"},
+                    TextureData{type::TextureDimension::kCube, "texture_depth_cube"},
+                    TextureData{type::TextureDimension::kCubeArray, "texture_depth_cube_array"}));
 
 using WgslGenerator_SampledTextureTest = TestParamHelper<TextureData>;
 TEST_P(WgslGenerator_SampledTextureTest, EmitType_SampledTexture_F32) {
@@ -400,12 +401,12 @@
 INSTANTIATE_TEST_SUITE_P(
     WgslGeneratorImplTest,
     WgslGenerator_SampledTextureTest,
-    testing::Values(TextureData{ast::TextureDimension::k1d, "texture_1d"},
-                    TextureData{ast::TextureDimension::k2d, "texture_2d"},
-                    TextureData{ast::TextureDimension::k2dArray, "texture_2d_array"},
-                    TextureData{ast::TextureDimension::k3d, "texture_3d"},
-                    TextureData{ast::TextureDimension::kCube, "texture_cube"},
-                    TextureData{ast::TextureDimension::kCubeArray, "texture_cube_array"}));
+    testing::Values(TextureData{type::TextureDimension::k1d, "texture_1d"},
+                    TextureData{type::TextureDimension::k2d, "texture_2d"},
+                    TextureData{type::TextureDimension::k2dArray, "texture_2d_array"},
+                    TextureData{type::TextureDimension::k3d, "texture_3d"},
+                    TextureData{type::TextureDimension::kCube, "texture_cube"},
+                    TextureData{type::TextureDimension::kCubeArray, "texture_cube_array"}));
 
 using WgslGenerator_MultiampledTextureTest = TestParamHelper<TextureData>;
 TEST_P(WgslGenerator_MultiampledTextureTest, EmitType_MultisampledTexture_F32) {
@@ -448,13 +449,13 @@
 }
 INSTANTIATE_TEST_SUITE_P(WgslGeneratorImplTest,
                          WgslGenerator_MultiampledTextureTest,
-                         testing::Values(TextureData{ast::TextureDimension::k2d,
+                         testing::Values(TextureData{type::TextureDimension::k2d,
                                                      "texture_multisampled_2d"}));
 
 struct StorageTextureData {
-    ast::TexelFormat fmt;
-    ast::TextureDimension dim;
-    ast::Access access;
+    type::TexelFormat fmt;
+    type::TextureDimension dim;
+    type::Access access;
     const char* name;
 };
 inline std::ostream& operator<<(std::ostream& out, StorageTextureData data) {
@@ -477,19 +478,18 @@
 INSTANTIATE_TEST_SUITE_P(
     WgslGeneratorImplTest,
     WgslGenerator_StorageTextureTest,
-    testing::Values(StorageTextureData{ast::TexelFormat::kRgba8Sint, ast::TextureDimension::k1d,
-                                       ast::Access::kWrite, "texture_storage_1d<rgba8sint, write>"},
-                    StorageTextureData{ast::TexelFormat::kRgba8Sint, ast::TextureDimension::k2d,
-                                       ast::Access::kWrite, "texture_storage_2d<rgba8sint, write>"},
-                    StorageTextureData{ast::TexelFormat::kRgba8Sint,
-                                       ast::TextureDimension::k2dArray, ast::Access::kWrite,
-                                       "texture_storage_2d_array<rgba8sint, write>"},
-                    StorageTextureData{ast::TexelFormat::kRgba8Sint, ast::TextureDimension::k3d,
-                                       ast::Access::kWrite,
-                                       "texture_storage_3d<rgba8sint, write>"}));
+    testing::Values(
+        StorageTextureData{type::TexelFormat::kRgba8Sint, type::TextureDimension::k1d,
+                           type::Access::kWrite, "texture_storage_1d<rgba8sint, write>"},
+        StorageTextureData{type::TexelFormat::kRgba8Sint, type::TextureDimension::k2d,
+                           type::Access::kWrite, "texture_storage_2d<rgba8sint, write>"},
+        StorageTextureData{type::TexelFormat::kRgba8Sint, type::TextureDimension::k2dArray,
+                           type::Access::kWrite, "texture_storage_2d_array<rgba8sint, write>"},
+        StorageTextureData{type::TexelFormat::kRgba8Sint, type::TextureDimension::k3d,
+                           type::Access::kWrite, "texture_storage_3d<rgba8sint, write>"}));
 
 struct ImageFormatData {
-    ast::TexelFormat fmt;
+    type::TexelFormat fmt;
     const char* name;
 };
 inline std::ostream& operator<<(std::ostream& out, ImageFormatData data) {
@@ -510,22 +510,22 @@
 INSTANTIATE_TEST_SUITE_P(
     WgslGeneratorImplTest,
     WgslGenerator_ImageFormatTest,
-    testing::Values(ImageFormatData{ast::TexelFormat::kR32Uint, "r32uint"},
-                    ImageFormatData{ast::TexelFormat::kR32Sint, "r32sint"},
-                    ImageFormatData{ast::TexelFormat::kR32Float, "r32float"},
-                    ImageFormatData{ast::TexelFormat::kRgba8Unorm, "rgba8unorm"},
-                    ImageFormatData{ast::TexelFormat::kRgba8Snorm, "rgba8snorm"},
-                    ImageFormatData{ast::TexelFormat::kRgba8Uint, "rgba8uint"},
-                    ImageFormatData{ast::TexelFormat::kRgba8Sint, "rgba8sint"},
-                    ImageFormatData{ast::TexelFormat::kRg32Uint, "rg32uint"},
-                    ImageFormatData{ast::TexelFormat::kRg32Sint, "rg32sint"},
-                    ImageFormatData{ast::TexelFormat::kRg32Float, "rg32float"},
-                    ImageFormatData{ast::TexelFormat::kRgba16Uint, "rgba16uint"},
-                    ImageFormatData{ast::TexelFormat::kRgba16Sint, "rgba16sint"},
-                    ImageFormatData{ast::TexelFormat::kRgba16Float, "rgba16float"},
-                    ImageFormatData{ast::TexelFormat::kRgba32Uint, "rgba32uint"},
-                    ImageFormatData{ast::TexelFormat::kRgba32Sint, "rgba32sint"},
-                    ImageFormatData{ast::TexelFormat::kRgba32Float, "rgba32float"}));
+    testing::Values(ImageFormatData{type::TexelFormat::kR32Uint, "r32uint"},
+                    ImageFormatData{type::TexelFormat::kR32Sint, "r32sint"},
+                    ImageFormatData{type::TexelFormat::kR32Float, "r32float"},
+                    ImageFormatData{type::TexelFormat::kRgba8Unorm, "rgba8unorm"},
+                    ImageFormatData{type::TexelFormat::kRgba8Snorm, "rgba8snorm"},
+                    ImageFormatData{type::TexelFormat::kRgba8Uint, "rgba8uint"},
+                    ImageFormatData{type::TexelFormat::kRgba8Sint, "rgba8sint"},
+                    ImageFormatData{type::TexelFormat::kRg32Uint, "rg32uint"},
+                    ImageFormatData{type::TexelFormat::kRg32Sint, "rg32sint"},
+                    ImageFormatData{type::TexelFormat::kRg32Float, "rg32float"},
+                    ImageFormatData{type::TexelFormat::kRgba16Uint, "rgba16uint"},
+                    ImageFormatData{type::TexelFormat::kRgba16Sint, "rgba16sint"},
+                    ImageFormatData{type::TexelFormat::kRgba16Float, "rgba16float"},
+                    ImageFormatData{type::TexelFormat::kRgba32Uint, "rgba32uint"},
+                    ImageFormatData{type::TexelFormat::kRgba32Sint, "rgba32sint"},
+                    ImageFormatData{type::TexelFormat::kRgba32Float, "rgba32float"}));
 
 TEST_F(WgslGeneratorImplTest, EmitType_Sampler) {
     auto* sampler = ty.sampler(ast::SamplerKind::kSampler);
diff --git a/src/tint/writer/wgsl/generator_impl_unary_op_test.cc b/src/tint/writer/wgsl/generator_impl_unary_op_test.cc
index 0d5edd5..544e1e3 100644
--- a/src/tint/writer/wgsl/generator_impl_unary_op_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_unary_op_test.cc
@@ -20,7 +20,7 @@
 using WgslUnaryOpTest = TestHelper;
 
 TEST_F(WgslUnaryOpTest, AddressOf) {
-    GlobalVar("expr", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("expr", ty.f32(), type::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kAddressOf, Expr("expr"));
     WrapInFunction(op);
 
@@ -32,7 +32,7 @@
 }
 
 TEST_F(WgslUnaryOpTest, Complement) {
-    GlobalVar("expr", ty.u32(), ast::AddressSpace::kPrivate);
+    GlobalVar("expr", ty.u32(), type::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kComplement, Expr("expr"));
     WrapInFunction(op);
 
@@ -44,7 +44,7 @@
 }
 
 TEST_F(WgslUnaryOpTest, Indirection) {
-    GlobalVar("G", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("G", ty.f32(), type::AddressSpace::kPrivate);
     auto* p = Let("expr", create<ast::UnaryOpExpression>(ast::UnaryOp::kAddressOf, Expr("G")));
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kIndirection, Expr("expr"));
     WrapInFunction(p, op);
@@ -57,7 +57,7 @@
 }
 
 TEST_F(WgslUnaryOpTest, Not) {
-    GlobalVar("expr", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("expr", ty.bool_(), type::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kNot, Expr("expr"));
     WrapInFunction(op);
 
@@ -69,7 +69,7 @@
 }
 
 TEST_F(WgslUnaryOpTest, Negation) {
-    GlobalVar("expr", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("expr", ty.i32(), type::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kNegation, Expr("expr"));
     WrapInFunction(op);
 
diff --git a/src/tint/writer/wgsl/generator_impl_variable_test.cc b/src/tint/writer/wgsl/generator_impl_variable_test.cc
index fd6110a..e215d29 100644
--- a/src/tint/writer/wgsl/generator_impl_variable_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_variable_test.cc
@@ -22,7 +22,7 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, EmitVariable) {
-    auto* v = GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
+    auto* v = GlobalVar("a", ty.f32(), type::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
@@ -32,7 +32,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitVariable_AddressSpace) {
-    auto* v = GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
+    auto* v = GlobalVar("a", ty.f32(), type::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
@@ -43,7 +43,7 @@
 
 TEST_F(WgslGeneratorImplTest, EmitVariable_Access_Read) {
     auto* s = Structure("S", utils::Vector{Member("a", ty.i32())});
-    auto* v = GlobalVar("a", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead,
+    auto* v = GlobalVar("a", ty.Of(s), type::AddressSpace::kStorage, type::Access::kRead,
                         Binding(0_a), Group(0_a));
 
     GeneratorImpl& gen = Build();
@@ -55,7 +55,7 @@
 
 TEST_F(WgslGeneratorImplTest, EmitVariable_Access_ReadWrite) {
     auto* s = Structure("S", utils::Vector{Member("a", ty.i32())});
-    auto* v = GlobalVar("a", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite,
+    auto* v = GlobalVar("a", ty.Of(s), type::AddressSpace::kStorage, type::Access::kReadWrite,
                         Binding(0_a), Group(0_a));
 
     GeneratorImpl& gen = Build();
@@ -76,7 +76,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitVariable_Initializer) {
-    auto* v = GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate, Expr(1_f));
+    auto* v = GlobalVar("a", ty.f32(), type::AddressSpace::kPrivate, Expr(1_f));
 
     GeneratorImpl& gen = Build();