Replace Type::(Is|As)Texture with Castable

Change-Id: I53bbccc3e1e7b88ad8c201997cf7e2e485ad9c81
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/34272
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/ast/function.cc b/src/ast/function.cc
index 2dc9c21..09a554f 100644
--- a/src/ast/function.cc
+++ b/src/ast/function.cc
@@ -310,12 +310,14 @@
 
   for (auto* var : referenced_module_variables()) {
     auto* unwrapped_type = var->type()->UnwrapIfNeeded();
-    if (!var->IsDecorated() || !unwrapped_type->IsTexture()) {
+    if (!var->IsDecorated() || !unwrapped_type->Is<ast::type::TextureType>()) {
       continue;
     }
 
-    if ((multisampled && !unwrapped_type->AsTexture()->IsMultisampled()) ||
-        (!multisampled && !unwrapped_type->AsTexture()->IsSampled())) {
+    if ((multisampled &&
+         !unwrapped_type->As<ast::type::TextureType>()->IsMultisampled()) ||
+        (!multisampled &&
+         !unwrapped_type->As<ast::type::TextureType>()->IsSampled())) {
       continue;
     }
 
diff --git a/src/ast/type/access_control_type_test.cc b/src/ast/type/access_control_type_test.cc
index c7ea3a3..e5fc40a 100644
--- a/src/ast/type/access_control_type_test.cc
+++ b/src/ast/type/access_control_type_test.cc
@@ -30,6 +30,7 @@
 #include "src/ast/type/matrix_type.h"
 #include "src/ast/type/pointer_type.h"
 #include "src/ast/type/struct_type.h"
+#include "src/ast/type/texture_type.h"
 #include "src/ast/type/u32_type.h"
 
 namespace tint {
@@ -61,7 +62,7 @@
   EXPECT_FALSE(ty->Is<PointerType>());
   EXPECT_FALSE(ty->Is<SamplerType>());
   EXPECT_FALSE(ty->Is<StructType>());
-  EXPECT_FALSE(ty->IsTexture());
+  EXPECT_FALSE(ty->Is<TextureType>());
   EXPECT_FALSE(ty->IsU32());
   EXPECT_FALSE(ty->IsVector());
 }
diff --git a/src/ast/type/alias_type_test.cc b/src/ast/type/alias_type_test.cc
index ce2f3c7..df38b69 100644
--- a/src/ast/type/alias_type_test.cc
+++ b/src/ast/type/alias_type_test.cc
@@ -31,6 +31,7 @@
 #include "src/ast/type/matrix_type.h"
 #include "src/ast/type/pointer_type.h"
 #include "src/ast/type/struct_type.h"
+#include "src/ast/type/texture_type.h"
 #include "src/ast/type/u32_type.h"
 
 namespace tint {
@@ -62,7 +63,7 @@
   EXPECT_FALSE(ty->Is<PointerType>());
   EXPECT_FALSE(ty->Is<SamplerType>());
   EXPECT_FALSE(ty->Is<StructType>());
-  EXPECT_FALSE(ty->IsTexture());
+  EXPECT_FALSE(ty->Is<TextureType>());
   EXPECT_FALSE(ty->IsU32());
   EXPECT_FALSE(ty->IsVector());
 }
diff --git a/src/ast/type/array_type_test.cc b/src/ast/type/array_type_test.cc
index 4cd1567..ba1fded 100644
--- a/src/ast/type/array_type_test.cc
+++ b/src/ast/type/array_type_test.cc
@@ -26,6 +26,7 @@
 #include "src/ast/type/matrix_type.h"
 #include "src/ast/type/pointer_type.h"
 #include "src/ast/type/struct_type.h"
+#include "src/ast/type/texture_type.h"
 #include "src/ast/type/u32_type.h"
 
 namespace tint {
@@ -68,7 +69,7 @@
   EXPECT_FALSE(ty->Is<PointerType>());
   EXPECT_FALSE(ty->Is<SamplerType>());
   EXPECT_FALSE(ty->Is<StructType>());
-  EXPECT_FALSE(ty->IsTexture());
+  EXPECT_FALSE(ty->Is<TextureType>());
   EXPECT_FALSE(ty->IsU32());
   EXPECT_FALSE(ty->IsVector());
 }
diff --git a/src/ast/type/bool_type_test.cc b/src/ast/type/bool_type_test.cc
index dc34ebb..e61aa8d 100644
--- a/src/ast/type/bool_type_test.cc
+++ b/src/ast/type/bool_type_test.cc
@@ -22,6 +22,7 @@
 #include "src/ast/type/matrix_type.h"
 #include "src/ast/type/pointer_type.h"
 #include "src/ast/type/struct_type.h"
+#include "src/ast/type/texture_type.h"
 
 namespace tint {
 namespace ast {
@@ -43,7 +44,7 @@
   EXPECT_FALSE(ty->Is<PointerType>());
   EXPECT_FALSE(ty->Is<SamplerType>());
   EXPECT_FALSE(ty->Is<StructType>());
-  EXPECT_FALSE(ty->IsTexture());
+  EXPECT_FALSE(ty->Is<TextureType>());
   EXPECT_FALSE(ty->IsU32());
   EXPECT_FALSE(ty->IsVector());
 }
diff --git a/src/ast/type/depth_texture_type_test.cc b/src/ast/type/depth_texture_type_test.cc
index 7eb0884..5db5e88 100644
--- a/src/ast/type/depth_texture_type_test.cc
+++ b/src/ast/type/depth_texture_type_test.cc
@@ -45,7 +45,7 @@
   EXPECT_FALSE(ty->Is<PointerType>());
   EXPECT_FALSE(ty->Is<SamplerType>());
   EXPECT_FALSE(ty->Is<StructType>());
-  EXPECT_TRUE(ty->IsTexture());
+  EXPECT_TRUE(ty->Is<TextureType>());
   EXPECT_FALSE(ty->IsU32());
   EXPECT_FALSE(ty->IsVector());
 }
diff --git a/src/ast/type/f32_type_test.cc b/src/ast/type/f32_type_test.cc
index f0138c5..058e2f2 100644
--- a/src/ast/type/f32_type_test.cc
+++ b/src/ast/type/f32_type_test.cc
@@ -22,6 +22,7 @@
 #include "src/ast/type/matrix_type.h"
 #include "src/ast/type/pointer_type.h"
 #include "src/ast/type/struct_type.h"
+#include "src/ast/type/texture_type.h"
 
 namespace tint {
 namespace ast {
@@ -43,7 +44,7 @@
   EXPECT_FALSE(ty->Is<PointerType>());
   EXPECT_FALSE(ty->Is<SamplerType>());
   EXPECT_FALSE(ty->Is<StructType>());
-  EXPECT_FALSE(ty->IsTexture());
+  EXPECT_FALSE(ty->Is<TextureType>());
   EXPECT_FALSE(ty->IsU32());
   EXPECT_FALSE(ty->IsVector());
 }
diff --git a/src/ast/type/i32_type_test.cc b/src/ast/type/i32_type_test.cc
index f3b6552..ba980b5 100644
--- a/src/ast/type/i32_type_test.cc
+++ b/src/ast/type/i32_type_test.cc
@@ -22,6 +22,7 @@
 #include "src/ast/type/matrix_type.h"
 #include "src/ast/type/pointer_type.h"
 #include "src/ast/type/struct_type.h"
+#include "src/ast/type/texture_type.h"
 
 namespace tint {
 namespace ast {
@@ -43,7 +44,7 @@
   EXPECT_FALSE(ty->Is<PointerType>());
   EXPECT_FALSE(ty->Is<SamplerType>());
   EXPECT_FALSE(ty->Is<StructType>());
-  EXPECT_FALSE(ty->IsTexture());
+  EXPECT_FALSE(ty->Is<TextureType>());
   EXPECT_FALSE(ty->IsU32());
   EXPECT_FALSE(ty->IsVector());
 }
diff --git a/src/ast/type/matrix_type_test.cc b/src/ast/type/matrix_type_test.cc
index 633ec29..9557e7e 100644
--- a/src/ast/type/matrix_type_test.cc
+++ b/src/ast/type/matrix_type_test.cc
@@ -22,6 +22,7 @@
 #include "src/ast/type/i32_type.h"
 #include "src/ast/type/pointer_type.h"
 #include "src/ast/type/struct_type.h"
+#include "src/ast/type/texture_type.h"
 
 namespace tint {
 namespace ast {
@@ -52,7 +53,7 @@
   EXPECT_FALSE(ty->Is<PointerType>());
   EXPECT_FALSE(ty->Is<SamplerType>());
   EXPECT_FALSE(ty->Is<StructType>());
-  EXPECT_FALSE(ty->IsTexture());
+  EXPECT_FALSE(ty->Is<TextureType>());
   EXPECT_FALSE(ty->IsU32());
   EXPECT_FALSE(ty->IsVector());
 }
diff --git a/src/ast/type/multisampled_texture_type_test.cc b/src/ast/type/multisampled_texture_type_test.cc
index d3a410c..9db6845 100644
--- a/src/ast/type/multisampled_texture_type_test.cc
+++ b/src/ast/type/multisampled_texture_type_test.cc
@@ -45,7 +45,7 @@
   EXPECT_FALSE(ty->Is<PointerType>());
   EXPECT_FALSE(ty->Is<SamplerType>());
   EXPECT_FALSE(ty->Is<StructType>());
-  EXPECT_TRUE(ty->IsTexture());
+  EXPECT_TRUE(ty->Is<TextureType>());
   EXPECT_FALSE(ty->IsU32());
   EXPECT_FALSE(ty->IsVector());
 }
diff --git a/src/ast/type/pointer_type_test.cc b/src/ast/type/pointer_type_test.cc
index 3ce8836..0e44002 100644
--- a/src/ast/type/pointer_type_test.cc
+++ b/src/ast/type/pointer_type_test.cc
@@ -22,6 +22,7 @@
 #include "src/ast/type/i32_type.h"
 #include "src/ast/type/matrix_type.h"
 #include "src/ast/type/struct_type.h"
+#include "src/ast/type/texture_type.h"
 
 namespace tint {
 namespace ast {
@@ -51,7 +52,7 @@
   EXPECT_TRUE(ty->Is<PointerType>());
   EXPECT_FALSE(ty->Is<SamplerType>());
   EXPECT_FALSE(ty->Is<StructType>());
-  EXPECT_FALSE(ty->IsTexture());
+  EXPECT_FALSE(ty->Is<TextureType>());
   EXPECT_FALSE(ty->IsU32());
   EXPECT_FALSE(ty->IsVector());
 }
diff --git a/src/ast/type/sampled_texture_type_test.cc b/src/ast/type/sampled_texture_type_test.cc
index 162f701..525eb99 100644
--- a/src/ast/type/sampled_texture_type_test.cc
+++ b/src/ast/type/sampled_texture_type_test.cc
@@ -45,7 +45,7 @@
   EXPECT_FALSE(ty->Is<PointerType>());
   EXPECT_FALSE(ty->Is<SamplerType>());
   EXPECT_FALSE(ty->Is<StructType>());
-  EXPECT_TRUE(ty->IsTexture());
+  EXPECT_TRUE(ty->Is<TextureType>());
   EXPECT_FALSE(ty->IsU32());
   EXPECT_FALSE(ty->IsVector());
 }
diff --git a/src/ast/type/sampler_type_test.cc b/src/ast/type/sampler_type_test.cc
index 7ab51d9..6a4c5f9 100644
--- a/src/ast/type/sampler_type_test.cc
+++ b/src/ast/type/sampler_type_test.cc
@@ -23,6 +23,7 @@
 #include "src/ast/type/matrix_type.h"
 #include "src/ast/type/pointer_type.h"
 #include "src/ast/type/struct_type.h"
+#include "src/ast/type/texture_type.h"
 
 namespace tint {
 namespace ast {
@@ -55,7 +56,7 @@
   EXPECT_FALSE(ty->Is<PointerType>());
   EXPECT_TRUE(ty->Is<SamplerType>());
   EXPECT_FALSE(ty->Is<StructType>());
-  EXPECT_FALSE(ty->IsTexture());
+  EXPECT_FALSE(ty->Is<TextureType>());
   EXPECT_FALSE(ty->IsU32());
   EXPECT_FALSE(ty->IsVector());
 }
diff --git a/src/ast/type/storage_texture_type_test.cc b/src/ast/type/storage_texture_type_test.cc
index c97c8ca..c87c9ae 100644
--- a/src/ast/type/storage_texture_type_test.cc
+++ b/src/ast/type/storage_texture_type_test.cc
@@ -49,7 +49,7 @@
   EXPECT_FALSE(ty->Is<PointerType>());
   EXPECT_FALSE(ty->Is<SamplerType>());
   EXPECT_FALSE(ty->Is<StructType>());
-  EXPECT_TRUE(ty->IsTexture());
+  EXPECT_TRUE(ty->Is<TextureType>());
   EXPECT_FALSE(ty->IsU32());
   EXPECT_FALSE(ty->IsVector());
 }
@@ -95,9 +95,9 @@
   TypeDeterminer td(&ctx, &mod);
 
   ASSERT_TRUE(td.Determine()) << td.error();
-  ASSERT_TRUE(s->IsTexture());
-  ASSERT_TRUE(s->AsTexture()->IsStorage());
-  EXPECT_TRUE(s->AsTexture()->AsStorage()->type()->Is<F32Type>());
+  ASSERT_TRUE(s->Is<TextureType>());
+  ASSERT_TRUE(s->As<TextureType>()->IsStorage());
+  EXPECT_TRUE(s->As<TextureType>()->AsStorage()->type()->Is<F32Type>());
 }
 
 TEST_F(StorageTextureTypeTest, U32Type) {
@@ -109,9 +109,9 @@
   TypeDeterminer td(&ctx, &mod);
 
   ASSERT_TRUE(td.Determine()) << td.error();
-  ASSERT_TRUE(s->IsTexture());
-  ASSERT_TRUE(s->AsTexture()->IsStorage());
-  EXPECT_TRUE(s->AsTexture()->AsStorage()->type()->IsU32());
+  ASSERT_TRUE(s->Is<TextureType>());
+  ASSERT_TRUE(s->As<TextureType>()->IsStorage());
+  EXPECT_TRUE(s->As<TextureType>()->AsStorage()->type()->IsU32());
 }
 
 TEST_F(StorageTextureTypeTest, I32Type) {
@@ -123,9 +123,9 @@
   TypeDeterminer td(&ctx, &mod);
 
   ASSERT_TRUE(td.Determine()) << td.error();
-  ASSERT_TRUE(s->IsTexture());
-  ASSERT_TRUE(s->AsTexture()->IsStorage());
-  EXPECT_TRUE(s->AsTexture()->AsStorage()->type()->Is<I32Type>());
+  ASSERT_TRUE(s->Is<TextureType>());
+  ASSERT_TRUE(s->As<TextureType>()->IsStorage());
+  EXPECT_TRUE(s->As<TextureType>()->AsStorage()->type()->Is<I32Type>());
 }
 
 TEST_F(StorageTextureTypeTest, MinBufferBindingSize) {
diff --git a/src/ast/type/struct_type_test.cc b/src/ast/type/struct_type_test.cc
index 84e5447..244bedd 100644
--- a/src/ast/type/struct_type_test.cc
+++ b/src/ast/type/struct_type_test.cc
@@ -28,6 +28,7 @@
 #include "src/ast/type/i32_type.h"
 #include "src/ast/type/matrix_type.h"
 #include "src/ast/type/pointer_type.h"
+#include "src/ast/type/texture_type.h"
 #include "src/ast/type/u32_type.h"
 #include "src/ast/type/vector_type.h"
 
@@ -59,7 +60,7 @@
   EXPECT_FALSE(ty->Is<PointerType>());
   EXPECT_FALSE(ty->Is<SamplerType>());
   EXPECT_TRUE(ty->Is<StructType>());
-  EXPECT_FALSE(ty->IsTexture());
+  EXPECT_FALSE(ty->Is<TextureType>());
   EXPECT_FALSE(ty->IsU32());
   EXPECT_FALSE(ty->IsVector());
 }
diff --git a/src/ast/type/texture_type.cc b/src/ast/type/texture_type.cc
index ab4e54f..c6ff7f1 100644
--- a/src/ast/type/texture_type.cc
+++ b/src/ast/type/texture_type.cc
@@ -61,10 +61,6 @@
 
 TextureType::~TextureType() = default;
 
-bool TextureType::IsTexture() const {
-  return true;
-}
-
 bool TextureType::IsDepth() const {
   return false;
 }
diff --git a/src/ast/type/texture_type.h b/src/ast/type/texture_type.h
index 249c85c..4cb9b23 100644
--- a/src/ast/type/texture_type.h
+++ b/src/ast/type/texture_type.h
@@ -60,9 +60,6 @@
   TextureType(TextureType&&);
   ~TextureType() override;
 
-  /// @returns true if the type is a texture type
-  bool IsTexture() const override;
-
   /// @returns the texture dimension
   TextureDimension dim() const { return dim_; }
 
diff --git a/src/ast/type/type.cc b/src/ast/type/type.cc
index 0ac063f..a2e6267 100644
--- a/src/ast/type/type.cc
+++ b/src/ast/type/type.cc
@@ -66,10 +66,6 @@
   return UnwrapIfNeeded()->UnwrapPtrIfNeeded()->UnwrapIfNeeded();
 }
 
-bool Type::IsTexture() const {
-  return false;
-}
-
 bool Type::IsU32() const {
   return false;
 }
@@ -134,11 +130,6 @@
   return is_unsigned_scalar_or_vector() || is_signed_scalar_or_vector();
 }
 
-const TextureType* Type::AsTexture() const {
-  assert(IsTexture());
-  return static_cast<const TextureType*>(this);
-}
-
 const U32Type* Type::AsU32() const {
   assert(IsU32());
   return static_cast<const U32Type*>(this);
@@ -154,11 +145,6 @@
   return static_cast<const VoidType*>(this);
 }
 
-TextureType* Type::AsTexture() {
-  assert(IsTexture());
-  return static_cast<TextureType*>(this);
-}
-
 U32Type* Type::AsU32() {
   assert(IsU32());
   return static_cast<U32Type*>(this);
diff --git a/src/ast/type/type.h b/src/ast/type/type.h
index 7f88819..4061b76 100644
--- a/src/ast/type/type.h
+++ b/src/ast/type/type.h
@@ -23,7 +23,6 @@
 namespace ast {
 namespace type {
 
-class TextureType;
 class U32Type;
 class VectorType;
 class VoidType;
@@ -38,8 +37,6 @@
   Type(Type&&);
   ~Type() override;
 
-  /// @returns true if the type is a texture type
-  virtual bool IsTexture() const;
   /// @returns true if the type is a u32 type
   virtual bool IsU32() const;
   /// @returns true if the type is a vec type
@@ -101,8 +98,6 @@
   /// @returns true if this type is an integer scalar or vector
   bool is_integer_scalar_or_vector();
 
-  /// @returns the type as a texture type
-  const TextureType* AsTexture() const;
   /// @returns the type as a u32 type
   const U32Type* AsU32() const;
   /// @returns the type as a vector type
@@ -110,8 +105,6 @@
   /// @returns the type as a void type
   const VoidType* AsVoid() const;
 
-  /// @returns the type as a texture type
-  TextureType* AsTexture();
   /// @returns the type as a u32 type
   U32Type* AsU32();
   /// @returns the type as a vector type
diff --git a/src/ast/type/u32_type_test.cc b/src/ast/type/u32_type_test.cc
index d8e756f..dd7096d 100644
--- a/src/ast/type/u32_type_test.cc
+++ b/src/ast/type/u32_type_test.cc
@@ -24,6 +24,7 @@
 #include "src/ast/type/pointer_type.h"
 #include "src/ast/type/sampler_type.h"
 #include "src/ast/type/struct_type.h"
+#include "src/ast/type/texture_type.h"
 
 namespace tint {
 namespace ast {
@@ -45,7 +46,7 @@
   EXPECT_FALSE(ty->Is<PointerType>());
   EXPECT_FALSE(ty->Is<SamplerType>());
   EXPECT_FALSE(ty->Is<StructType>());
-  EXPECT_FALSE(ty->IsTexture());
+  EXPECT_FALSE(ty->Is<TextureType>());
   EXPECT_TRUE(ty->IsU32());
   EXPECT_FALSE(ty->IsVector());
 }
diff --git a/src/ast/type/vector_type_test.cc b/src/ast/type/vector_type_test.cc
index 6a67e9a..a6d2d2b 100644
--- a/src/ast/type/vector_type_test.cc
+++ b/src/ast/type/vector_type_test.cc
@@ -23,6 +23,7 @@
 #include "src/ast/type/matrix_type.h"
 #include "src/ast/type/pointer_type.h"
 #include "src/ast/type/struct_type.h"
+#include "src/ast/type/texture_type.h"
 
 namespace tint {
 namespace ast {
@@ -52,7 +53,7 @@
   EXPECT_FALSE(ty->Is<PointerType>());
   EXPECT_FALSE(ty->Is<SamplerType>());
   EXPECT_FALSE(ty->Is<StructType>());
-  EXPECT_FALSE(ty->IsTexture());
+  EXPECT_FALSE(ty->Is<TextureType>());
   EXPECT_FALSE(ty->IsU32());
   EXPECT_TRUE(ty->IsVector());
 }
diff --git a/src/inspector/inspector.cc b/src/inspector/inspector.cc
index c16c952..94ba8bb 100644
--- a/src/inspector/inspector.cc
+++ b/src/inspector/inspector.cc
@@ -350,7 +350,8 @@
     entry.bind_group = binding_info.set->value();
     entry.binding = binding_info.binding->value();
 
-    auto* texture_type = var->type()->UnwrapIfNeeded()->AsTexture();
+    auto* texture_type =
+        var->type()->UnwrapIfNeeded()->As<ast::type::TextureType>();
     switch (texture_type->dim()) {
       case ast::type::TextureDimension::k1d:
         entry.dim = ResourceBinding::TextureDimension::k1d;
diff --git a/src/reader/spirv/function.cc b/src/reader/spirv/function.cc
index 5b50531..e008eb7 100644
--- a/src/reader/spirv/function.cc
+++ b/src/reader/spirv/function.cc
@@ -3711,7 +3711,8 @@
     // integer.
     if (ast::type::PointerType* type =
             parser_impl_.GetTypeForHandleVar(*image)) {
-      if (ast::type::TextureType* texture_type = type->type()->AsTexture()) {
+      if (ast::type::TextureType* texture_type =
+              type->type()->As<ast::type::TextureType>()) {
         if (texture_type->IsDepth()) {
           // Convert it to an unsigned integer type.
           lod_operand = ast_module_.create<ast::TypeConstructorExpression>(
@@ -3782,11 +3783,12 @@
     Fail();
     return {};
   }
-  if (!type || !type->type()->IsTexture()) {
+  if (!type || !type->type()->Is<ast::type::TextureType>()) {
     Fail() << "invalid texture type for " << image->PrettyPrint();
     return {};
   }
-  ast::type::TextureDimension dim = type->type()->AsTexture()->dim();
+  ast::type::TextureDimension dim =
+      type->type()->As<ast::type::TextureType>()->dim();
   // Number of regular coordinates.
   uint32_t num_axes = 0;
   bool is_arrayed = false;
diff --git a/src/reader/wgsl/parser_impl_depth_texture_type_test.cc b/src/reader/wgsl/parser_impl_depth_texture_type_test.cc
index c7faf99..78783f9 100644
--- a/src/reader/wgsl/parser_impl_depth_texture_type_test.cc
+++ b/src/reader/wgsl/parser_impl_depth_texture_type_test.cc
@@ -36,9 +36,10 @@
   EXPECT_TRUE(t.matched);
   EXPECT_FALSE(t.errored);
   ASSERT_NE(t.value, nullptr);
-  ASSERT_TRUE(t->IsTexture());
-  ASSERT_TRUE(t->AsTexture()->IsDepth());
-  EXPECT_EQ(t->AsTexture()->dim(), ast::type::TextureDimension::k2d);
+  ASSERT_TRUE(t->Is<ast::type::TextureType>());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()->IsDepth());
+  EXPECT_EQ(t->As<ast::type::TextureType>()->dim(),
+            ast::type::TextureDimension::k2d);
   EXPECT_FALSE(p->has_error());
 }
 
@@ -48,9 +49,10 @@
   EXPECT_TRUE(t.matched);
   EXPECT_FALSE(t.errored);
   ASSERT_NE(t.value, nullptr);
-  ASSERT_TRUE(t->IsTexture());
-  ASSERT_TRUE(t->AsTexture()->IsDepth());
-  EXPECT_EQ(t->AsTexture()->dim(), ast::type::TextureDimension::k2dArray);
+  ASSERT_TRUE(t->Is<ast::type::TextureType>());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()->IsDepth());
+  EXPECT_EQ(t->As<ast::type::TextureType>()->dim(),
+            ast::type::TextureDimension::k2dArray);
   EXPECT_FALSE(p->has_error());
 }
 
@@ -60,9 +62,10 @@
   EXPECT_TRUE(t.matched);
   EXPECT_FALSE(t.errored);
   ASSERT_NE(t.value, nullptr);
-  ASSERT_TRUE(t->IsTexture());
-  ASSERT_TRUE(t->AsTexture()->IsDepth());
-  EXPECT_EQ(t->AsTexture()->dim(), ast::type::TextureDimension::kCube);
+  ASSERT_TRUE(t->Is<ast::type::TextureType>());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()->IsDepth());
+  EXPECT_EQ(t->As<ast::type::TextureType>()->dim(),
+            ast::type::TextureDimension::kCube);
   EXPECT_FALSE(p->has_error());
 }
 
@@ -72,9 +75,10 @@
   EXPECT_TRUE(t.matched);
   EXPECT_FALSE(t.errored);
   ASSERT_NE(t.value, nullptr);
-  ASSERT_TRUE(t->IsTexture());
-  ASSERT_TRUE(t->AsTexture()->IsDepth());
-  EXPECT_EQ(t->AsTexture()->dim(), ast::type::TextureDimension::kCubeArray);
+  ASSERT_TRUE(t->Is<ast::type::TextureType>());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()->IsDepth());
+  EXPECT_EQ(t->As<ast::type::TextureType>()->dim(),
+            ast::type::TextureDimension::kCubeArray);
   EXPECT_FALSE(p->has_error());
 }
 
diff --git a/src/reader/wgsl/parser_impl_texture_sampler_types_test.cc b/src/reader/wgsl/parser_impl_texture_sampler_types_test.cc
index 463533d..baa7d62 100644
--- a/src/reader/wgsl/parser_impl_texture_sampler_types_test.cc
+++ b/src/reader/wgsl/parser_impl_texture_sampler_types_test.cc
@@ -64,9 +64,10 @@
   EXPECT_TRUE(t.matched);
   EXPECT_FALSE(t.errored);
   ASSERT_NE(t.value, nullptr);
-  ASSERT_TRUE(t->IsTexture());
-  ASSERT_TRUE(t->AsTexture()->IsDepth());
-  EXPECT_EQ(t->AsTexture()->dim(), ast::type::TextureDimension::k2d);
+  ASSERT_TRUE(t->Is<ast::type::TextureType>());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()->IsDepth());
+  EXPECT_EQ(t->As<ast::type::TextureType>()->dim(),
+            ast::type::TextureDimension::k2d);
 }
 
 TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_F32_Old) {
@@ -76,10 +77,14 @@
   EXPECT_TRUE(t.matched);
   EXPECT_FALSE(t.errored);
   ASSERT_NE(t.value, nullptr);
-  ASSERT_TRUE(t->IsTexture());
-  ASSERT_TRUE(t->AsTexture()->IsSampled());
-  ASSERT_TRUE(t->AsTexture()->AsSampled()->type()->Is<ast::type::F32Type>());
-  EXPECT_EQ(t->AsTexture()->dim(), ast::type::TextureDimension::k1d);
+  ASSERT_TRUE(t->Is<ast::type::TextureType>());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()->IsSampled());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()
+                  ->AsSampled()
+                  ->type()
+                  ->Is<ast::type::F32Type>());
+  EXPECT_EQ(t->As<ast::type::TextureType>()->dim(),
+            ast::type::TextureDimension::k1d);
 }
 
 TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_I32_Old) {
@@ -89,10 +94,14 @@
   EXPECT_TRUE(t.matched);
   EXPECT_FALSE(t.errored);
   ASSERT_NE(t.value, nullptr);
-  ASSERT_TRUE(t->IsTexture());
-  ASSERT_TRUE(t->AsTexture()->IsSampled());
-  ASSERT_TRUE(t->AsTexture()->AsSampled()->type()->Is<ast::type::I32Type>());
-  EXPECT_EQ(t->AsTexture()->dim(), ast::type::TextureDimension::k2d);
+  ASSERT_TRUE(t->Is<ast::type::TextureType>());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()->IsSampled());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()
+                  ->AsSampled()
+                  ->type()
+                  ->Is<ast::type::I32Type>());
+  EXPECT_EQ(t->As<ast::type::TextureType>()->dim(),
+            ast::type::TextureDimension::k2d);
 }
 
 TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_U32_Old) {
@@ -102,10 +111,11 @@
   EXPECT_TRUE(t.matched);
   EXPECT_FALSE(t.errored);
   ASSERT_NE(t.value, nullptr);
-  ASSERT_TRUE(t->IsTexture());
-  ASSERT_TRUE(t->AsTexture()->IsSampled());
-  ASSERT_TRUE(t->AsTexture()->AsSampled()->type()->IsU32());
-  EXPECT_EQ(t->AsTexture()->dim(), ast::type::TextureDimension::k3d);
+  ASSERT_TRUE(t->Is<ast::type::TextureType>());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()->IsSampled());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()->AsSampled()->type()->IsU32());
+  EXPECT_EQ(t->As<ast::type::TextureType>()->dim(),
+            ast::type::TextureDimension::k3d);
 }
 
 TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_Invalid_Old) {
@@ -156,10 +166,14 @@
   EXPECT_TRUE(t.matched);
   EXPECT_FALSE(t.errored);
   ASSERT_NE(t.value, nullptr);
-  ASSERT_TRUE(t->IsTexture());
-  ASSERT_TRUE(t->AsTexture()->IsSampled());
-  ASSERT_TRUE(t->AsTexture()->AsSampled()->type()->Is<ast::type::F32Type>());
-  EXPECT_EQ(t->AsTexture()->dim(), ast::type::TextureDimension::k1d);
+  ASSERT_TRUE(t->Is<ast::type::TextureType>());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()->IsSampled());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()
+                  ->AsSampled()
+                  ->type()
+                  ->Is<ast::type::F32Type>());
+  EXPECT_EQ(t->As<ast::type::TextureType>()->dim(),
+            ast::type::TextureDimension::k1d);
 }
 
 TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_I32) {
@@ -169,10 +183,14 @@
   EXPECT_TRUE(t.matched);
   EXPECT_FALSE(t.errored);
   ASSERT_NE(t.value, nullptr);
-  ASSERT_TRUE(t->IsTexture());
-  ASSERT_TRUE(t->AsTexture()->IsSampled());
-  ASSERT_TRUE(t->AsTexture()->AsSampled()->type()->Is<ast::type::I32Type>());
-  EXPECT_EQ(t->AsTexture()->dim(), ast::type::TextureDimension::k2d);
+  ASSERT_TRUE(t->Is<ast::type::TextureType>());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()->IsSampled());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()
+                  ->AsSampled()
+                  ->type()
+                  ->Is<ast::type::I32Type>());
+  EXPECT_EQ(t->As<ast::type::TextureType>()->dim(),
+            ast::type::TextureDimension::k2d);
 }
 
 TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_U32) {
@@ -182,10 +200,11 @@
   EXPECT_TRUE(t.matched);
   EXPECT_FALSE(t.errored);
   ASSERT_NE(t.value, nullptr);
-  ASSERT_TRUE(t->IsTexture());
-  ASSERT_TRUE(t->AsTexture()->IsSampled());
-  ASSERT_TRUE(t->AsTexture()->AsSampled()->type()->IsU32());
-  EXPECT_EQ(t->AsTexture()->dim(), ast::type::TextureDimension::k3d);
+  ASSERT_TRUE(t->Is<ast::type::TextureType>());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()->IsSampled());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()->AsSampled()->type()->IsU32());
+  EXPECT_EQ(t->As<ast::type::TextureType>()->dim(),
+            ast::type::TextureDimension::k3d);
 }
 
 TEST_F(ParserImplTest, TextureSamplerTypes_SampledTexture_Invalid) {
@@ -235,11 +254,14 @@
   EXPECT_TRUE(t.matched);
   EXPECT_FALSE(t.errored);
   ASSERT_NE(t.value, nullptr);
-  ASSERT_TRUE(t->IsTexture());
-  ASSERT_TRUE(t->AsTexture()->IsMultisampled());
-  ASSERT_TRUE(
-      t->AsTexture()->AsMultisampled()->type()->Is<ast::type::I32Type>());
-  EXPECT_EQ(t->AsTexture()->dim(), ast::type::TextureDimension::k2d);
+  ASSERT_TRUE(t->Is<ast::type::TextureType>());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()->IsMultisampled());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()
+                  ->AsMultisampled()
+                  ->type()
+                  ->Is<ast::type::I32Type>());
+  EXPECT_EQ(t->As<ast::type::TextureType>()->dim(),
+            ast::type::TextureDimension::k2d);
 }
 
 TEST_F(ParserImplTest, TextureSamplerTypes_MultisampledTexture_Invalid) {
@@ -290,13 +312,14 @@
   EXPECT_TRUE(t.matched);
   EXPECT_FALSE(t.errored);
   ASSERT_NE(t.value, nullptr);
-  ASSERT_TRUE(t->IsTexture());
-  ASSERT_TRUE(t->AsTexture()->IsStorage());
-  EXPECT_EQ(t->AsTexture()->AsStorage()->image_format(),
+  ASSERT_TRUE(t->Is<ast::type::TextureType>());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()->IsStorage());
+  EXPECT_EQ(t->As<ast::type::TextureType>()->AsStorage()->image_format(),
             ast::type::ImageFormat::kR8Unorm);
-  EXPECT_EQ(t->AsTexture()->AsStorage()->access(),
+  EXPECT_EQ(t->As<ast::type::TextureType>()->AsStorage()->access(),
             ast::AccessControl::kReadOnly);
-  EXPECT_EQ(t->AsTexture()->dim(), ast::type::TextureDimension::k1d);
+  EXPECT_EQ(t->As<ast::type::TextureType>()->dim(),
+            ast::type::TextureDimension::k1d);
 }
 
 TEST_F(ParserImplTest,
@@ -307,13 +330,14 @@
   EXPECT_TRUE(t.matched);
   EXPECT_FALSE(t.errored);
   ASSERT_NE(t.value, nullptr);
-  ASSERT_TRUE(t->IsTexture());
-  ASSERT_TRUE(t->AsTexture()->IsStorage());
-  EXPECT_EQ(t->AsTexture()->AsStorage()->image_format(),
+  ASSERT_TRUE(t->Is<ast::type::TextureType>());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()->IsStorage());
+  EXPECT_EQ(t->As<ast::type::TextureType>()->AsStorage()->image_format(),
             ast::type::ImageFormat::kR16Float);
-  EXPECT_EQ(t->AsTexture()->AsStorage()->access(),
+  EXPECT_EQ(t->As<ast::type::TextureType>()->AsStorage()->access(),
             ast::AccessControl::kWriteOnly);
-  EXPECT_EQ(t->AsTexture()->dim(), ast::type::TextureDimension::k2d);
+  EXPECT_EQ(t->As<ast::type::TextureType>()->dim(),
+            ast::type::TextureDimension::k2d);
 }
 
 TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_InvalidType_Old) {
@@ -360,13 +384,14 @@
   EXPECT_TRUE(t.matched);
   EXPECT_FALSE(t.errored);
   ASSERT_NE(t.value, nullptr);
-  ASSERT_TRUE(t->IsTexture());
-  ASSERT_TRUE(t->AsTexture()->IsStorage());
-  EXPECT_EQ(t->AsTexture()->AsStorage()->image_format(),
+  ASSERT_TRUE(t->Is<ast::type::TextureType>());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()->IsStorage());
+  EXPECT_EQ(t->As<ast::type::TextureType>()->AsStorage()->image_format(),
             ast::type::ImageFormat::kR8Unorm);
-  EXPECT_EQ(t->AsTexture()->AsStorage()->access(),
+  EXPECT_EQ(t->As<ast::type::TextureType>()->AsStorage()->access(),
             ast::AccessControl::kReadOnly);
-  EXPECT_EQ(t->AsTexture()->dim(), ast::type::TextureDimension::k1d);
+  EXPECT_EQ(t->As<ast::type::TextureType>()->dim(),
+            ast::type::TextureDimension::k1d);
 }
 
 TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_Writeonly2dR16Float) {
@@ -376,13 +401,14 @@
   EXPECT_TRUE(t.matched);
   EXPECT_FALSE(t.errored);
   ASSERT_NE(t.value, nullptr);
-  ASSERT_TRUE(t->IsTexture());
-  ASSERT_TRUE(t->AsTexture()->IsStorage());
-  EXPECT_EQ(t->AsTexture()->AsStorage()->image_format(),
+  ASSERT_TRUE(t->Is<ast::type::TextureType>());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()->IsStorage());
+  EXPECT_EQ(t->As<ast::type::TextureType>()->AsStorage()->image_format(),
             ast::type::ImageFormat::kR16Float);
-  EXPECT_EQ(t->AsTexture()->AsStorage()->access(),
+  EXPECT_EQ(t->As<ast::type::TextureType>()->AsStorage()->access(),
             ast::AccessControl::kWriteOnly);
-  EXPECT_EQ(t->AsTexture()->dim(), ast::type::TextureDimension::k2d);
+  EXPECT_EQ(t->As<ast::type::TextureType>()->dim(),
+            ast::type::TextureDimension::k2d);
 }
 
 TEST_F(ParserImplTest, TextureSamplerTypes_StorageTexture_InvalidType) {
diff --git a/src/reader/wgsl/parser_impl_type_decl_test.cc b/src/reader/wgsl/parser_impl_type_decl_test.cc
index 0472dae..cb58617 100644
--- a/src/reader/wgsl/parser_impl_type_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_type_decl_test.cc
@@ -764,9 +764,12 @@
   EXPECT_FALSE(t.errored);
   ASSERT_NE(t.value, nullptr) << p->error();
   EXPECT_EQ(t.value, type);
-  ASSERT_TRUE(t->IsTexture());
-  ASSERT_TRUE(t->AsTexture()->IsSampled());
-  ASSERT_TRUE(t->AsTexture()->AsSampled()->type()->Is<ast::type::F32Type>());
+  ASSERT_TRUE(t->Is<ast::type::TextureType>());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()->IsSampled());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()
+                  ->AsSampled()
+                  ->type()
+                  ->Is<ast::type::F32Type>());
 }
 
 TEST_F(ParserImplTest, TypeDecl_Texture) {
@@ -782,9 +785,12 @@
   EXPECT_FALSE(t.errored);
   ASSERT_NE(t.value, nullptr);
   EXPECT_EQ(t.value, type);
-  ASSERT_TRUE(t->IsTexture());
-  ASSERT_TRUE(t->AsTexture()->IsSampled());
-  ASSERT_TRUE(t->AsTexture()->AsSampled()->type()->Is<ast::type::F32Type>());
+  ASSERT_TRUE(t->Is<ast::type::TextureType>());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()->IsSampled());
+  ASSERT_TRUE(t->As<ast::type::TextureType>()
+                  ->AsSampled()
+                  ->type()
+                  ->Is<ast::type::F32Type>());
 }
 
 }  // namespace
