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

Change-Id: I60ed33bd9a54b14bb9b35f3cd999a2604c2c4450
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/34265
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/ast/type/access_control_type_test.cc b/src/ast/type/access_control_type_test.cc
index 652e3b8..b07d2a2 100644
--- a/src/ast/type/access_control_type_test.cc
+++ b/src/ast/type/access_control_type_test.cc
@@ -24,6 +24,7 @@
 #include "src/ast/struct_member_offset_decoration.h"
 #include "src/ast/test_helper.h"
 #include "src/ast/type/array_type.h"
+#include "src/ast/type/bool_type.h"
 #include "src/ast/type/i32_type.h"
 #include "src/ast/type/pointer_type.h"
 #include "src/ast/type/struct_type.h"
@@ -51,7 +52,7 @@
   EXPECT_TRUE(ty->Is<AccessControlType>());
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
-  EXPECT_FALSE(ty->IsBool());
+  EXPECT_FALSE(ty->Is<BoolType>());
   EXPECT_FALSE(ty->IsF32());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
diff --git a/src/ast/type/alias_type_test.cc b/src/ast/type/alias_type_test.cc
index 67e7473..22b81a7 100644
--- a/src/ast/type/alias_type_test.cc
+++ b/src/ast/type/alias_type_test.cc
@@ -25,6 +25,7 @@
 #include "src/ast/test_helper.h"
 #include "src/ast/type/access_control_type.h"
 #include "src/ast/type/array_type.h"
+#include "src/ast/type/bool_type.h"
 #include "src/ast/type/i32_type.h"
 #include "src/ast/type/pointer_type.h"
 #include "src/ast/type/struct_type.h"
@@ -52,7 +53,7 @@
   EXPECT_FALSE(ty->Is<AccessControlType>());
   EXPECT_TRUE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
-  EXPECT_FALSE(ty->IsBool());
+  EXPECT_FALSE(ty->Is<BoolType>());
   EXPECT_FALSE(ty->IsF32());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
diff --git a/src/ast/type/array_type_test.cc b/src/ast/type/array_type_test.cc
index 84cb3bd..40ec166 100644
--- a/src/ast/type/array_type_test.cc
+++ b/src/ast/type/array_type_test.cc
@@ -20,6 +20,7 @@
 #include "src/ast/stride_decoration.h"
 #include "src/ast/test_helper.h"
 #include "src/ast/type/access_control_type.h"
+#include "src/ast/type/bool_type.h"
 #include "src/ast/type/i32_type.h"
 #include "src/ast/type/u32_type.h"
 
@@ -56,7 +57,7 @@
   EXPECT_FALSE(ty->Is<AccessControlType>());
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_TRUE(ty->Is<ArrayType>());
-  EXPECT_FALSE(ty->IsBool());
+  EXPECT_FALSE(ty->Is<BoolType>());
   EXPECT_FALSE(ty->IsF32());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
diff --git a/src/ast/type/bool_type.cc b/src/ast/type/bool_type.cc
index e8f0af3..7accedf 100644
--- a/src/ast/type/bool_type.cc
+++ b/src/ast/type/bool_type.cc
@@ -24,10 +24,6 @@
 
 BoolType::~BoolType() = default;
 
-bool BoolType::IsBool() const {
-  return true;
-}
-
 std::string BoolType::type_name() const {
   return "__bool";
 }
diff --git a/src/ast/type/bool_type.h b/src/ast/type/bool_type.h
index abd6e73..5e7ccf6 100644
--- a/src/ast/type/bool_type.h
+++ b/src/ast/type/bool_type.h
@@ -32,9 +32,6 @@
   BoolType(BoolType&&);
   ~BoolType() override;
 
-  /// @returns true if the type is a bool type
-  bool IsBool() const override;
-
   /// @returns the name for this type
   std::string type_name() const override;
 };
diff --git a/src/ast/type/bool_type_test.cc b/src/ast/type/bool_type_test.cc
index 2b674b2..6b7c523 100644
--- a/src/ast/type/bool_type_test.cc
+++ b/src/ast/type/bool_type_test.cc
@@ -31,7 +31,7 @@
   EXPECT_FALSE(ty->Is<AccessControlType>());
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
-  EXPECT_TRUE(ty->IsBool());
+  EXPECT_TRUE(ty->Is<BoolType>());
   EXPECT_FALSE(ty->IsF32());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
