Replace TextureType::(Is|As)Storage with Castable

Change-Id: I627304c0b397605f565ae688f2a2b61132c26b9b
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/34278
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/ast/type/depth_texture_type_test.cc b/src/ast/type/depth_texture_type_test.cc
index 2798b93..867c2a1 100644
--- a/src/ast/type/depth_texture_type_test.cc
+++ b/src/ast/type/depth_texture_type_test.cc
@@ -23,6 +23,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/storage_texture_type.h"
 #include "src/ast/type/struct_type.h"
 #include "src/ast/type/u32_type.h"
 #include "src/ast/type/vector_type.h"
@@ -54,9 +55,10 @@
 
 TEST_F(DepthTextureTypeTest, IsTextureType) {
   DepthTextureType d(TextureDimension::kCube);
-  EXPECT_TRUE(d.Is<DepthTextureType>());
-  EXPECT_FALSE(d.IsSampled());
-  EXPECT_FALSE(d.IsStorage());
+  TextureType*ty = &d;
+  EXPECT_TRUE(ty->Is<DepthTextureType>());
+  EXPECT_FALSE(ty->IsSampled());
+  EXPECT_FALSE(ty->Is<StorageTextureType>());
 }
 
 TEST_F(DepthTextureTypeTest, Dim) {
diff --git a/src/ast/type/multisampled_texture_type_test.cc b/src/ast/type/multisampled_texture_type_test.cc
index 10cf1d2..1d987e6 100644
--- a/src/ast/type/multisampled_texture_type_test.cc
+++ b/src/ast/type/multisampled_texture_type_test.cc
@@ -23,6 +23,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/storage_texture_type.h"
 #include "src/ast/type/struct_type.h"
 #include "src/ast/type/u32_type.h"
 #include "src/ast/type/vector_type.h"
@@ -60,7 +61,7 @@
   EXPECT_FALSE(ty->Is<DepthTextureType>());
   EXPECT_TRUE(ty->Is<MultisampledTextureType>());
   EXPECT_FALSE(ty->IsSampled());
-  EXPECT_FALSE(ty->IsStorage());
+  EXPECT_FALSE(ty->Is<StorageTextureType>());
 }
 
 TEST_F(MultisampledTextureTypeTest, Dim) {
diff --git a/src/ast/type/sampled_texture_type_test.cc b/src/ast/type/sampled_texture_type_test.cc
index a37b8b7..ed6344f 100644
--- a/src/ast/type/sampled_texture_type_test.cc
+++ b/src/ast/type/sampled_texture_type_test.cc
@@ -23,6 +23,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/storage_texture_type.h"
 #include "src/ast/type/struct_type.h"
 #include "src/ast/type/u32_type.h"
 #include "src/ast/type/vector_type.h"
@@ -59,7 +60,7 @@
   TextureType* ty = &s;
   EXPECT_FALSE(ty->Is<DepthTextureType>());
   EXPECT_TRUE(ty->IsSampled());
-  EXPECT_FALSE(ty->IsStorage());
+  EXPECT_FALSE(ty->Is<StorageTextureType>());
 }
 
 TEST_F(SampledTextureTypeTest, Dim) {
diff --git a/src/ast/type/storage_texture_type.cc b/src/ast/type/storage_texture_type.cc
index d544963..963e491 100644
--- a/src/ast/type/storage_texture_type.cc
+++ b/src/ast/type/storage_texture_type.cc
@@ -169,10 +169,6 @@
 
 StorageTextureType::~StorageTextureType() = default;
 
-bool StorageTextureType::IsStorage() const {
-  return true;
-}
-
 std::string StorageTextureType::type_name() const {
   std::ostringstream out;
   out << "__storage_texture_" << access_ << "_" << dim() << "_"
diff --git a/src/ast/type/storage_texture_type.h b/src/ast/type/storage_texture_type.h
index 8157b07..84d6e6e 100644
--- a/src/ast/type/storage_texture_type.h
+++ b/src/ast/type/storage_texture_type.h
@@ -80,9 +80,6 @@
   StorageTextureType(StorageTextureType&&);
   ~StorageTextureType() override;
 
-  /// @returns true if the type is a storage texture type
-  bool IsStorage() const override;
-
   /// @param type the subtype of the storage texture
   void set_type(Type* const type);
 
diff --git a/src/ast/type/storage_texture_type_test.cc b/src/ast/type/storage_texture_type_test.cc
index cc548c9..9062d7d 100644
--- a/src/ast/type/storage_texture_type_test.cc
+++ b/src/ast/type/storage_texture_type_test.cc
@@ -63,7 +63,7 @@
   TextureType* ty = &s;
   EXPECT_FALSE(ty->Is<DepthTextureType>());
   EXPECT_FALSE(ty->IsSampled());
-  EXPECT_TRUE(ty->IsStorage());
+  EXPECT_TRUE(ty->Is<StorageTextureType>());
 }
 
 TEST_F(StorageTextureTypeTest, Dim) {
@@ -93,44 +93,45 @@
 TEST_F(StorageTextureTypeTest, F32Type) {
   Context ctx;
   ast::Module mod;
-  ast::type::Type* s = mod.create<StorageTextureType>(
-      TextureDimension::k2dArray, AccessControl::kReadOnly,
-      ImageFormat::kRgba32Float);
+  Type* s = mod.create<StorageTextureType>(TextureDimension::k2dArray,
+                                           AccessControl::kReadOnly,
+                                           ImageFormat::kRgba32Float);
   TypeDeterminer td(&ctx, &mod);
 
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(s->Is<TextureType>());
-  ASSERT_TRUE(s->As<TextureType>()->IsStorage());
-  EXPECT_TRUE(s->As<TextureType>()->AsStorage()->type()->Is<F32Type>());
+  ASSERT_TRUE(s->Is<StorageTextureType>());
+  EXPECT_TRUE(
+      s->As<TextureType>()->As<StorageTextureType>()->type()->Is<F32Type>());
 }
 
 TEST_F(StorageTextureTypeTest, U32Type) {
   Context ctx;
   ast::Module mod;
-  ast::type::Type* s = mod.create<StorageTextureType>(
-      TextureDimension::k2dArray, AccessControl::kReadOnly,
-      ImageFormat::kRg32Uint);
+  Type* s = mod.create<StorageTextureType>(TextureDimension::k2dArray,
+                                           AccessControl::kReadOnly,
+                                           ImageFormat::kRg32Uint);
   TypeDeterminer td(&ctx, &mod);
 
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(s->Is<TextureType>());
-  ASSERT_TRUE(s->As<TextureType>()->IsStorage());
-  EXPECT_TRUE(
-      s->As<TextureType>()->AsStorage()->type()->Is<ast::type::U32Type>());
+  ASSERT_TRUE(s->Is<StorageTextureType>());
+  EXPECT_TRUE(s->As<StorageTextureType>()->type()->Is<U32Type>());
 }
 
 TEST_F(StorageTextureTypeTest, I32Type) {
   Context ctx;
   ast::Module mod;
-  ast::type::Type* s = mod.create<StorageTextureType>(
-      TextureDimension::k2dArray, AccessControl::kReadOnly,
-      ImageFormat::kRgba32Sint);
+  Type* s = mod.create<StorageTextureType>(TextureDimension::k2dArray,
+                                           AccessControl::kReadOnly,
+                                           ImageFormat::kRgba32Sint);
   TypeDeterminer td(&ctx, &mod);
 
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(s->Is<TextureType>());
-  ASSERT_TRUE(s->As<TextureType>()->IsStorage());
-  EXPECT_TRUE(s->As<TextureType>()->AsStorage()->type()->Is<I32Type>());
+  ASSERT_TRUE(s->Is<StorageTextureType>());
+  EXPECT_TRUE(
+      s->As<TextureType>()->As<StorageTextureType>()->type()->Is<I32Type>());
 }
 
 TEST_F(StorageTextureTypeTest, MinBufferBindingSize) {
diff --git a/src/ast/type/texture_type.cc b/src/ast/type/texture_type.cc
index 18ea61a..14c698e 100644
--- a/src/ast/type/texture_type.cc
+++ b/src/ast/type/texture_type.cc
@@ -18,7 +18,6 @@
 
 #include "src/ast/type/multisampled_texture_type.h"
 #include "src/ast/type/sampled_texture_type.h"
-#include "src/ast/type/storage_texture_type.h"
 
 namespace tint {
 namespace ast {
@@ -60,9 +59,6 @@
 
 TextureType::~TextureType() = default;
 
-bool TextureType::IsStorage() const {
-  return false;
-}
 bool TextureType::IsSampled() const {
   return false;
 }
@@ -72,21 +68,11 @@
   return static_cast<const SampledTextureType*>(this);
 }
 
-const StorageTextureType* TextureType::AsStorage() const {
-  assert(IsStorage());
-  return static_cast<const StorageTextureType*>(this);
-}
-
 SampledTextureType* TextureType::AsSampled() {
   assert(IsSampled());
   return static_cast<SampledTextureType*>(this);
 }
 
-StorageTextureType* TextureType::AsStorage() {
-  assert(IsStorage());
-  return static_cast<StorageTextureType*>(this);
-}
-
 }  // namespace type
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/type/texture_type.h b/src/ast/type/texture_type.h
index a2139b8..f3047df 100644
--- a/src/ast/type/texture_type.h
+++ b/src/ast/type/texture_type.h
@@ -25,7 +25,6 @@
 namespace type {
 
 class SampledTextureType;
-class StorageTextureType;
 
 /// The dimensionality of the texture
 enum class TextureDimension {
@@ -61,20 +60,14 @@
   /// @returns the texture dimension
   TextureDimension dim() const { return dim_; }
 
-  /// @returns true if this is a storage texture
-  virtual bool IsStorage() const;
   /// @returns true if this is a sampled texture
   virtual bool IsSampled() const;
 
   /// @returns the texture as a sampled texture
   const SampledTextureType* AsSampled() const;
-  /// @returns the texture as a storage texture
-  const StorageTextureType* AsStorage() const;
 
   /// @returns the texture as a sampled texture
   SampledTextureType* AsSampled();
-  /// @returns the texture as a storage texture
-  StorageTextureType* AsStorage();
 
  private:
   TextureDimension dim_ = TextureDimension::k1d;
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 13aab4f..4dcb422 100644
--- a/src/reader/wgsl/parser_impl_texture_sampler_types_test.cc
+++ b/src/reader/wgsl/parser_impl_texture_sampler_types_test.cc
@@ -320,10 +320,10 @@
   EXPECT_FALSE(t.errored);
   ASSERT_NE(t.value, nullptr);
   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(),
+  ASSERT_TRUE(t->Is<ast::type::StorageTextureType>());
+  EXPECT_EQ(t->As<ast::type::StorageTextureType>()->image_format(),
             ast::type::ImageFormat::kR8Unorm);
-  EXPECT_EQ(t->As<ast::type::TextureType>()->AsStorage()->access(),
+  EXPECT_EQ(t->As<ast::type::StorageTextureType>()->access(),
             ast::AccessControl::kReadOnly);
   EXPECT_EQ(t->As<ast::type::TextureType>()->dim(),
             ast::type::TextureDimension::k1d);
@@ -338,10 +338,10 @@
   EXPECT_FALSE(t.errored);
   ASSERT_NE(t.value, nullptr);
   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(),
+  ASSERT_TRUE(t->Is<ast::type::StorageTextureType>());
+  EXPECT_EQ(t->As<ast::type::StorageTextureType>()->image_format(),
             ast::type::ImageFormat::kR16Float);
-  EXPECT_EQ(t->As<ast::type::TextureType>()->AsStorage()->access(),
+  EXPECT_EQ(t->As<ast::type::StorageTextureType>()->access(),
             ast::AccessControl::kWriteOnly);
   EXPECT_EQ(t->As<ast::type::TextureType>()->dim(),
             ast::type::TextureDimension::k2d);
@@ -392,10 +392,10 @@
   EXPECT_FALSE(t.errored);
   ASSERT_NE(t.value, nullptr);
   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(),
+  ASSERT_TRUE(t->Is<ast::type::StorageTextureType>());
+  EXPECT_EQ(t->As<ast::type::StorageTextureType>()->image_format(),
             ast::type::ImageFormat::kR8Unorm);
-  EXPECT_EQ(t->As<ast::type::TextureType>()->AsStorage()->access(),
+  EXPECT_EQ(t->As<ast::type::StorageTextureType>()->access(),
             ast::AccessControl::kReadOnly);
   EXPECT_EQ(t->As<ast::type::TextureType>()->dim(),
             ast::type::TextureDimension::k1d);
@@ -409,10 +409,10 @@
   EXPECT_FALSE(t.errored);
   ASSERT_NE(t.value, nullptr);
   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(),
+  ASSERT_TRUE(t->Is<ast::type::StorageTextureType>());
+  EXPECT_EQ(t->As<ast::type::StorageTextureType>()->image_format(),
             ast::type::ImageFormat::kR16Float);
-  EXPECT_EQ(t->As<ast::type::TextureType>()->AsStorage()->access(),
+  EXPECT_EQ(t->As<ast::type::StorageTextureType>()->access(),
             ast::AccessControl::kWriteOnly);
   EXPECT_EQ(t->As<ast::type::TextureType>()->dim(),
             ast::type::TextureDimension::k2d);
diff --git a/src/type_determiner.cc b/src/type_determiner.cc
index 5a423ab..ffe72d0 100644
--- a/src/type_determiner.cc
+++ b/src/type_determiner.cc
@@ -87,11 +87,11 @@
   for (auto& iter : mod_->types()) {
     auto& type = iter.second;
     if (!type->Is<ast::type::TextureType>() ||
-        !type->As<ast::type::TextureType>()->IsStorage()) {
+        !type->Is<ast::type::StorageTextureType>()) {
       continue;
     }
     if (!DetermineStorageTextureSubtype(
-            type->As<ast::type::TextureType>()->AsStorage())) {
+            type->As<ast::type::StorageTextureType>())) {
       set_error(Source{}, "unable to determine storage texture subtype for: " +
                               type->type_name());
       return false;
@@ -671,7 +671,7 @@
       return true;
     }
 
-    if (!texture->IsStorage() &&
+    if (!texture->Is<ast::type::StorageTextureType>() &&
         !(texture->IsSampled() ||
           texture->Is<ast::type::MultisampledTextureType>())) {
       set_error(expr->source(), "invalid texture for " + ident->name());
@@ -679,8 +679,8 @@
     }
 
     ast::type::Type* type = nullptr;
-    if (texture->IsStorage()) {
-      type = texture->AsStorage()->type();
+    if (texture->Is<ast::type::StorageTextureType>()) {
+      type = texture->As<ast::type::StorageTextureType>()->type();
     } else if (texture->IsSampled()) {
       type = texture->AsSampled()->type();
     } else if (texture->Is<ast::type::MultisampledTextureType>()) {
diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc
index 042708f..b9f16d7 100644
--- a/src/writer/hlsl/generator_impl.cc
+++ b/src/writer/hlsl/generator_impl.cc
@@ -47,6 +47,7 @@
 #include "src/ast/type/matrix_type.h"
 #include "src/ast/type/pointer_type.h"
 #include "src/ast/type/sampler_type.h"
+#include "src/ast/type/storage_texture_type.h"
 #include "src/ast/type/struct_type.h"
 #include "src/ast/type/texture_type.h"
 #include "src/ast/type/u32_type.h"
@@ -2099,7 +2100,7 @@
     out << type->As<ast::type::StructType>()->name();
   } else if (type->Is<ast::type::TextureType>()) {
     auto* tex = type->As<ast::type::TextureType>();
-    if (tex->IsStorage()) {
+    if (tex->Is<ast::type::StorageTextureType>()) {
       out << "RW";
     }
     out << "Texture";
diff --git a/src/writer/msl/generator_impl.cc b/src/writer/msl/generator_impl.cc
index 19de1c0..6205aa8 100644
--- a/src/writer/msl/generator_impl.cc
+++ b/src/writer/msl/generator_impl.cc
@@ -1880,8 +1880,8 @@
     out_ << "<";
     if (tex->Is<ast::type::DepthTextureType>()) {
       out_ << "float, access::sample";
-    } else if (tex->IsStorage()) {
-      auto* storage = tex->AsStorage();
+    } else if (tex->Is<ast::type::StorageTextureType>()) {
+      auto* storage = tex->As<ast::type::StorageTextureType>();
       if (!EmitType(storage->type(), "")) {
         return false;
       }
diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc
index 0602006..bff08f4 100644
--- a/src/writer/spirv/builder.cc
+++ b/src/writer/spirv/builder.cc
@@ -718,8 +718,8 @@
     ops.push_back(Operand::Int(init_id));
   } else if (type->Is<ast::type::TextureType>()) {
     // Decorate storage texture variables with NonRead/Writeable if needed.
-    if (type->As<ast::type::TextureType>()->IsStorage()) {
-      switch (type->As<ast::type::TextureType>()->AsStorage()->access()) {
+    if (type->Is<ast::type::StorageTextureType>()) {
+      switch (type->As<ast::type::StorageTextureType>()->access()) {
         case ast::AccessControl::kWriteOnly:
           push_annot(
               spv::Op::OpDecorate,
@@ -1964,8 +1964,9 @@
   spirv_operands.reserve(4);  // Enough to fit most parameter lists
 
   if (ident->intrinsic() == ast::Intrinsic::kTextureLoad) {
-    op = texture_type->IsStorage() ? spv::Op::OpImageRead
-                                   : spv::Op::OpImageFetch;
+    op = texture_type->Is<ast::type::StorageTextureType>()
+             ? spv::Op::OpImageRead
+             : spv::Op::OpImageFetch;
     spirv_params.emplace_back(gen_param(pidx.texture));
     spirv_params.emplace_back(gen_param(pidx.coords));
 
@@ -2503,7 +2504,7 @@
     if (texture->IsSampled()) {
       push_capability(SpvCapabilitySampled1D);
     } else {
-      assert(texture->IsStorage());
+      assert(texture->Is<ast::type::StorageTextureType>());
       push_capability(SpvCapabilityImage1D);
     }
   }
@@ -2546,12 +2547,14 @@
   } else if (texture->Is<ast::type::MultisampledTextureType>()) {
     type_id = GenerateTypeIfNeeded(
         texture->As<ast::type::MultisampledTextureType>()->type());
-  } else if (texture->IsStorage()) {
-    if (texture->AsStorage()->access() == ast::AccessControl::kWriteOnly) {
+  } else if (texture->Is<ast::type::StorageTextureType>()) {
+    if (texture->As<ast::type::StorageTextureType>()->access() ==
+        ast::AccessControl::kWriteOnly) {
       ast::type::VoidType void_type;
       type_id = GenerateTypeIfNeeded(&void_type);
     } else {
-      type_id = GenerateTypeIfNeeded(texture->AsStorage()->type());
+      type_id = GenerateTypeIfNeeded(
+          texture->As<ast::type::StorageTextureType>()->type());
     }
   }
   if (type_id == 0u) {
@@ -2559,9 +2562,9 @@
   }
 
   uint32_t format_literal = SpvImageFormat_::SpvImageFormatUnknown;
-  if (texture->IsStorage()) {
-    format_literal =
-        convert_image_format_to_spv(texture->AsStorage()->image_format());
+  if (texture->Is<ast::type::StorageTextureType>()) {
+    format_literal = convert_image_format_to_spv(
+        texture->As<ast::type::StorageTextureType>()->image_format());
   }
 
   push_type(spv::Op::OpTypeImage,
diff --git a/src/writer/wgsl/generator_impl.cc b/src/writer/wgsl/generator_impl.cc
index 7f0b7d0..f5f6015 100644
--- a/src/writer/wgsl/generator_impl.cc
+++ b/src/writer/wgsl/generator_impl.cc
@@ -476,10 +476,10 @@
       /* nothing to emit */
     } else if (texture->Is<ast::type::MultisampledTextureType>()) {
       out_ << "multisampled_";
-    } else if (texture->IsStorage()) {
+    } else if (texture->Is<ast::type::StorageTextureType>()) {
       out_ << "storage_";
 
-      auto* storage = texture->AsStorage();
+      auto* storage = texture->As<ast::type::StorageTextureType>();
       if (storage->access() == ast::AccessControl::kReadOnly) {
         out_ << "ro_";
       } else if (storage->access() == ast::AccessControl::kWriteOnly) {
@@ -536,8 +536,8 @@
         return false;
       }
       out_ << ">";
-    } else if (texture->IsStorage()) {
-      auto* storage = texture->AsStorage();
+    } else if (texture->Is<ast::type::StorageTextureType>()) {
+      auto* storage = texture->As<ast::type::StorageTextureType>();
 
       out_ << "<";
       if (!EmitImageFormat(storage->image_format())) {