diff --git a/src/type_determiner.cc b/src/type_determiner.cc
index a879a79..8f5ab1d 100644
--- a/src/type_determiner.cc
+++ b/src/type_determiner.cc
@@ -85,10 +85,12 @@
 bool TypeDeterminer::Determine() {
   for (auto& iter : mod_->types()) {
     auto& type = iter.second;
-    if (!type->IsTexture() || !type->AsTexture()->IsStorage()) {
+    if (!type->Is<ast::type::TextureType>() ||
+        !type->As<ast::type::TextureType>()->IsStorage()) {
       continue;
     }
-    if (!DetermineStorageTextureSubtype(type->AsTexture()->AsStorage())) {
+    if (!DetermineStorageTextureSubtype(
+            type->As<ast::type::TextureType>()->AsStorage())) {
       set_error(Source{}, "unable to determine storage texture subtype for: " +
                               type->type_name());
       return false;
@@ -550,12 +552,15 @@
     ast::intrinsic::TextureSignature::Parameters param;
 
     auto* texture_param = expr->params()[0];
-    if (!texture_param->result_type()->UnwrapPtrIfNeeded()->IsTexture()) {
+    if (!texture_param->result_type()
+             ->UnwrapPtrIfNeeded()
+             ->Is<ast::type::TextureType>()) {
       set_error(expr->source(), "invalid first argument for " + ident->name());
       return false;
     }
-    ast::type::TextureType* texture =
-        texture_param->result_type()->UnwrapPtrIfNeeded()->AsTexture();
+    ast::type::TextureType* texture = texture_param->result_type()
+                                          ->UnwrapPtrIfNeeded()
+                                          ->As<ast::type::TextureType>();
 
     bool is_array = false;
     switch (texture->dim()) {
diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc
index 5056a8a..340af43 100644
--- a/src/writer/hlsl/generator_impl.cc
+++ b/src/writer/hlsl/generator_impl.cc
@@ -2089,8 +2089,8 @@
     out << "State";
   } else if (type->Is<ast::type::StructType>()) {
     out << type->As<ast::type::StructType>()->name();
-  } else if (type->IsTexture()) {
-    auto* tex = type->AsTexture();
+  } else if (type->Is<ast::type::TextureType>()) {
+    auto* tex = type->As<ast::type::TextureType>();
     if (tex->IsStorage()) {
       out << "RW";
     }
diff --git a/src/writer/msl/generator_impl.cc b/src/writer/msl/generator_impl.cc
index 46b6855..a021d79 100644
--- a/src/writer/msl/generator_impl.cc
+++ b/src/writer/msl/generator_impl.cc
@@ -712,7 +712,7 @@
     auto dim = params[pidx.texture]
                    ->result_type()
                    ->UnwrapPtrIfNeeded()
-                   ->AsTexture()
+                   ->As<ast::type::TextureType>()
                    ->dim();
     switch (dim) {
       case ast::type::TextureDimension::k2d:
@@ -1838,8 +1838,8 @@
     // The struct type emits as just the name. The declaration would be emitted
     // as part of emitting the constructed types.
     out_ << type->As<ast::type::StructType>()->name();
-  } else if (type->IsTexture()) {
-    auto* tex = type->AsTexture();
+  } else if (type->Is<ast::type::TextureType>()) {
+    auto* tex = type->As<ast::type::TextureType>();
 
     if (tex->IsDepth()) {
       out_ << "depth";
diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc
index 54853a7..cda2161 100644
--- a/src/writer/spirv/builder.cc
+++ b/src/writer/spirv/builder.cc
@@ -716,10 +716,10 @@
                      Operand::Int(ConvertStorageClass(sc))};
   if (var->has_constructor()) {
     ops.push_back(Operand::Int(init_id));
-  } else if (type->IsTexture()) {
+  } else if (type->Is<ast::type::TextureType>()) {
     // Decorate storage texture variables with NonRead/Writeable if needed.
-    if (type->AsTexture()->IsStorage()) {
-      switch (type->AsTexture()->AsStorage()->access()) {
+    if (type->As<ast::type::TextureType>()->IsStorage()) {
+      switch (type->As<ast::type::TextureType>()->AsStorage()->access()) {
         case ast::AccessControl::kWriteOnly:
           push_annot(
               spv::Op::OpDecorate,
@@ -1917,8 +1917,10 @@
                                        ast::CallExpression* call,
                                        spirv::Operand result_type,
                                        spirv::Operand result_id) {
-  auto* texture_type =
-      call->params()[0]->result_type()->UnwrapAll()->AsTexture();
+  auto* texture_type = call->params()[0]
+                           ->result_type()
+                           ->UnwrapAll()
+                           ->As<ast::type::TextureType>();
 
   auto* sig = static_cast<const ast::intrinsic::TextureSignature*>(
       ident->intrinsic_signature());
@@ -2453,8 +2455,8 @@
     }
   } else if (type->IsVoid()) {
     push_type(spv::Op::OpTypeVoid, {result});
-  } else if (type->IsTexture()) {
-    if (!GenerateTextureType(type->AsTexture(), result)) {
+  } else if (type->Is<ast::type::TextureType>()) {
+    if (!GenerateTextureType(type->As<ast::type::TextureType>(), result)) {
       return 0;
     }
   } else if (type->Is<ast::type::SamplerType>()) {
diff --git a/src/writer/wgsl/generator_impl.cc b/src/writer/wgsl/generator_impl.cc
index 402ae87..27d84e7 100644
--- a/src/writer/wgsl/generator_impl.cc
+++ b/src/writer/wgsl/generator_impl.cc
@@ -464,8 +464,8 @@
     // The struct, as a type, is just the name. We should have already emitted
     // the declaration through a call to |EmitStructType| earlier.
     out_ << type->As<ast::type::StructType>()->name();
-  } else if (type->IsTexture()) {
-    auto* texture = type->AsTexture();
+  } else if (type->Is<ast::type::TextureType>()) {
+    auto* texture = type->As<ast::type::TextureType>();
 
     out_ << "texture_";
     if (texture->IsDepth()) {