diff --git a/src/ast/type/depth_texture_type_test.cc b/src/ast/type/depth_texture_type_test.cc
index 0d19918..1f5ea21 100644
--- a/src/ast/type/depth_texture_type_test.cc
+++ b/src/ast/type/depth_texture_type_test.cc
@@ -18,6 +18,7 @@
 
 #include "src/ast/type/access_control_type.h"
 #include "src/ast/type/array_type.h"
+#include "src/ast/type/bool_type.h"
 
 namespace tint {
 namespace ast {
@@ -32,7 +33,7 @@
   EXPECT_FALSE(ty->Is<AccessControlType>());
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
-  EXPECT_FALSE(ty->IsBool());
+  EXPECT_FALSE(ty->Is<BoolType>());
   EXPECT_FALSE(ty->IsF32());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
diff --git a/src/ast/type/f32_type_test.cc b/src/ast/type/f32_type_test.cc
index f48c070..01327c4 100644
--- a/src/ast/type/f32_type_test.cc
+++ b/src/ast/type/f32_type_test.cc
@@ -17,6 +17,7 @@
 #include "src/ast/test_helper.h"
 #include "src/ast/type/access_control_type.h"
 #include "src/ast/type/array_type.h"
+#include "src/ast/type/bool_type.h"
 
 namespace tint {
 namespace ast {
@@ -31,7 +32,7 @@
   EXPECT_FALSE(ty->Is<AccessControlType>());
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
-  EXPECT_FALSE(ty->IsBool());
+  EXPECT_FALSE(ty->Is<BoolType>());
   EXPECT_TRUE(ty->IsF32());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
diff --git a/src/ast/type/i32_type_test.cc b/src/ast/type/i32_type_test.cc
index 7e7b086..3deed3b 100644
--- a/src/ast/type/i32_type_test.cc
+++ b/src/ast/type/i32_type_test.cc
@@ -17,6 +17,7 @@
 #include "src/ast/test_helper.h"
 #include "src/ast/type/access_control_type.h"
 #include "src/ast/type/array_type.h"
+#include "src/ast/type/bool_type.h"
 
 namespace tint {
 namespace ast {
@@ -31,7 +32,7 @@
   EXPECT_FALSE(ty->Is<AccessControlType>());
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
-  EXPECT_FALSE(ty->IsBool());
+  EXPECT_FALSE(ty->Is<BoolType>());
   EXPECT_FALSE(ty->IsF32());
   EXPECT_TRUE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
diff --git a/src/ast/type/matrix_type_test.cc b/src/ast/type/matrix_type_test.cc
index bc2791e..395e4df 100644
--- a/src/ast/type/matrix_type_test.cc
+++ b/src/ast/type/matrix_type_test.cc
@@ -17,6 +17,7 @@
 #include "src/ast/test_helper.h"
 #include "src/ast/type/access_control_type.h"
 #include "src/ast/type/array_type.h"
+#include "src/ast/type/bool_type.h"
 #include "src/ast/type/i32_type.h"
 
 namespace tint {
@@ -41,7 +42,7 @@
   EXPECT_FALSE(ty->Is<AccessControlType>());
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
-  EXPECT_FALSE(ty->IsBool());
+  EXPECT_FALSE(ty->Is<BoolType>());
   EXPECT_FALSE(ty->IsF32());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_TRUE(ty->IsMatrix());
diff --git a/src/ast/type/multisampled_texture_type_test.cc b/src/ast/type/multisampled_texture_type_test.cc
index f11e8ce..75a15aa 100644
--- a/src/ast/type/multisampled_texture_type_test.cc
+++ b/src/ast/type/multisampled_texture_type_test.cc
@@ -17,6 +17,7 @@
 #include "src/ast/test_helper.h"
 #include "src/ast/type/access_control_type.h"
 #include "src/ast/type/array_type.h"
+#include "src/ast/type/bool_type.h"
 #include "src/ast/type/f32_type.h"
 
 namespace tint {
@@ -33,7 +34,7 @@
   EXPECT_FALSE(ty->Is<AccessControlType>());
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
-  EXPECT_FALSE(ty->IsBool());
+  EXPECT_FALSE(ty->Is<BoolType>());
   EXPECT_FALSE(ty->IsF32());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
diff --git a/src/ast/type/pointer_type_test.cc b/src/ast/type/pointer_type_test.cc
index 8aeb8cd..1d93fc2 100644
--- a/src/ast/type/pointer_type_test.cc
+++ b/src/ast/type/pointer_type_test.cc
@@ -17,6 +17,7 @@
 #include "src/ast/test_helper.h"
 #include "src/ast/type/access_control_type.h"
 #include "src/ast/type/array_type.h"
+#include "src/ast/type/bool_type.h"
 #include "src/ast/type/i32_type.h"
 
 namespace tint {
@@ -40,7 +41,7 @@
   EXPECT_FALSE(ty->Is<AccessControlType>());
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
-  EXPECT_FALSE(ty->IsBool());
+  EXPECT_FALSE(ty->Is<BoolType>());
   EXPECT_FALSE(ty->IsF32());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
diff --git a/src/ast/type/sampled_texture_type_test.cc b/src/ast/type/sampled_texture_type_test.cc
index dd08506..bc90dcf 100644
--- a/src/ast/type/sampled_texture_type_test.cc
+++ b/src/ast/type/sampled_texture_type_test.cc
@@ -17,6 +17,7 @@
 #include "src/ast/test_helper.h"
 #include "src/ast/type/access_control_type.h"
 #include "src/ast/type/array_type.h"
+#include "src/ast/type/bool_type.h"
 #include "src/ast/type/f32_type.h"
 
 namespace tint {
@@ -33,7 +34,7 @@
   EXPECT_FALSE(ty->Is<AccessControlType>());
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
-  EXPECT_FALSE(ty->IsBool());
+  EXPECT_FALSE(ty->Is<BoolType>());
   EXPECT_FALSE(ty->IsF32());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
diff --git a/src/ast/type/sampler_type_test.cc b/src/ast/type/sampler_type_test.cc
index db11115..1363f09 100644
--- a/src/ast/type/sampler_type_test.cc
+++ b/src/ast/type/sampler_type_test.cc
@@ -17,6 +17,7 @@
 #include "src/ast/test_helper.h"
 #include "src/ast/type/access_control_type.h"
 #include "src/ast/type/array_type.h"
+#include "src/ast/type/bool_type.h"
 
 namespace tint {
 namespace ast {
@@ -42,7 +43,7 @@
   EXPECT_FALSE(ty->Is<AccessControlType>());
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
-  EXPECT_FALSE(ty->IsBool());
+  EXPECT_FALSE(ty->Is<BoolType>());
   EXPECT_FALSE(ty->IsF32());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
diff --git a/src/ast/type/storage_texture_type_test.cc b/src/ast/type/storage_texture_type_test.cc
index 47afe0d..c35e5d0 100644
--- a/src/ast/type/storage_texture_type_test.cc
+++ b/src/ast/type/storage_texture_type_test.cc
@@ -20,6 +20,7 @@
 #include "src/ast/test_helper.h"
 #include "src/ast/type/access_control_type.h"
 #include "src/ast/type/array_type.h"
+#include "src/ast/type/bool_type.h"
 #include "src/type_determiner.h"
 
 namespace tint {
@@ -36,7 +37,7 @@
   EXPECT_FALSE(ty->Is<AccessControlType>());
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
-  EXPECT_FALSE(ty->IsBool());
+  EXPECT_FALSE(ty->Is<BoolType>());
   EXPECT_FALSE(ty->IsF32());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
diff --git a/src/ast/type/struct_type_test.cc b/src/ast/type/struct_type_test.cc
index 3c1ba83..cee3f5b8 100644
--- a/src/ast/type/struct_type_test.cc
+++ b/src/ast/type/struct_type_test.cc
@@ -23,6 +23,7 @@
 #include "src/ast/test_helper.h"
 #include "src/ast/type/access_control_type.h"
 #include "src/ast/type/array_type.h"
+#include "src/ast/type/bool_type.h"
 #include "src/ast/type/i32_type.h"
 #include "src/ast/type/u32_type.h"
 #include "src/ast/type/vector_type.h"
@@ -48,7 +49,7 @@
   EXPECT_FALSE(ty->Is<AccessControlType>());
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
-  EXPECT_FALSE(ty->IsBool());
+  EXPECT_FALSE(ty->Is<BoolType>());
   EXPECT_FALSE(ty->IsF32());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
diff --git a/src/ast/type/type.cc b/src/ast/type/type.cc
index 45dcc0f..8339977 100644
--- a/src/ast/type/type.cc
+++ b/src/ast/type/type.cc
@@ -66,10 +66,6 @@
   return UnwrapIfNeeded()->UnwrapPtrIfNeeded()->UnwrapIfNeeded();
 }
 
-bool Type::IsBool() const {
-  return false;
-}
-
 bool Type::IsF32() const {
   return false;
 }
@@ -119,7 +115,7 @@
 }
 
 bool Type::is_scalar() {
-  return is_float_scalar() || is_integer_scalar() || IsBool();
+  return is_float_scalar() || is_integer_scalar() || Is<BoolType>();
 }
 
 bool Type::is_float_scalar() {
@@ -162,11 +158,6 @@
   return is_unsigned_scalar_or_vector() || is_signed_scalar_or_vector();
 }
 
-const BoolType* Type::AsBool() const {
-  assert(IsBool());
-  return static_cast<const BoolType*>(this);
-}
-
 const F32Type* Type::AsF32() const {
   assert(IsF32());
   return static_cast<const F32Type*>(this);
@@ -217,11 +208,6 @@
   return static_cast<const VoidType*>(this);
 }
 
-BoolType* Type::AsBool() {
-  assert(IsBool());
-  return static_cast<BoolType*>(this);
-}
-
 F32Type* Type::AsF32() {
   assert(IsF32());
   return static_cast<F32Type*>(this);
diff --git a/src/ast/type/type.h b/src/ast/type/type.h
index 7993f42..907d7a3 100644
--- a/src/ast/type/type.h
+++ b/src/ast/type/type.h
@@ -23,7 +23,6 @@
 namespace ast {
 namespace type {
 
-class BoolType;
 class F32Type;
 class I32Type;
 class MatrixType;
@@ -45,8 +44,6 @@
   Type(Type&&);
   ~Type() override;
 
-  /// @returns true if the type is a bool type
-  virtual bool IsBool() const;
   /// @returns true if the type is an f32 type
   virtual bool IsF32() const;
   /// @returns true if the type is an i32 type
@@ -122,8 +119,6 @@
   /// @returns true if this type is an integer scalar or vector
   bool is_integer_scalar_or_vector();
 
-  /// @returns the type as a bool type
-  const BoolType* AsBool() const;
   /// @returns the type as a f32 type
   const F32Type* AsF32() const;
   /// @returns the type as an i32 type
@@ -145,8 +140,6 @@
   /// @returns the type as a void type
   const VoidType* AsVoid() const;
 
-  /// @returns the type as a bool type
-  BoolType* AsBool();
   /// @returns the type as a f32 type
   F32Type* AsF32();
   /// @returns the type as an i32 type
diff --git a/src/ast/type/u32_type_test.cc b/src/ast/type/u32_type_test.cc
index d764f38..20d92da 100644
--- a/src/ast/type/u32_type_test.cc
+++ b/src/ast/type/u32_type_test.cc
@@ -17,6 +17,7 @@
 #include "src/ast/test_helper.h"
 #include "src/ast/type/access_control_type.h"
 #include "src/ast/type/array_type.h"
+#include "src/ast/type/bool_type.h"
 
 namespace tint {
 namespace ast {
@@ -31,7 +32,7 @@
   EXPECT_FALSE(ty->Is<AccessControlType>());
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
-  EXPECT_FALSE(ty->IsBool());
+  EXPECT_FALSE(ty->Is<BoolType>());
   EXPECT_FALSE(ty->IsF32());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
diff --git a/src/ast/type/vector_type_test.cc b/src/ast/type/vector_type_test.cc
index cbbdd73..a849f5e 100644
--- a/src/ast/type/vector_type_test.cc
+++ b/src/ast/type/vector_type_test.cc
@@ -17,6 +17,7 @@
 #include "src/ast/test_helper.h"
 #include "src/ast/type/access_control_type.h"
 #include "src/ast/type/array_type.h"
+#include "src/ast/type/bool_type.h"
 #include "src/ast/type/i32_type.h"
 
 namespace tint {
@@ -40,7 +41,7 @@
   EXPECT_FALSE(ty->Is<AccessControlType>());
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
-  EXPECT_FALSE(ty->IsBool());
+  EXPECT_FALSE(ty->Is<BoolType>());
   EXPECT_FALSE(ty->IsF32());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
diff --git a/src/reader/spirv/function.cc b/src/reader/spirv/function.cc
index 027cacc..ad29bfc 100644
--- a/src/reader/spirv/function.cc
+++ b/src/reader/spirv/function.cc
@@ -3597,7 +3597,7 @@
   //   a VariablePointers* capability, which is not allowed in by WebGPU.
   auto* op_ty = operand1.type;
   if (op_ty->IsVector() || op_ty->is_float_scalar() ||
-      op_ty->is_integer_scalar() || op_ty->IsBool()) {
+      op_ty->is_integer_scalar() || op_ty->Is<ast::type::BoolType>()) {
     ast::ExpressionList params;
     params.push_back(operand1.expr);
     params.push_back(operand2.expr);
diff --git a/src/reader/spirv/parser_impl.cc b/src/reader/spirv/parser_impl.cc
index 3fe9599..096289f 100644
--- a/src/reader/spirv/parser_impl.cc
+++ b/src/reader/spirv/parser_impl.cc
@@ -1277,7 +1277,7 @@
             create<ast::ScalarConstructorExpression>(
                 create<ast::FloatLiteral>(ast_type, spirv_const->GetFloat()))};
   }
-  if (ast_type->IsBool()) {
+  if (ast_type->Is<ast::type::BoolType>()) {
     const bool value = spirv_const->AsNullConstant()
                            ? false
                            : spirv_const->AsBoolConstant()->value();
@@ -1334,7 +1334,7 @@
   auto* original_type = type;
   type = type->UnwrapIfNeeded();
 
-  if (type->IsBool()) {
+  if (type->Is<ast::type::BoolType>()) {
     return create<ast::ScalarConstructorExpression>(
         create<ast::BoolLiteral>(type, false));
   }
diff --git a/src/reader/spirv/parser_impl_convert_type_test.cc b/src/reader/spirv/parser_impl_convert_type_test.cc
index 3239b0a..11f2d09 100644
--- a/src/reader/spirv/parser_impl_convert_type_test.cc
+++ b/src/reader/spirv/parser_impl_convert_type_test.cc
@@ -19,6 +19,7 @@
 #include "gmock/gmock.h"
 #include "src/ast/struct.h"
 #include "src/ast/type/array_type.h"
+#include "src/ast/type/bool_type.h"
 #include "src/ast/type/matrix_type.h"
 #include "src/ast/type/pointer_type.h"
 #include "src/ast/type/struct_type.h"
@@ -96,7 +97,7 @@
   EXPECT_TRUE(p->BuildInternalModule());
 
   auto* type = p->ConvertType(100);
-  EXPECT_TRUE(type->IsBool());
+  EXPECT_TRUE(type->Is<ast::type::BoolType>());
   EXPECT_TRUE(p->error().empty());
 }
 
diff --git a/src/reader/wgsl/parser_impl_type_decl_test.cc b/src/reader/wgsl/parser_impl_type_decl_test.cc
index 96352ad..83c31f1 100644
--- a/src/reader/wgsl/parser_impl_type_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_type_decl_test.cc
@@ -87,7 +87,7 @@
   EXPECT_FALSE(t.errored);
   ASSERT_NE(t.value, nullptr) << p->error();
   EXPECT_EQ(t.value, bool_type);
-  ASSERT_TRUE(t->IsBool());
+  ASSERT_TRUE(t->Is<ast::type::BoolType>());
 }
 
 TEST_F(ParserImplTest, TypeDecl_F32) {
diff --git a/src/type_determiner_test.cc b/src/type_determiner_test.cc
index 6503585..9c486ea 100644
--- a/src/type_determiner_test.cc
+++ b/src/type_determiner_test.cc
@@ -1190,7 +1190,7 @@
 
   ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
   ASSERT_NE(expr.result_type(), nullptr);
-  EXPECT_TRUE(expr.result_type()->IsBool());
+  EXPECT_TRUE(expr.result_type()->Is<ast::type::BoolType>());
 }
 
 TEST_P(Expr_Binary_LogicalTest, Vector) {
@@ -1211,7 +1211,8 @@
   ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
   ASSERT_NE(expr.result_type(), nullptr);
   ASSERT_TRUE(expr.result_type()->IsVector());
-  EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsBool());
+  EXPECT_TRUE(
+      expr.result_type()->AsVector()->type()->Is<ast::type::BoolType>());
   EXPECT_EQ(expr.result_type()->AsVector()->size(), 3u);
 }
 INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
@@ -1236,7 +1237,7 @@
 
   ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
   ASSERT_NE(expr.result_type(), nullptr);
-  EXPECT_TRUE(expr.result_type()->IsBool());
+  EXPECT_TRUE(expr.result_type()->Is<ast::type::BoolType>());
 }
 
 TEST_P(Expr_Binary_CompareTest, Vector) {
@@ -1257,7 +1258,8 @@
   ASSERT_TRUE(td()->DetermineResultType(&expr)) << td()->error();
   ASSERT_NE(expr.result_type(), nullptr);
   ASSERT_TRUE(expr.result_type()->IsVector());
-  EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsBool());
+  EXPECT_TRUE(
+      expr.result_type()->AsVector()->type()->Is<ast::type::BoolType>());
   EXPECT_EQ(expr.result_type()->AsVector()->size(), 3u);
 }
 INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
@@ -1616,7 +1618,7 @@
 
   EXPECT_TRUE(td()->DetermineResultType(&expr));
   ASSERT_NE(expr.result_type(), nullptr);
-  EXPECT_TRUE(expr.result_type()->IsBool());
+  EXPECT_TRUE(expr.result_type()->Is<ast::type::BoolType>());
 }
 INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
                          Intrinsic,
@@ -1644,7 +1646,8 @@
 
   ASSERT_NE(expr.result_type(), nullptr);
   ASSERT_TRUE(expr.result_type()->IsVector());
-  EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsBool());
+  EXPECT_TRUE(
+      expr.result_type()->AsVector()->type()->Is<ast::type::BoolType>());
   EXPECT_EQ(expr.result_type()->AsVector()->size(), 3u);
 }
 
@@ -1666,7 +1669,7 @@
   EXPECT_TRUE(td()->Determine());
   EXPECT_TRUE(td()->DetermineResultType(&expr));
   ASSERT_NE(expr.result_type(), nullptr);
-  EXPECT_TRUE(expr.result_type()->IsBool());
+  EXPECT_TRUE(expr.result_type()->Is<ast::type::BoolType>());
 }
 
 TEST_P(Intrinsic_FloatMethod, MissingParam) {
diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc
index a4d7564..e39d5ee 100644
--- a/src/writer/hlsl/generator_impl.cc
+++ b/src/writer/hlsl/generator_impl.cc
@@ -41,6 +41,7 @@
 #include "src/ast/type/access_control_type.h"
 #include "src/ast/type/alias_type.h"
 #include "src/ast/type/array_type.h"
+#include "src/ast/type/bool_type.h"
 #include "src/ast/type/f32_type.h"
 #include "src/ast/type/i32_type.h"
 #include "src/ast/type/matrix_type.h"
@@ -1542,7 +1543,7 @@
 }
 
 bool GeneratorImpl::EmitZeroValue(std::ostream& out, ast::type::Type* type) {
-  if (type->IsBool()) {
+  if (type->Is<ast::type::BoolType>()) {
     out << "false";
   } else if (type->IsF32()) {
     out << "0.0f";
@@ -2057,7 +2058,7 @@
     for (uint32_t size : sizes) {
       out << "[" << size << "]";
     }
-  } else if (type->IsBool()) {
+  } else if (type->Is<ast::type::BoolType>()) {
     out << "bool";
   } else if (type->IsF32()) {
     out << "float";
diff --git a/src/writer/msl/generator_impl.cc b/src/writer/msl/generator_impl.cc
index 1e98cc1..0d8830e 100644
--- a/src/writer/msl/generator_impl.cc
+++ b/src/writer/msl/generator_impl.cc
@@ -194,7 +194,7 @@
     uint32_t type_size = calculate_alignment_size(ary->type());
     return ary->size() * type_size;
   }
-  if (type->IsBool()) {
+  if (type->Is<ast::type::BoolType>()) {
     return 1;
   }
   if (type->IsPointer()) {
@@ -928,7 +928,7 @@
 }
 
 bool GeneratorImpl::EmitZeroValue(ast::type::Type* type) {
-  if (type->IsBool()) {
+  if (type->Is<ast::type::BoolType>()) {
     out_ << "false";
   } else if (type->IsF32()) {
     out_ << "0.0f";
@@ -1812,7 +1812,7 @@
     for (uint32_t size : sizes) {
       out_ << "[" << size << "]";
     }
-  } else if (type->IsBool()) {
+  } else if (type->Is<ast::type::BoolType>()) {
     out_ << "bool";
   } else if (type->IsF32()) {
     out_ << "float";
diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc
index 68b3e37..c640f84 100644
--- a/src/writer/spirv/builder.cc
+++ b/src/writer/spirv/builder.cc
@@ -52,6 +52,7 @@
 #include "src/ast/switch_statement.h"
 #include "src/ast/type/access_control_type.h"
 #include "src/ast/type/array_type.h"
+#include "src/ast/type/bool_type.h"
 #include "src/ast/type/depth_texture_type.h"
 #include "src/ast/type/f32_type.h"
 #include "src/ast/type/i32_type.h"
@@ -750,7 +751,7 @@
       } else if (type->IsI32()) {
         ast::SintLiteral l(type, 0);
         init_id = GenerateLiteralIfNeeded(var, &l);
-      } else if (type->IsBool()) {
+      } else if (type->Is<ast::type::BoolType>()) {
         ast::BoolLiteral l(type, false);
         init_id = GenerateLiteralIfNeeded(var, &l);
       } else {
@@ -1407,7 +1408,8 @@
              (from_type->is_float_vector() &&
               to_type->is_unsigned_integer_vector())) {
     op = spv::Op::OpConvertFToU;
-  } else if ((from_type->IsBool() && to_type->IsBool()) ||
+  } else if ((from_type->Is<ast::type::BoolType>() &&
+              to_type->Is<ast::type::BoolType>()) ||
              (from_type->IsU32() && to_type->IsU32()) ||
              (from_type->IsI32() && to_type->IsI32()) ||
              (from_type->IsF32() && to_type->IsF32()) ||
@@ -2414,7 +2416,7 @@
     if (!GenerateArrayType(type->As<ast::type::ArrayType>(), result)) {
       return 0;
     }
-  } else if (type->IsBool()) {
+  } else if (type->Is<ast::type::BoolType>()) {
     push_type(spv::Op::OpTypeBool, {result});
   } else if (type->IsF32()) {
     push_type(spv::Op::OpTypeFloat, {result, Operand::Int(32)});
diff --git a/src/writer/wgsl/generator_impl.cc b/src/writer/wgsl/generator_impl.cc
index f2d16de..00aaa68 100644
--- a/src/writer/wgsl/generator_impl.cc
+++ b/src/writer/wgsl/generator_impl.cc
@@ -53,6 +53,7 @@
 #include "src/ast/switch_statement.h"
 #include "src/ast/type/access_control_type.h"
 #include "src/ast/type/array_type.h"
+#include "src/ast/type/bool_type.h"
 #include "src/ast/type/depth_texture_type.h"
 #include "src/ast/type/matrix_type.h"
 #include "src/ast/type/multisampled_texture_type.h"
@@ -430,7 +431,7 @@
       out_ << ", " << ary->size();
 
     out_ << ">";
-  } else if (type->IsBool()) {
+  } else if (type->Is<ast::type::BoolType>()) {
     out_ << "bool";
   } else if (type->IsF32()) {
     out_ << "f32";