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

Change-Id: I75e5a34034360c1d4c96ae0ce293bc6cbfc1c33d
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/34266
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 b07d2a2..389f7f8 100644
--- a/src/ast/type/access_control_type_test.cc
+++ b/src/ast/type/access_control_type_test.cc
@@ -25,6 +25,7 @@
 #include "src/ast/test_helper.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/pointer_type.h"
 #include "src/ast/type/struct_type.h"
@@ -53,7 +54,7 @@
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
   EXPECT_FALSE(ty->Is<BoolType>());
-  EXPECT_FALSE(ty->IsF32());
+  EXPECT_FALSE(ty->Is<F32Type>());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
   EXPECT_FALSE(ty->IsPointer());
diff --git a/src/ast/type/alias_type_test.cc b/src/ast/type/alias_type_test.cc
index 22b81a7..26b1b32 100644
--- a/src/ast/type/alias_type_test.cc
+++ b/src/ast/type/alias_type_test.cc
@@ -26,6 +26,7 @@
 #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"
 #include "src/ast/type/i32_type.h"
 #include "src/ast/type/pointer_type.h"
 #include "src/ast/type/struct_type.h"
@@ -54,7 +55,7 @@
   EXPECT_TRUE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
   EXPECT_FALSE(ty->Is<BoolType>());
-  EXPECT_FALSE(ty->IsF32());
+  EXPECT_FALSE(ty->Is<F32Type>());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
   EXPECT_FALSE(ty->IsPointer());
diff --git a/src/ast/type/array_type_test.cc b/src/ast/type/array_type_test.cc
index 40ec166..19f7d1a 100644
--- a/src/ast/type/array_type_test.cc
+++ b/src/ast/type/array_type_test.cc
@@ -21,6 +21,7 @@
 #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/f32_type.h"
 #include "src/ast/type/i32_type.h"
 #include "src/ast/type/u32_type.h"
 
@@ -58,7 +59,7 @@
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_TRUE(ty->Is<ArrayType>());
   EXPECT_FALSE(ty->Is<BoolType>());
-  EXPECT_FALSE(ty->IsF32());
+  EXPECT_FALSE(ty->Is<F32Type>());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
   EXPECT_FALSE(ty->IsPointer());
diff --git a/src/ast/type/bool_type_test.cc b/src/ast/type/bool_type_test.cc
index 6b7c523..fffa7d7 100644
--- a/src/ast/type/bool_type_test.cc
+++ b/src/ast/type/bool_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/f32_type.h"
 
 namespace tint {
 namespace ast {
@@ -32,7 +33,7 @@
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
   EXPECT_TRUE(ty->Is<BoolType>());
-  EXPECT_FALSE(ty->IsF32());
+  EXPECT_FALSE(ty->Is<F32Type>());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
   EXPECT_FALSE(ty->IsPointer());
diff --git a/src/ast/type/depth_texture_type_test.cc b/src/ast/type/depth_texture_type_test.cc
index 1f5ea21..1bc6e15 100644
--- a/src/ast/type/depth_texture_type_test.cc
+++ b/src/ast/type/depth_texture_type_test.cc
@@ -19,6 +19,7 @@
 #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 {
 namespace ast {
@@ -34,7 +35,7 @@
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
   EXPECT_FALSE(ty->Is<BoolType>());
-  EXPECT_FALSE(ty->IsF32());
+  EXPECT_FALSE(ty->Is<F32Type>());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
   EXPECT_FALSE(ty->IsPointer());
diff --git a/src/ast/type/f32_type.cc b/src/ast/type/f32_type.cc
index ef9d5f1..08e37c2 100644
--- a/src/ast/type/f32_type.cc
+++ b/src/ast/type/f32_type.cc
@@ -24,10 +24,6 @@
 
 F32Type::~F32Type() = default;
 
-bool F32Type::IsF32() const {
-  return true;
-}
-
 std::string F32Type::type_name() const {
   return "__f32";
 }
diff --git a/src/ast/type/f32_type.h b/src/ast/type/f32_type.h
index bbc330d..e5ceb7f 100644
--- a/src/ast/type/f32_type.h
+++ b/src/ast/type/f32_type.h
@@ -32,9 +32,6 @@
   F32Type(F32Type&&);
   ~F32Type() override;
 
-  /// @returns true if the type is an f32 type
-  bool IsF32() const override;
-
   /// @returns the name for this type
   std::string type_name() const override;
 
diff --git a/src/ast/type/f32_type_test.cc b/src/ast/type/f32_type_test.cc
index 01327c4..718df7b 100644
--- a/src/ast/type/f32_type_test.cc
+++ b/src/ast/type/f32_type_test.cc
@@ -33,7 +33,7 @@
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
   EXPECT_FALSE(ty->Is<BoolType>());
-  EXPECT_TRUE(ty->IsF32());
+  EXPECT_TRUE(ty->Is<F32Type>());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
   EXPECT_FALSE(ty->IsPointer());
diff --git a/src/ast/type/i32_type_test.cc b/src/ast/type/i32_type_test.cc
index 3deed3b..e41c2fb 100644
--- a/src/ast/type/i32_type_test.cc
+++ b/src/ast/type/i32_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"
+#include "src/ast/type/f32_type.h"
 
 namespace tint {
 namespace ast {
@@ -33,7 +34,7 @@
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
   EXPECT_FALSE(ty->Is<BoolType>());
-  EXPECT_FALSE(ty->IsF32());
+  EXPECT_FALSE(ty->Is<F32Type>());
   EXPECT_TRUE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
   EXPECT_FALSE(ty->IsPointer());
diff --git a/src/ast/type/matrix_type_test.cc b/src/ast/type/matrix_type_test.cc
index 395e4df..ae207e9 100644
--- a/src/ast/type/matrix_type_test.cc
+++ b/src/ast/type/matrix_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"
+#include "src/ast/type/f32_type.h"
 #include "src/ast/type/i32_type.h"
 
 namespace tint {
@@ -43,7 +44,7 @@
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
   EXPECT_FALSE(ty->Is<BoolType>());
-  EXPECT_FALSE(ty->IsF32());
+  EXPECT_FALSE(ty->Is<F32Type>());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_TRUE(ty->IsMatrix());
   EXPECT_FALSE(ty->IsPointer());
diff --git a/src/ast/type/multisampled_texture_type_test.cc b/src/ast/type/multisampled_texture_type_test.cc
index 75a15aa..c9d5919 100644
--- a/src/ast/type/multisampled_texture_type_test.cc
+++ b/src/ast/type/multisampled_texture_type_test.cc
@@ -35,7 +35,7 @@
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
   EXPECT_FALSE(ty->Is<BoolType>());
-  EXPECT_FALSE(ty->IsF32());
+  EXPECT_FALSE(ty->Is<F32Type>());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
   EXPECT_FALSE(ty->IsPointer());
diff --git a/src/ast/type/pointer_type_test.cc b/src/ast/type/pointer_type_test.cc
index 1d93fc2..755d6ae 100644
--- a/src/ast/type/pointer_type_test.cc
+++ b/src/ast/type/pointer_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"
+#include "src/ast/type/f32_type.h"
 #include "src/ast/type/i32_type.h"
 
 namespace tint {
@@ -42,7 +43,7 @@
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
   EXPECT_FALSE(ty->Is<BoolType>());
-  EXPECT_FALSE(ty->IsF32());
+  EXPECT_FALSE(ty->Is<F32Type>());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
   EXPECT_TRUE(ty->IsPointer());
diff --git a/src/ast/type/sampled_texture_type_test.cc b/src/ast/type/sampled_texture_type_test.cc
index bc90dcf..845735d 100644
--- a/src/ast/type/sampled_texture_type_test.cc
+++ b/src/ast/type/sampled_texture_type_test.cc
@@ -35,7 +35,7 @@
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
   EXPECT_FALSE(ty->Is<BoolType>());
-  EXPECT_FALSE(ty->IsF32());
+  EXPECT_FALSE(ty->Is<F32Type>());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
   EXPECT_FALSE(ty->IsPointer());
diff --git a/src/ast/type/sampler_type_test.cc b/src/ast/type/sampler_type_test.cc
index 1363f09..d895bbb 100644
--- a/src/ast/type/sampler_type_test.cc
+++ b/src/ast/type/sampler_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"
+#include "src/ast/type/f32_type.h"
 
 namespace tint {
 namespace ast {
@@ -44,7 +45,7 @@
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
   EXPECT_FALSE(ty->Is<BoolType>());
-  EXPECT_FALSE(ty->IsF32());
+  EXPECT_FALSE(ty->Is<F32Type>());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
   EXPECT_FALSE(ty->IsPointer());
diff --git a/src/ast/type/storage_texture_type_test.cc b/src/ast/type/storage_texture_type_test.cc
index c35e5d0..4e9277a 100644
--- a/src/ast/type/storage_texture_type_test.cc
+++ b/src/ast/type/storage_texture_type_test.cc
@@ -21,6 +21,7 @@
 #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"
 #include "src/type_determiner.h"
 
 namespace tint {
@@ -38,7 +39,7 @@
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
   EXPECT_FALSE(ty->Is<BoolType>());
-  EXPECT_FALSE(ty->IsF32());
+  EXPECT_FALSE(ty->Is<F32Type>());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
   EXPECT_FALSE(ty->IsPointer());
@@ -92,7 +93,7 @@
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(s->IsTexture());
   ASSERT_TRUE(s->AsTexture()->IsStorage());
-  EXPECT_TRUE(s->AsTexture()->AsStorage()->type()->IsF32());
+  EXPECT_TRUE(s->AsTexture()->AsStorage()->type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(StorageTextureTypeTest, U32Type) {
diff --git a/src/ast/type/struct_type_test.cc b/src/ast/type/struct_type_test.cc
index cee3f5b..94aef60 100644
--- a/src/ast/type/struct_type_test.cc
+++ b/src/ast/type/struct_type_test.cc
@@ -24,6 +24,7 @@
 #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"
 #include "src/ast/type/i32_type.h"
 #include "src/ast/type/u32_type.h"
 #include "src/ast/type/vector_type.h"
@@ -50,7 +51,7 @@
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
   EXPECT_FALSE(ty->Is<BoolType>());
-  EXPECT_FALSE(ty->IsF32());
+  EXPECT_FALSE(ty->Is<F32Type>());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
   EXPECT_FALSE(ty->IsPointer());
diff --git a/src/ast/type/type.cc b/src/ast/type/type.cc
index 8339977..e6377ce 100644
--- a/src/ast/type/type.cc
+++ b/src/ast/type/type.cc
@@ -66,10 +66,6 @@
   return UnwrapIfNeeded()->UnwrapPtrIfNeeded()->UnwrapIfNeeded();
 }
 
-bool Type::IsF32() const {
-  return false;
-}
-
 bool Type::IsI32() const {
   return false;
 }
@@ -119,7 +115,7 @@
 }
 
 bool Type::is_float_scalar() {
-  return IsF32();
+  return Is<F32Type>();
 }
 
 bool Type::is_float_matrix() {
@@ -158,11 +154,6 @@
   return is_unsigned_scalar_or_vector() || is_signed_scalar_or_vector();
 }
 
-const F32Type* Type::AsF32() const {
-  assert(IsF32());
-  return static_cast<const F32Type*>(this);
-}
-
 const I32Type* Type::AsI32() const {
   assert(IsI32());
   return static_cast<const I32Type*>(this);
@@ -208,11 +199,6 @@
   return static_cast<const VoidType*>(this);
 }
 
-F32Type* Type::AsF32() {
-  assert(IsF32());
-  return static_cast<F32Type*>(this);
-}
-
 I32Type* Type::AsI32() {
   assert(IsI32());
   return static_cast<I32Type*>(this);
diff --git a/src/ast/type/type.h b/src/ast/type/type.h
index 907d7a3..fff6457 100644
--- a/src/ast/type/type.h
+++ b/src/ast/type/type.h
@@ -23,7 +23,6 @@
 namespace ast {
 namespace type {
 
-class F32Type;
 class I32Type;
 class MatrixType;
 class PointerType;
@@ -44,8 +43,6 @@
   Type(Type&&);
   ~Type() override;
 
-  /// @returns true if the type is an f32 type
-  virtual bool IsF32() const;
   /// @returns true if the type is an i32 type
   virtual bool IsI32() const;
   /// @returns true if the type is a matrix type
@@ -119,8 +116,6 @@
   /// @returns true if this type is an integer scalar or vector
   bool is_integer_scalar_or_vector();
 
-  /// @returns the type as a f32 type
-  const F32Type* AsF32() const;
   /// @returns the type as an i32 type
   const I32Type* AsI32() const;
   /// @returns the type as a matrix type
@@ -140,8 +135,6 @@
   /// @returns the type as a void type
   const VoidType* AsVoid() const;
 
-  /// @returns the type as a f32 type
-  F32Type* AsF32();
   /// @returns the type as an i32 type
   I32Type* AsI32();
   /// @returns the type as a matrix type
diff --git a/src/ast/type/u32_type_test.cc b/src/ast/type/u32_type_test.cc
index 20d92da..98ab357 100644
--- a/src/ast/type/u32_type_test.cc
+++ b/src/ast/type/u32_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"
+#include "src/ast/type/f32_type.h"
 
 namespace tint {
 namespace ast {
@@ -33,7 +34,7 @@
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
   EXPECT_FALSE(ty->Is<BoolType>());
-  EXPECT_FALSE(ty->IsF32());
+  EXPECT_FALSE(ty->Is<F32Type>());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
   EXPECT_FALSE(ty->IsPointer());
diff --git a/src/ast/type/vector_type_test.cc b/src/ast/type/vector_type_test.cc
index a849f5e..d5491bf 100644
--- a/src/ast/type/vector_type_test.cc
+++ b/src/ast/type/vector_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"
+#include "src/ast/type/f32_type.h"
 #include "src/ast/type/i32_type.h"
 
 namespace tint {
@@ -42,7 +43,7 @@
   EXPECT_FALSE(ty->Is<AliasType>());
   EXPECT_FALSE(ty->Is<ArrayType>());
   EXPECT_FALSE(ty->Is<BoolType>());
-  EXPECT_FALSE(ty->IsF32());
+  EXPECT_FALSE(ty->Is<F32Type>());
   EXPECT_FALSE(ty->IsI32());
   EXPECT_FALSE(ty->IsMatrix());
   EXPECT_FALSE(ty->IsPointer());
diff --git a/src/inspector/inspector.cc b/src/inspector/inspector.cc
index 2eba14f..f891d7c 100644
--- a/src/inspector/inspector.cc
+++ b/src/inspector/inspector.cc
@@ -28,6 +28,7 @@
 #include "src/ast/sint_literal.h"
 #include "src/ast/type/access_control_type.h"
 #include "src/ast/type/array_type.h"
+#include "src/ast/type/f32_type.h"
 #include "src/ast/type/matrix_type.h"
 #include "src/ast/type/multisampled_texture_type.h"
 #include "src/ast/type/sampled_texture_type.h"
@@ -391,7 +392,7 @@
       base_type = base_type->AsVector()->type();
     }
 
-    if (base_type->IsF32()) {
+    if (base_type->Is<ast::type::F32Type>()) {
       entry.sampled_kind = ResourceBinding::SampledKind::kFloat;
     } else if (base_type->IsU32()) {
       entry.sampled_kind = ResourceBinding::SampledKind::kUInt;
diff --git a/src/reader/spirv/function.cc b/src/reader/spirv/function.cc
index ad29bfc..816fac1 100644
--- a/src/reader/spirv/function.cc
+++ b/src/reader/spirv/function.cc
@@ -53,6 +53,7 @@
 #include "src/ast/storage_class.h"
 #include "src/ast/switch_statement.h"
 #include "src/ast/type/bool_type.h"
+#include "src/ast/type/f32_type.h"
 #include "src/ast/type/pointer_type.h"
 #include "src/ast/type/texture_type.h"
 #include "src/ast/type/type.h"
@@ -3823,7 +3824,7 @@
   assert(num_axes <= 3);
   const auto num_coords_required = num_axes + (is_arrayed ? 1 : 0);
   uint32_t num_coords_supplied = 0;
-  if (raw_coords.type->IsF32()) {
+  if (raw_coords.type->Is<ast::type::F32Type>()) {
     num_coords_supplied = 1;
   } else if (raw_coords.type->IsVector()) {
     num_coords_supplied = raw_coords.type->AsVector()->size();
diff --git a/src/reader/spirv/parser_impl.cc b/src/reader/spirv/parser_impl.cc
index 096289f..4edcfd5 100644
--- a/src/reader/spirv/parser_impl.cc
+++ b/src/reader/spirv/parser_impl.cc
@@ -983,7 +983,7 @@
           ast_expr =
               create<ast::ScalarConstructorExpression>(create<ast::UintLiteral>(
                   ast_type, static_cast<uint32_t>(literal_value)));
-        } else if (ast_type->IsF32()) {
+        } else if (ast_type->Is<ast::type::F32Type>()) {
           float float_value;
           // Copy the bits so we can read them as a float.
           std::memcpy(&float_value, &literal_value, sizeof(float_value));
@@ -1272,7 +1272,7 @@
             create<ast::ScalarConstructorExpression>(
                 create<ast::SintLiteral>(ast_type, spirv_const->GetS32()))};
   }
-  if (ast_type->IsF32()) {
+  if (ast_type->Is<ast::type::F32Type>()) {
     return {ast_type,
             create<ast::ScalarConstructorExpression>(
                 create<ast::FloatLiteral>(ast_type, spirv_const->GetFloat()))};
@@ -1346,7 +1346,7 @@
     return create<ast::ScalarConstructorExpression>(
         create<ast::SintLiteral>(type, 0));
   }
-  if (type->IsF32()) {
+  if (type->Is<ast::type::F32Type>()) {
     return create<ast::ScalarConstructorExpression>(
         create<ast::FloatLiteral>(type, 0.0f));
   }
@@ -1445,7 +1445,7 @@
     Fail() << "no type provided";
   }
   auto* i32 = ast_module_.create<ast::type::I32Type>();
-  if (other->IsF32() || other->IsU32() || other->IsI32()) {
+  if (other->Is<ast::type::F32Type>() || other->IsU32() || other->IsI32()) {
     return i32;
   }
   auto* vec_ty = other->AsVector();
@@ -1463,7 +1463,7 @@
     return nullptr;
   }
   auto* u32 = ast_module_.create<ast::type::U32Type>();
-  if (other->IsF32() || other->IsU32() || other->IsI32()) {
+  if (other->Is<ast::type::F32Type>() || other->IsU32() || other->IsI32()) {
     return u32;
   }
   auto* vec_ty = other->AsVector();
diff --git a/src/reader/spirv/parser_impl_convert_type_test.cc b/src/reader/spirv/parser_impl_convert_type_test.cc
index 11f2d09..0c3e9da 100644
--- a/src/reader/spirv/parser_impl_convert_type_test.cc
+++ b/src/reader/spirv/parser_impl_convert_type_test.cc
@@ -20,6 +20,7 @@
 #include "src/ast/struct.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/matrix_type.h"
 #include "src/ast/type/pointer_type.h"
 #include "src/ast/type/struct_type.h"
@@ -124,7 +125,7 @@
   EXPECT_TRUE(p->BuildInternalModule());
 
   auto* type = p->ConvertType(4);
-  EXPECT_TRUE(type->IsF32());
+  EXPECT_TRUE(type->Is<ast::type::F32Type>());
   EXPECT_TRUE(p->error().empty());
 }
 
@@ -169,17 +170,17 @@
 
   auto* v2xf32 = p->ConvertType(20);
   EXPECT_TRUE(v2xf32->IsVector());
-  EXPECT_TRUE(v2xf32->AsVector()->type()->IsF32());
+  EXPECT_TRUE(v2xf32->AsVector()->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(v2xf32->AsVector()->size(), 2u);
 
   auto* v3xf32 = p->ConvertType(30);
   EXPECT_TRUE(v3xf32->IsVector());
-  EXPECT_TRUE(v3xf32->AsVector()->type()->IsF32());
+  EXPECT_TRUE(v3xf32->AsVector()->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(v3xf32->AsVector()->size(), 3u);
 
   auto* v4xf32 = p->ConvertType(40);
   EXPECT_TRUE(v4xf32->IsVector());
-  EXPECT_TRUE(v4xf32->AsVector()->type()->IsF32());
+  EXPECT_TRUE(v4xf32->AsVector()->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(v4xf32->AsVector()->size(), 4u);
 
   EXPECT_TRUE(p->error().empty());
@@ -275,55 +276,55 @@
 
   auto* m22 = p->ConvertType(22);
   EXPECT_TRUE(m22->IsMatrix());
-  EXPECT_TRUE(m22->AsMatrix()->type()->IsF32());
+  EXPECT_TRUE(m22->AsMatrix()->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(m22->AsMatrix()->rows(), 2u);
   EXPECT_EQ(m22->AsMatrix()->columns(), 2u);
 
   auto* m23 = p->ConvertType(23);
   EXPECT_TRUE(m23->IsMatrix());
-  EXPECT_TRUE(m23->AsMatrix()->type()->IsF32());
+  EXPECT_TRUE(m23->AsMatrix()->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(m23->AsMatrix()->rows(), 2u);
   EXPECT_EQ(m23->AsMatrix()->columns(), 3u);
 
   auto* m24 = p->ConvertType(24);
   EXPECT_TRUE(m24->IsMatrix());
-  EXPECT_TRUE(m24->AsMatrix()->type()->IsF32());
+  EXPECT_TRUE(m24->AsMatrix()->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(m24->AsMatrix()->rows(), 2u);
   EXPECT_EQ(m24->AsMatrix()->columns(), 4u);
 
   auto* m32 = p->ConvertType(32);
   EXPECT_TRUE(m32->IsMatrix());
-  EXPECT_TRUE(m32->AsMatrix()->type()->IsF32());
+  EXPECT_TRUE(m32->AsMatrix()->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(m32->AsMatrix()->rows(), 3u);
   EXPECT_EQ(m32->AsMatrix()->columns(), 2u);
 
   auto* m33 = p->ConvertType(33);
   EXPECT_TRUE(m33->IsMatrix());
-  EXPECT_TRUE(m33->AsMatrix()->type()->IsF32());
+  EXPECT_TRUE(m33->AsMatrix()->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(m33->AsMatrix()->rows(), 3u);
   EXPECT_EQ(m33->AsMatrix()->columns(), 3u);
 
   auto* m34 = p->ConvertType(34);
   EXPECT_TRUE(m34->IsMatrix());
-  EXPECT_TRUE(m34->AsMatrix()->type()->IsF32());
+  EXPECT_TRUE(m34->AsMatrix()->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(m34->AsMatrix()->rows(), 3u);
   EXPECT_EQ(m34->AsMatrix()->columns(), 4u);
 
   auto* m42 = p->ConvertType(42);
   EXPECT_TRUE(m42->IsMatrix());
-  EXPECT_TRUE(m42->AsMatrix()->type()->IsF32());
+  EXPECT_TRUE(m42->AsMatrix()->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(m42->AsMatrix()->rows(), 4u);
   EXPECT_EQ(m42->AsMatrix()->columns(), 2u);
 
   auto* m43 = p->ConvertType(43);
   EXPECT_TRUE(m43->IsMatrix());
-  EXPECT_TRUE(m43->AsMatrix()->type()->IsF32());
+  EXPECT_TRUE(m43->AsMatrix()->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(m43->AsMatrix()->rows(), 4u);
   EXPECT_EQ(m43->AsMatrix()->columns(), 3u);
 
   auto* m44 = p->ConvertType(44);
   EXPECT_TRUE(m44->IsMatrix());
-  EXPECT_TRUE(m44->AsMatrix()->type()->IsF32());
+  EXPECT_TRUE(m44->AsMatrix()->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(m44->AsMatrix()->rows(), 4u);
   EXPECT_EQ(m44->AsMatrix()->columns(), 4u);
 
@@ -657,7 +658,7 @@
   EXPECT_TRUE(type->IsPointer());
   auto* ptr_ty = type->AsPointer();
   EXPECT_NE(ptr_ty, nullptr);
-  EXPECT_TRUE(ptr_ty->type()->IsF32());
+  EXPECT_TRUE(ptr_ty->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(ptr_ty->storage_class(), ast::StorageClass::kInput);
   EXPECT_TRUE(p->error().empty());
 }
@@ -673,7 +674,7 @@
   EXPECT_TRUE(type->IsPointer());
   auto* ptr_ty = type->AsPointer();
   EXPECT_NE(ptr_ty, nullptr);
-  EXPECT_TRUE(ptr_ty->type()->IsF32());
+  EXPECT_TRUE(ptr_ty->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(ptr_ty->storage_class(), ast::StorageClass::kOutput);
   EXPECT_TRUE(p->error().empty());
 }
@@ -689,7 +690,7 @@
   EXPECT_TRUE(type->IsPointer());
   auto* ptr_ty = type->AsPointer();
   EXPECT_NE(ptr_ty, nullptr);
-  EXPECT_TRUE(ptr_ty->type()->IsF32());
+  EXPECT_TRUE(ptr_ty->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(ptr_ty->storage_class(), ast::StorageClass::kUniform);
   EXPECT_TRUE(p->error().empty());
 }
@@ -705,7 +706,7 @@
   EXPECT_TRUE(type->IsPointer());
   auto* ptr_ty = type->AsPointer();
   EXPECT_NE(ptr_ty, nullptr);
-  EXPECT_TRUE(ptr_ty->type()->IsF32());
+  EXPECT_TRUE(ptr_ty->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(ptr_ty->storage_class(), ast::StorageClass::kWorkgroup);
   EXPECT_TRUE(p->error().empty());
 }
@@ -721,7 +722,7 @@
   EXPECT_TRUE(type->IsPointer());
   auto* ptr_ty = type->AsPointer();
   EXPECT_NE(ptr_ty, nullptr);
-  EXPECT_TRUE(ptr_ty->type()->IsF32());
+  EXPECT_TRUE(ptr_ty->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(ptr_ty->storage_class(), ast::StorageClass::kUniformConstant);
   EXPECT_TRUE(p->error().empty());
 }
@@ -737,7 +738,7 @@
   EXPECT_TRUE(type->IsPointer());
   auto* ptr_ty = type->AsPointer();
   EXPECT_NE(ptr_ty, nullptr);
-  EXPECT_TRUE(ptr_ty->type()->IsF32());
+  EXPECT_TRUE(ptr_ty->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(ptr_ty->storage_class(), ast::StorageClass::kStorageBuffer);
   EXPECT_TRUE(p->error().empty());
 }
@@ -753,7 +754,7 @@
   EXPECT_TRUE(type->IsPointer());
   auto* ptr_ty = type->AsPointer();
   EXPECT_NE(ptr_ty, nullptr);
-  EXPECT_TRUE(ptr_ty->type()->IsF32());
+  EXPECT_TRUE(ptr_ty->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(ptr_ty->storage_class(), ast::StorageClass::kImage);
   EXPECT_TRUE(p->error().empty());
 }
@@ -769,7 +770,7 @@
   EXPECT_TRUE(type->IsPointer());
   auto* ptr_ty = type->AsPointer();
   EXPECT_NE(ptr_ty, nullptr);
-  EXPECT_TRUE(ptr_ty->type()->IsF32());
+  EXPECT_TRUE(ptr_ty->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(ptr_ty->storage_class(), ast::StorageClass::kPrivate);
   EXPECT_TRUE(p->error().empty());
 }
@@ -785,7 +786,7 @@
   EXPECT_TRUE(type->IsPointer());
   auto* ptr_ty = type->AsPointer();
   EXPECT_NE(ptr_ty, nullptr);
-  EXPECT_TRUE(ptr_ty->type()->IsF32());
+  EXPECT_TRUE(ptr_ty->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(ptr_ty->storage_class(), ast::StorageClass::kFunction);
   EXPECT_TRUE(p->error().empty());
 }
@@ -811,7 +812,7 @@
   auto* ptr_ptr_ty = ptr_ty->type()->AsPointer();
   EXPECT_NE(ptr_ptr_ty, nullptr);
   EXPECT_EQ(ptr_ptr_ty->storage_class(), ast::StorageClass::kOutput);
-  EXPECT_TRUE(ptr_ptr_ty->type()->IsF32());
+  EXPECT_TRUE(ptr_ptr_ty->type()->Is<ast::type::F32Type>());
 
   EXPECT_TRUE(p->error().empty());
 }
diff --git a/src/reader/wgsl/parser_impl_global_constant_decl_test.cc b/src/reader/wgsl/parser_impl_global_constant_decl_test.cc
index 3f4aaed..ed6bbf6 100644
--- a/src/reader/wgsl/parser_impl_global_constant_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_global_constant_decl_test.cc
@@ -14,6 +14,7 @@
 
 #include "gtest/gtest.h"
 #include "src/ast/decorated_variable.h"
+#include "src/ast/type/f32_type.h"
 #include "src/ast/variable_decoration.h"
 #include "src/reader/wgsl/parser_impl.h"
 #include "src/reader/wgsl/parser_impl_test_helper.h"
@@ -34,7 +35,7 @@
   EXPECT_TRUE(e->is_const());
   EXPECT_EQ(e->name(), "a");
   ASSERT_NE(e->type(), nullptr);
-  EXPECT_TRUE(e->type()->IsF32());
+  EXPECT_TRUE(e->type()->Is<ast::type::F32Type>());
 
   EXPECT_EQ(e->source().range.begin.line, 1u);
   EXPECT_EQ(e->source().range.begin.column, 7u);
diff --git a/src/reader/wgsl/parser_impl_global_variable_decl_test.cc b/src/reader/wgsl/parser_impl_global_variable_decl_test.cc
index 65913b3..4ec1806 100644
--- a/src/reader/wgsl/parser_impl_global_variable_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_global_variable_decl_test.cc
@@ -14,6 +14,7 @@
 
 #include "gtest/gtest.h"
 #include "src/ast/decorated_variable.h"
+#include "src/ast/type/f32_type.h"
 #include "src/ast/variable_decoration.h"
 #include "src/reader/wgsl/parser_impl.h"
 #include "src/reader/wgsl/parser_impl_test_helper.h"
@@ -35,7 +36,7 @@
   ASSERT_NE(e.value, nullptr);
 
   EXPECT_EQ(e->name(), "a");
-  EXPECT_TRUE(e->type()->IsF32());
+  EXPECT_TRUE(e->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(e->storage_class(), ast::StorageClass::kOutput);
 
   EXPECT_EQ(e->source().range.begin.line, 1u);
@@ -59,7 +60,7 @@
   ASSERT_NE(e.value, nullptr);
 
   EXPECT_EQ(e->name(), "a");
-  EXPECT_TRUE(e->type()->IsF32());
+  EXPECT_TRUE(e->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(e->storage_class(), ast::StorageClass::kOutput);
 
   EXPECT_EQ(e->source().range.begin.line, 1u);
@@ -88,7 +89,7 @@
 
   EXPECT_EQ(e->name(), "a");
   ASSERT_NE(e->type(), nullptr);
-  EXPECT_TRUE(e->type()->IsF32());
+  EXPECT_TRUE(e->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(e->storage_class(), ast::StorageClass::kOutput);
 
   EXPECT_EQ(e->source().range.begin.line, 1u);
@@ -122,7 +123,7 @@
 
   EXPECT_EQ(e->name(), "a");
   ASSERT_NE(e->type(), nullptr);
-  EXPECT_TRUE(e->type()->IsF32());
+  EXPECT_TRUE(e->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(e->storage_class(), ast::StorageClass::kOutput);
 
   EXPECT_EQ(e->source().range.begin.line, 1u);
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 f4d354a..6b370e6 100644
--- a/src/reader/wgsl/parser_impl_texture_sampler_types_test.cc
+++ b/src/reader/wgsl/parser_impl_texture_sampler_types_test.cc
@@ -13,6 +13,7 @@
 // limitations under the License.
 
 #include "gtest/gtest.h"
+#include "src/ast/type/f32_type.h"
 #include "src/ast/type/multisampled_texture_type.h"
 #include "src/ast/type/sampled_texture_type.h"
 #include "src/ast/type/sampler_type.h"
@@ -76,7 +77,7 @@
   ASSERT_NE(t.value, nullptr);
   ASSERT_TRUE(t->IsTexture());
   ASSERT_TRUE(t->AsTexture()->IsSampled());
-  ASSERT_TRUE(t->AsTexture()->AsSampled()->type()->IsF32());
+  ASSERT_TRUE(t->AsTexture()->AsSampled()->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(t->AsTexture()->dim(), ast::type::TextureDimension::k1d);
 }
 
@@ -156,7 +157,7 @@
   ASSERT_NE(t.value, nullptr);
   ASSERT_TRUE(t->IsTexture());
   ASSERT_TRUE(t->AsTexture()->IsSampled());
-  ASSERT_TRUE(t->AsTexture()->AsSampled()->type()->IsF32());
+  ASSERT_TRUE(t->AsTexture()->AsSampled()->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(t->AsTexture()->dim(), ast::type::TextureDimension::k1d);
 }
 
diff --git a/src/reader/wgsl/parser_impl_type_decl_test.cc b/src/reader/wgsl/parser_impl_type_decl_test.cc
index 83c31f1..73fc77a 100644
--- a/src/reader/wgsl/parser_impl_type_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_type_decl_test.cc
@@ -101,7 +101,7 @@
   EXPECT_FALSE(t.errored);
   ASSERT_NE(t.value, nullptr) << p->error();
   EXPECT_EQ(t.value, float_type);
-  ASSERT_TRUE(t->IsF32());
+  ASSERT_TRUE(t->Is<ast::type::F32Type>());
 }
 
 TEST_F(ParserImplTest, TypeDecl_I32) {
@@ -242,7 +242,7 @@
   ASSERT_TRUE(t->IsPointer());
 
   auto* ptr = t->AsPointer();
-  ASSERT_TRUE(ptr->type()->IsF32());
+  ASSERT_TRUE(ptr->type()->Is<ast::type::F32Type>());
   ASSERT_EQ(ptr->storage_class(), ast::StorageClass::kFunction);
 }
 
@@ -261,7 +261,7 @@
 
   auto* vec = ptr->type()->AsVector();
   ASSERT_EQ(vec->size(), 2u);
-  ASSERT_TRUE(vec->type()->IsF32());
+  ASSERT_TRUE(vec->type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(ParserImplTest, TypeDecl_Ptr_MissingLessThan) {
@@ -356,7 +356,7 @@
   auto* a = t->As<ast::type::ArrayType>();
   ASSERT_FALSE(a->IsRuntimeArray());
   ASSERT_EQ(a->size(), 5u);
-  ASSERT_TRUE(a->type()->IsF32());
+  ASSERT_TRUE(a->type()->Is<ast::type::F32Type>());
   ASSERT_FALSE(a->has_array_stride());
 }
 
@@ -372,7 +372,7 @@
   auto* a = t->As<ast::type::ArrayType>();
   ASSERT_FALSE(a->IsRuntimeArray());
   ASSERT_EQ(a->size(), 5u);
-  ASSERT_TRUE(a->type()->IsF32());
+  ASSERT_TRUE(a->type()->Is<ast::type::F32Type>());
   ASSERT_TRUE(a->has_array_stride());
   EXPECT_EQ(a->array_stride(), 16u);
 }
@@ -388,7 +388,7 @@
 
   auto* a = t->As<ast::type::ArrayType>();
   ASSERT_TRUE(a->IsRuntimeArray());
-  ASSERT_TRUE(a->type()->IsF32());
+  ASSERT_TRUE(a->type()->Is<ast::type::F32Type>());
   ASSERT_TRUE(a->has_array_stride());
   EXPECT_EQ(a->array_stride(), 16u);
 }
@@ -404,7 +404,7 @@
 
   auto* a = t->As<ast::type::ArrayType>();
   ASSERT_TRUE(a->IsRuntimeArray());
-  ASSERT_TRUE(a->type()->IsF32());
+  ASSERT_TRUE(a->type()->Is<ast::type::F32Type>());
 
   auto& decos = a->decorations();
   ASSERT_EQ(decos.size(), 2u);
@@ -425,7 +425,7 @@
 
   auto* a = t->As<ast::type::ArrayType>();
   ASSERT_TRUE(a->IsRuntimeArray());
-  ASSERT_TRUE(a->type()->IsF32());
+  ASSERT_TRUE(a->type()->Is<ast::type::F32Type>());
 
   auto& decos = a->decorations();
   ASSERT_EQ(decos.size(), 2u);
@@ -766,7 +766,7 @@
   EXPECT_EQ(t.value, type);
   ASSERT_TRUE(t->IsTexture());
   ASSERT_TRUE(t->AsTexture()->IsSampled());
-  ASSERT_TRUE(t->AsTexture()->AsSampled()->type()->IsF32());
+  ASSERT_TRUE(t->AsTexture()->AsSampled()->type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(ParserImplTest, TypeDecl_Texture) {
@@ -784,7 +784,7 @@
   EXPECT_EQ(t.value, type);
   ASSERT_TRUE(t->IsTexture());
   ASSERT_TRUE(t->AsTexture()->IsSampled());
-  ASSERT_TRUE(t->AsTexture()->AsSampled()->type()->IsF32());
+  ASSERT_TRUE(t->AsTexture()->AsSampled()->type()->Is<ast::type::F32Type>());
 }
 
 }  // namespace
diff --git a/src/reader/wgsl/parser_impl_variable_decl_test.cc b/src/reader/wgsl/parser_impl_variable_decl_test.cc
index 64fb71e..fdc17c9 100644
--- a/src/reader/wgsl/parser_impl_variable_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_variable_decl_test.cc
@@ -13,6 +13,7 @@
 // limitations under the License.
 
 #include "gtest/gtest.h"
+#include "src/ast/type/f32_type.h"
 #include "src/ast/variable.h"
 #include "src/reader/wgsl/parser_impl.h"
 #include "src/reader/wgsl/parser_impl_test_helper.h"
@@ -31,7 +32,7 @@
   ASSERT_NE(var.value, nullptr);
   EXPECT_EQ(var->name(), "my_var");
   EXPECT_NE(var->type(), nullptr);
-  EXPECT_TRUE(var->type()->IsF32());
+  EXPECT_TRUE(var->type()->Is<ast::type::F32Type>());
 
   EXPECT_EQ(var->source().range.begin.line, 1u);
   EXPECT_EQ(var->source().range.begin.column, 5u);
@@ -69,7 +70,7 @@
   EXPECT_FALSE(p->has_error());
   ASSERT_NE(v.value, nullptr);
   EXPECT_EQ(v->name(), "my_var");
-  EXPECT_TRUE(v->type()->IsF32());
+  EXPECT_TRUE(v->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(v->storage_class(), ast::StorageClass::kPrivate);
 
   EXPECT_EQ(v->source().range.begin.line, 1u);
diff --git a/src/reader/wgsl/parser_impl_variable_ident_decl_test.cc b/src/reader/wgsl/parser_impl_variable_ident_decl_test.cc
index 6a6fd74..da48b88 100644
--- a/src/reader/wgsl/parser_impl_variable_ident_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_variable_ident_decl_test.cc
@@ -16,6 +16,7 @@
 #include "src/ast/struct.h"
 #include "src/ast/struct_block_decoration.h"
 #include "src/ast/type/access_control_type.h"
+#include "src/ast/type/f32_type.h"
 #include "src/ast/type/i32_type.h"
 #include "src/ast/type/struct_type.h"
 #include "src/reader/wgsl/parser_impl.h"
@@ -33,7 +34,7 @@
   ASSERT_FALSE(decl.errored);
   ASSERT_EQ(decl->name, "my_var");
   ASSERT_NE(decl->type, nullptr);
-  ASSERT_TRUE(decl->type->IsF32());
+  ASSERT_TRUE(decl->type->Is<ast::type::F32Type>());
 
   ASSERT_EQ(decl->source.range.begin.line, 1u);
   ASSERT_EQ(decl->source.range.begin.column, 1u);
diff --git a/src/type_determiner_test.cc b/src/type_determiner_test.cc
index 9c486ea..5ed83a1 100644
--- a/src/type_determiner_test.cc
+++ b/src/type_determiner_test.cc
@@ -136,7 +136,7 @@
   ASSERT_NE(rhs->result_type(), nullptr);
 
   EXPECT_TRUE(lhs->result_type()->IsI32());
-  EXPECT_TRUE(rhs->result_type()->IsF32());
+  EXPECT_TRUE(rhs->result_type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Stmt_Case) {
@@ -159,7 +159,7 @@
   ASSERT_NE(lhs->result_type(), nullptr);
   ASSERT_NE(rhs->result_type(), nullptr);
   EXPECT_TRUE(lhs->result_type()->IsI32());
-  EXPECT_TRUE(rhs->result_type()->IsF32());
+  EXPECT_TRUE(rhs->result_type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Stmt_Block) {
@@ -178,7 +178,7 @@
   ASSERT_NE(lhs->result_type(), nullptr);
   ASSERT_NE(rhs->result_type(), nullptr);
   EXPECT_TRUE(lhs->result_type()->IsI32());
-  EXPECT_TRUE(rhs->result_type()->IsF32());
+  EXPECT_TRUE(rhs->result_type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Stmt_Else) {
@@ -203,7 +203,7 @@
   ASSERT_NE(rhs->result_type(), nullptr);
   EXPECT_TRUE(stmt.condition()->result_type()->IsI32());
   EXPECT_TRUE(lhs->result_type()->IsI32());
-  EXPECT_TRUE(rhs->result_type()->IsF32());
+  EXPECT_TRUE(rhs->result_type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Stmt_If) {
@@ -247,9 +247,9 @@
   ASSERT_NE(rhs->result_type(), nullptr);
   EXPECT_TRUE(stmt.condition()->result_type()->IsI32());
   EXPECT_TRUE(else_lhs->result_type()->IsI32());
-  EXPECT_TRUE(else_rhs->result_type()->IsF32());
+  EXPECT_TRUE(else_rhs->result_type()->Is<ast::type::F32Type>());
   EXPECT_TRUE(lhs->result_type()->IsI32());
-  EXPECT_TRUE(rhs->result_type()->IsF32());
+  EXPECT_TRUE(rhs->result_type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Stmt_Loop) {
@@ -281,9 +281,9 @@
   ASSERT_NE(continuing_lhs->result_type(), nullptr);
   ASSERT_NE(continuing_rhs->result_type(), nullptr);
   EXPECT_TRUE(body_lhs->result_type()->IsI32());
-  EXPECT_TRUE(body_rhs->result_type()->IsF32());
+  EXPECT_TRUE(body_rhs->result_type()->Is<ast::type::F32Type>());
   EXPECT_TRUE(continuing_lhs->result_type()->IsI32());
-  EXPECT_TRUE(continuing_rhs->result_type()->IsF32());
+  EXPECT_TRUE(continuing_rhs->result_type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Stmt_Return) {
@@ -334,7 +334,7 @@
 
   EXPECT_TRUE(stmt.condition()->result_type()->IsI32());
   EXPECT_TRUE(lhs->result_type()->IsI32());
-  EXPECT_TRUE(rhs->result_type()->IsF32());
+  EXPECT_TRUE(rhs->result_type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Stmt_Call) {
@@ -355,7 +355,7 @@
   ast::CallStatement call(expr);
   EXPECT_TRUE(td()->DetermineResultType(&call));
   ASSERT_NE(expr->result_type(), nullptr);
-  EXPECT_TRUE(expr->result_type()->IsF32());
+  EXPECT_TRUE(expr->result_type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Stmt_Call_undeclared) {
@@ -441,7 +441,7 @@
   ASSERT_TRUE(acc.result_type()->IsPointer());
 
   auto* ptr = acc.result_type()->AsPointer();
-  EXPECT_TRUE(ptr->type()->IsF32());
+  EXPECT_TRUE(ptr->type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Alias_Array) {
@@ -466,7 +466,7 @@
   ASSERT_TRUE(acc.result_type()->IsPointer());
 
   auto* ptr = acc.result_type()->AsPointer();
-  EXPECT_TRUE(ptr->type()->IsF32());
+  EXPECT_TRUE(ptr->type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Array_Constant) {
@@ -488,7 +488,8 @@
                                    idx);
   EXPECT_TRUE(td()->DetermineResultType(&acc));
   ASSERT_NE(acc.result_type(), nullptr);
-  EXPECT_TRUE(acc.result_type()->IsF32()) << acc.result_type()->type_name();
+  EXPECT_TRUE(acc.result_type()->Is<ast::type::F32Type>())
+      << acc.result_type()->type_name();
 }
 
 TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Matrix) {
@@ -540,7 +541,7 @@
   ASSERT_TRUE(acc.result_type()->IsPointer());
 
   auto* ptr = acc.result_type()->AsPointer();
-  EXPECT_TRUE(ptr->type()->IsF32());
+  EXPECT_TRUE(ptr->type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Vector) {
@@ -563,7 +564,7 @@
   ASSERT_TRUE(acc.result_type()->IsPointer());
 
   auto* ptr = acc.result_type()->AsPointer();
-  EXPECT_TRUE(ptr->type()->IsF32());
+  EXPECT_TRUE(ptr->type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Expr_Bitcast) {
@@ -576,7 +577,7 @@
 
   EXPECT_TRUE(td()->DetermineResultType(&bitcast));
   ASSERT_NE(bitcast.result_type(), nullptr);
-  EXPECT_TRUE(bitcast.result_type()->IsF32());
+  EXPECT_TRUE(bitcast.result_type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Expr_Call) {
@@ -595,7 +596,7 @@
                            call_params);
   EXPECT_TRUE(td()->DetermineResultType(&call));
   ASSERT_NE(call.result_type(), nullptr);
-  EXPECT_TRUE(call.result_type()->IsF32());
+  EXPECT_TRUE(call.result_type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Expr_Call_WithParams) {
@@ -619,7 +620,7 @@
                            call_params);
   EXPECT_TRUE(td()->DetermineResultType(&call));
   ASSERT_NE(param->result_type(), nullptr);
-  EXPECT_TRUE(param->result_type()->IsF32());
+  EXPECT_TRUE(param->result_type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Expr_Call_Intrinsic) {
@@ -637,7 +638,7 @@
 
   EXPECT_TRUE(td()->DetermineResultType(&call));
   ASSERT_NE(call.result_type(), nullptr);
-  EXPECT_TRUE(call.result_type()->IsF32());
+  EXPECT_TRUE(call.result_type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Expr_Cast) {
@@ -652,7 +653,7 @@
 
   EXPECT_TRUE(td()->DetermineResultType(&cast));
   ASSERT_NE(cast.result_type(), nullptr);
-  EXPECT_TRUE(cast.result_type()->IsF32());
+  EXPECT_TRUE(cast.result_type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Expr_Constructor_Scalar) {
@@ -661,7 +662,7 @@
 
   EXPECT_TRUE(td()->DetermineResultType(&s));
   ASSERT_NE(s.result_type(), nullptr);
-  EXPECT_TRUE(s.result_type()->IsF32());
+  EXPECT_TRUE(s.result_type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Expr_Constructor_Type) {
@@ -681,7 +682,7 @@
   EXPECT_TRUE(td()->DetermineResultType(&tc));
   ASSERT_NE(tc.result_type(), nullptr);
   ASSERT_TRUE(tc.result_type()->IsVector());
-  EXPECT_TRUE(tc.result_type()->AsVector()->type()->IsF32());
+  EXPECT_TRUE(tc.result_type()->AsVector()->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(tc.result_type()->AsVector()->size(), 3u);
 }
 
@@ -697,7 +698,8 @@
   EXPECT_TRUE(td()->DetermineResultType(&ident));
   ASSERT_NE(ident.result_type(), nullptr);
   EXPECT_TRUE(ident.result_type()->IsPointer());
-  EXPECT_TRUE(ident.result_type()->AsPointer()->type()->IsF32());
+  EXPECT_TRUE(
+      ident.result_type()->AsPointer()->type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Expr_Identifier_GlobalConstant) {
@@ -712,7 +714,7 @@
   ast::IdentifierExpression ident("my_var");
   EXPECT_TRUE(td()->DetermineResultType(&ident));
   ASSERT_NE(ident.result_type(), nullptr);
-  EXPECT_TRUE(ident.result_type()->IsF32());
+  EXPECT_TRUE(ident.result_type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Expr_Identifier_FunctionVariable_Const) {
@@ -733,7 +735,7 @@
   EXPECT_TRUE(td()->DetermineFunction(&f));
 
   ASSERT_NE(my_var->result_type(), nullptr);
-  EXPECT_TRUE(my_var->result_type()->IsF32());
+  EXPECT_TRUE(my_var->result_type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Expr_Identifier_FunctionVariable) {
@@ -754,7 +756,8 @@
 
   ASSERT_NE(my_var->result_type(), nullptr);
   EXPECT_TRUE(my_var->result_type()->IsPointer());
-  EXPECT_TRUE(my_var->result_type()->AsPointer()->type()->IsF32());
+  EXPECT_TRUE(
+      my_var->result_type()->AsPointer()->type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Expr_Identifier_Function_Ptr) {
@@ -776,7 +779,8 @@
 
   ASSERT_NE(my_var->result_type(), nullptr);
   EXPECT_TRUE(my_var->result_type()->IsPointer());
-  EXPECT_TRUE(my_var->result_type()->AsPointer()->type()->IsF32());
+  EXPECT_TRUE(
+      my_var->result_type()->AsPointer()->type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Expr_Identifier_Function) {
@@ -793,7 +797,7 @@
   ast::IdentifierExpression ident("my_func");
   EXPECT_TRUE(td()->DetermineResultType(&ident));
   ASSERT_NE(ident.result_type(), nullptr);
-  EXPECT_TRUE(ident.result_type()->IsF32());
+  EXPECT_TRUE(ident.result_type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Expr_Identifier_Unknown) {
@@ -966,7 +970,7 @@
   ASSERT_TRUE(mem.result_type()->IsPointer());
 
   auto* ptr = mem.result_type()->AsPointer();
-  EXPECT_TRUE(ptr->type()->IsF32());
+  EXPECT_TRUE(ptr->type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Expr_MemberAccessor_Struct_Alias) {
@@ -1000,7 +1004,7 @@
   ASSERT_TRUE(mem.result_type()->IsPointer());
 
   auto* ptr = mem.result_type()->AsPointer();
-  EXPECT_TRUE(ptr->type()->IsF32());
+  EXPECT_TRUE(ptr->type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Expr_MemberAccessor_VectorSwizzle) {
@@ -1020,7 +1024,7 @@
   EXPECT_TRUE(td()->DetermineResultType(&mem)) << td()->error();
   ASSERT_NE(mem.result_type(), nullptr);
   ASSERT_TRUE(mem.result_type()->IsVector());
-  EXPECT_TRUE(mem.result_type()->AsVector()->type()->IsF32());
+  EXPECT_TRUE(mem.result_type()->AsVector()->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(mem.result_type()->AsVector()->size(), 2u);
 }
 
@@ -1043,7 +1047,7 @@
   ASSERT_TRUE(mem.result_type()->IsPointer());
 
   auto* ptr = mem.result_type()->AsPointer();
-  ASSERT_TRUE(ptr->type()->IsF32());
+  ASSERT_TRUE(ptr->type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Expr_Accessor_MultiLevel) {
@@ -1115,7 +1119,7 @@
 
   ASSERT_NE(mem.result_type(), nullptr);
   ASSERT_TRUE(mem.result_type()->IsVector());
-  EXPECT_TRUE(mem.result_type()->AsVector()->type()->IsF32());
+  EXPECT_TRUE(mem.result_type()->AsVector()->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(mem.result_type()->AsVector()->size(), 2u);
 }
 
@@ -1310,7 +1314,7 @@
   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()->IsF32());
+  EXPECT_TRUE(expr.result_type()->AsVector()->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(expr.result_type()->AsVector()->size(), 3u);
 }
 
@@ -1335,7 +1339,7 @@
   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()->IsF32());
+  EXPECT_TRUE(expr.result_type()->AsVector()->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(expr.result_type()->AsVector()->size(), 3u);
 }
 
@@ -1357,7 +1361,7 @@
   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()->IsF32());
+  EXPECT_TRUE(expr.result_type()->AsVector()->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(expr.result_type()->AsVector()->size(), 3u);
 }
 
@@ -1384,7 +1388,7 @@
   ASSERT_TRUE(expr.result_type()->IsMatrix());
 
   auto* mat = expr.result_type()->AsMatrix();
-  EXPECT_TRUE(mat->type()->IsF32());
+  EXPECT_TRUE(mat->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(mat->rows(), 3u);
   EXPECT_EQ(mat->columns(), 2u);
 }
@@ -1412,7 +1416,7 @@
   ASSERT_TRUE(expr.result_type()->IsMatrix());
 
   auto* mat = expr.result_type()->AsMatrix();
-  EXPECT_TRUE(mat->type()->IsF32());
+  EXPECT_TRUE(mat->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(mat->rows(), 3u);
   EXPECT_EQ(mat->columns(), 2u);
 }
@@ -1439,7 +1443,7 @@
   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()->IsF32());
+  EXPECT_TRUE(expr.result_type()->AsVector()->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(expr.result_type()->AsVector()->size(), 3u);
 }
 
@@ -1465,7 +1469,7 @@
   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()->IsF32());
+  EXPECT_TRUE(expr.result_type()->AsVector()->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(expr.result_type()->AsVector()->size(), 2u);
 }
 
@@ -1493,7 +1497,7 @@
   ASSERT_TRUE(expr.result_type()->IsMatrix());
 
   auto* mat = expr.result_type()->AsMatrix();
-  EXPECT_TRUE(mat->type()->IsF32());
+  EXPECT_TRUE(mat->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(mat->rows(), 4u);
   EXPECT_EQ(mat->columns(), 4u);
 }
@@ -1518,7 +1522,7 @@
   EXPECT_TRUE(td()->DetermineResultType(&expr));
 
   ASSERT_NE(expr.result_type(), nullptr);
-  ASSERT_TRUE(expr.result_type()->IsF32());
+  ASSERT_TRUE(expr.result_type()->Is<ast::type::F32Type>());
 }
 
 TEST_P(IntrinsicDerivativeTest, Vector) {
@@ -1542,7 +1546,7 @@
 
   ASSERT_NE(expr.result_type(), nullptr);
   ASSERT_TRUE(expr.result_type()->IsVector());
-  EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsF32());
+  EXPECT_TRUE(expr.result_type()->AsVector()->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(expr.result_type()->AsVector()->size(), 4u);
 }
 
@@ -1807,7 +1811,8 @@
   ASSERT_NE(expr.result_type(), nullptr);
   ASSERT_TRUE(expr.result_type()->IsVector());
   if (type == TextureType::kF32) {
-    EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsF32());
+    EXPECT_TRUE(
+        expr.result_type()->AsVector()->type()->Is<ast::type::F32Type>());
   } else if (type == TextureType::kI32) {
     EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsI32());
   } else {
@@ -1877,7 +1882,8 @@
   ASSERT_NE(expr.result_type(), nullptr);
   ASSERT_TRUE(expr.result_type()->IsVector());
   if (type == TextureType::kF32) {
-    EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsF32());
+    EXPECT_TRUE(
+        expr.result_type()->AsVector()->type()->Is<ast::type::F32Type>());
   } else if (type == TextureType::kI32) {
     EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsI32());
   } else {
@@ -1913,7 +1919,7 @@
   EXPECT_TRUE(td()->Determine());
   EXPECT_TRUE(td()->DetermineResultType(&expr));
   ASSERT_NE(expr.result_type(), nullptr);
-  EXPECT_TRUE(expr.result_type()->IsF32());
+  EXPECT_TRUE(expr.result_type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Intrinsic_Select) {
@@ -1942,7 +1948,7 @@
   ASSERT_NE(expr.result_type(), nullptr);
   EXPECT_TRUE(expr.result_type()->IsVector());
   EXPECT_EQ(expr.result_type()->AsVector()->size(), 3u);
-  EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsF32());
+  EXPECT_TRUE(expr.result_type()->AsVector()->type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, Intrinsic_Select_TooFewParams) {
@@ -2013,7 +2019,7 @@
   ASSERT_TRUE(expr.result_type()->IsMatrix());
 
   auto* mat = expr.result_type()->AsMatrix();
-  EXPECT_TRUE(mat->type()->IsF32());
+  EXPECT_TRUE(mat->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(mat->rows(), 3u);
   EXPECT_EQ(mat->columns(), 2u);
 }
@@ -2078,7 +2084,7 @@
   EXPECT_TRUE(td()->DetermineResultType(&der));
   ASSERT_NE(der.result_type(), nullptr);
   ASSERT_TRUE(der.result_type()->IsVector());
-  EXPECT_TRUE(der.result_type()->AsVector()->type()->IsF32());
+  EXPECT_TRUE(der.result_type()->AsVector()->type()->Is<ast::type::F32Type>());
   EXPECT_EQ(der.result_type()->AsVector()->size(), 4u);
 }
 INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
@@ -2880,7 +2886,7 @@
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
   ASSERT_NE(ident->result_type(), nullptr);
-  EXPECT_TRUE(ident->result_type()->IsF32());
+  EXPECT_TRUE(ident->result_type()->Is<ast::type::F32Type>());
 }
 
 TEST_F(TypeDeterminerTest, ImportData_Distance_Error_Integer) {
@@ -3928,7 +3934,7 @@
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
   ASSERT_NE(ident->result_type(), nullptr);
-  EXPECT_TRUE(ident->result_type()->IsF32());
+  EXPECT_TRUE(ident->result_type()->Is<ast::type::F32Type>());
 }
 
 TEST_P(ImportData_FloatOrInt_TwoParamTest, Vector_Signed) {
@@ -4193,7 +4199,7 @@
 
   EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error();
   ASSERT_NE(ident->result_type(), nullptr);
-  EXPECT_TRUE(ident->result_type()->IsF32());
+  EXPECT_TRUE(ident->result_type()->Is<ast::type::F32Type>());
 }
 
 using ImportData_Matrix_OneParam_Test =
diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc
index e39d5ee..5528b3f 100644
--- a/src/writer/hlsl/generator_impl.cc
+++ b/src/writer/hlsl/generator_impl.cc
@@ -265,7 +265,7 @@
 bool GeneratorImpl::EmitBitcast(std::ostream& pre,
                                 std::ostream& out,
                                 ast::BitcastExpression* expr) {
-  if (!expr->type()->IsF32() && !expr->type()->IsI32() &&
+  if (!expr->type()->Is<ast::type::F32Type>() && !expr->type()->IsI32() &&
       !expr->type()->IsU32()) {
     error_ = "Unable to do bitcast to type " + expr->type()->type_name();
     return false;
@@ -1545,7 +1545,7 @@
 bool GeneratorImpl::EmitZeroValue(std::ostream& out, ast::type::Type* type) {
   if (type->Is<ast::type::BoolType>()) {
     out << "false";
-  } else if (type->IsF32()) {
+  } else if (type->Is<ast::type::F32Type>()) {
     out << "0.0f";
   } else if (type->IsI32()) {
     out << "0";
@@ -2060,7 +2060,7 @@
     }
   } else if (type->Is<ast::type::BoolType>()) {
     out << "bool";
-  } else if (type->IsF32()) {
+  } else if (type->Is<ast::type::F32Type>()) {
     out << "float";
   } else if (type->IsI32()) {
     out << "int";
@@ -2123,7 +2123,7 @@
   } else if (type->IsVector()) {
     auto* vec = type->AsVector();
     auto size = vec->size();
-    if (vec->type()->IsF32() && size >= 1 && size <= 4) {
+    if (vec->type()->Is<ast::type::F32Type>() && size >= 1 && size <= 4) {
       out << "float" << size;
     } else if (vec->type()->IsI32() && size >= 1 && size <= 4) {
       out << "int" << size;
diff --git a/src/writer/msl/generator_impl.cc b/src/writer/msl/generator_impl.cc
index 0d8830e..d1d5fa4 100644
--- a/src/writer/msl/generator_impl.cc
+++ b/src/writer/msl/generator_impl.cc
@@ -200,7 +200,7 @@
   if (type->IsPointer()) {
     return 0;
   }
-  if (type->IsF32() || type->IsI32() || type->IsU32()) {
+  if (type->Is<ast::type::F32Type>() || type->IsI32() || type->IsU32()) {
     return 4;
   }
   if (type->IsMatrix()) {
@@ -793,7 +793,7 @@
       out += ident->name();
       break;
     case ast::Intrinsic::kAbs:
-      if (ident->result_type()->IsF32()) {
+      if (ident->result_type()->Is<ast::type::F32Type>()) {
         out += "fabs";
       } else if (ident->result_type()->IsU32() ||
                  ident->result_type()->IsI32()) {
@@ -801,7 +801,7 @@
       }
       break;
     case ast::Intrinsic::kMax:
-      if (ident->result_type()->IsF32()) {
+      if (ident->result_type()->Is<ast::type::F32Type>()) {
         out += "fmax";
       } else if (ident->result_type()->IsU32() ||
                  ident->result_type()->IsI32()) {
@@ -809,7 +809,7 @@
       }
       break;
     case ast::Intrinsic::kMin:
-      if (ident->result_type()->IsF32()) {
+      if (ident->result_type()->Is<ast::type::F32Type>()) {
         out += "fmin";
       } else if (ident->result_type()->IsU32() ||
                  ident->result_type()->IsI32()) {
@@ -930,7 +930,7 @@
 bool GeneratorImpl::EmitZeroValue(ast::type::Type* type) {
   if (type->Is<ast::type::BoolType>()) {
     out_ << "false";
-  } else if (type->IsF32()) {
+  } else if (type->Is<ast::type::F32Type>()) {
     out_ << "0.0f";
   } else if (type->IsI32()) {
     out_ << "0";
@@ -1814,7 +1814,7 @@
     }
   } else if (type->Is<ast::type::BoolType>()) {
     out_ << "bool";
-  } else if (type->IsF32()) {
+  } else if (type->Is<ast::type::F32Type>()) {
     out_ << "float";
   } else if (type->IsI32()) {
     out_ << "int";
diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc
index c640f84..d447be4 100644
--- a/src/writer/spirv/builder.cc
+++ b/src/writer/spirv/builder.cc
@@ -742,7 +742,7 @@
     // 2- If we don't have a constructor and we're an Output or Private variable
     //    then WGSL requires an initializer.
     if (var->IsDecorated() && var->AsDecorated()->HasConstantIdDecoration()) {
-      if (type->IsF32()) {
+      if (type->Is<ast::type::F32Type>()) {
         ast::FloatLiteral l(type, 0.0f);
         init_id = GenerateLiteralIfNeeded(var, &l);
       } else if (type->IsU32()) {
@@ -1393,18 +1393,18 @@
   auto* from_type = from_expr->result_type()->UnwrapPtrIfNeeded();
 
   spv::Op op = spv::Op::OpNop;
-  if ((from_type->IsI32() && to_type->IsF32()) ||
+  if ((from_type->IsI32() && to_type->Is<ast::type::F32Type>()) ||
       (from_type->is_signed_integer_vector() && to_type->is_float_vector())) {
     op = spv::Op::OpConvertSToF;
-  } else if ((from_type->IsU32() && to_type->IsF32()) ||
+  } else if ((from_type->IsU32() && to_type->Is<ast::type::F32Type>()) ||
              (from_type->is_unsigned_integer_vector() &&
               to_type->is_float_vector())) {
     op = spv::Op::OpConvertUToF;
-  } else if ((from_type->IsF32() && to_type->IsI32()) ||
+  } else if ((from_type->Is<ast::type::F32Type>() && to_type->IsI32()) ||
              (from_type->is_float_vector() &&
               to_type->is_signed_integer_vector())) {
     op = spv::Op::OpConvertFToS;
-  } else if ((from_type->IsF32() && to_type->IsU32()) ||
+  } else if ((from_type->Is<ast::type::F32Type>() && to_type->IsU32()) ||
              (from_type->is_float_vector() &&
               to_type->is_unsigned_integer_vector())) {
     op = spv::Op::OpConvertFToU;
@@ -1412,7 +1412,8 @@
               to_type->Is<ast::type::BoolType>()) ||
              (from_type->IsU32() && to_type->IsU32()) ||
              (from_type->IsI32() && to_type->IsI32()) ||
-             (from_type->IsF32() && to_type->IsF32()) ||
+             (from_type->Is<ast::type::F32Type>() &&
+              to_type->Is<ast::type::F32Type>()) ||
              (from_type->IsVector() && (from_type == to_type))) {
     return val_id;
   } else if ((from_type->IsI32() && to_type->IsU32()) ||
@@ -2418,7 +2419,7 @@
     }
   } else if (type->Is<ast::type::BoolType>()) {
     push_type(spv::Op::OpTypeBool, {result});
-  } else if (type->IsF32()) {
+  } else if (type->Is<ast::type::F32Type>()) {
     push_type(spv::Op::OpTypeFloat, {result, Operand::Int(32)});
   } else if (type->IsI32()) {
     push_type(spv::Op::OpTypeInt, {result, Operand::Int(32), Operand::Int(1)});
@@ -2685,7 +2686,7 @@
       push_annot(spv::Op::OpMemberDecorate,
                  {Operand::Int(struct_id), Operand::Int(idx),
                   Operand::Int(SpvDecorationColMajor)});
-      if (!matrix_type->type()->IsF32()) {
+      if (!matrix_type->type()->Is<ast::type::F32Type>()) {
         error_ = "matrix scalar element type must be f32";
         return 0;
       }
diff --git a/src/writer/wgsl/generator_impl.cc b/src/writer/wgsl/generator_impl.cc
index 00aaa68..706c9f0 100644
--- a/src/writer/wgsl/generator_impl.cc
+++ b/src/writer/wgsl/generator_impl.cc
@@ -54,6 +54,7 @@
 #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"
 #include "src/ast/type/depth_texture_type.h"
 #include "src/ast/type/matrix_type.h"
 #include "src/ast/type/multisampled_texture_type.h"
@@ -433,7 +434,7 @@
     out_ << ">";
   } else if (type->Is<ast::type::BoolType>()) {
     out_ << "bool";
-  } else if (type->IsF32()) {
+  } else if (type->Is<ast::type::F32Type>()) {
     out_ << "f32";
   } else if (type->IsI32()) {
     out_ << "i32";