writer/spirv tests: Replace std::make_unique<T> -> create<T>

create() is currently just a simple forwarder to std::make_unique<>, but
will be later replaced with a function that returns a raw pointer,
and owned by the context.

Bug: tint:322
Change-Id: I5321553847b6a7d47ac211ba093d219c7f3bb9bd
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/32673
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/writer/spirv/builder_accessor_expression_test.cc b/src/writer/spirv/builder_accessor_expression_test.cc
index 4f2dde6..f0e5b0b 100644
--- a/src/writer/spirv/builder_accessor_expression_test.cc
+++ b/src/writer/spirv/builder_accessor_expression_test.cc
@@ -56,9 +56,9 @@
 
   ast::Variable var("ary", ast::StorageClass::kFunction, &vec3);
 
-  auto ary = std::make_unique<ast::IdentifierExpression>("ary");
-  auto idx_expr = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 1));
+  auto ary = create<ast::IdentifierExpression>("ary");
+  auto idx_expr = create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 1));
 
   ast::ArrayAccessorExpression expr(std::move(ary), std::move(idx_expr));
 
@@ -98,8 +98,8 @@
   ast::Variable var("ary", ast::StorageClass::kFunction, &vec3);
   ast::Variable idx("idx", ast::StorageClass::kFunction, &i32);
 
-  auto ary = std::make_unique<ast::IdentifierExpression>("ary");
-  auto idx_expr = std::make_unique<ast::IdentifierExpression>("idx");
+  auto ary = create<ast::IdentifierExpression>("ary");
+  auto idx_expr = create<ast::IdentifierExpression>("idx");
 
   ast::ArrayAccessorExpression expr(std::move(ary), std::move(idx_expr));
 
@@ -142,15 +142,15 @@
 
   ast::Variable var("ary", ast::StorageClass::kFunction, &vec3);
 
-  auto ary = std::make_unique<ast::IdentifierExpression>("ary");
+  auto ary = create<ast::IdentifierExpression>("ary");
 
   ast::ArrayAccessorExpression expr(
-      std::move(ary), std::make_unique<ast::BinaryExpression>(
-                          ast::BinaryOp::kAdd,
-                          std::make_unique<ast::ScalarConstructorExpression>(
-                              std::make_unique<ast::SintLiteral>(&i32, 1)),
-                          std::make_unique<ast::ScalarConstructorExpression>(
-                              std::make_unique<ast::SintLiteral>(&i32, 2))));
+      std::move(ary),
+      create<ast::BinaryExpression>(ast::BinaryOp::kAdd,
+                                    create<ast::ScalarConstructorExpression>(
+                                        create<ast::SintLiteral>(&i32, 1)),
+                                    create<ast::ScalarConstructorExpression>(
+                                        create<ast::SintLiteral>(&i32, 2))));
 
   td.RegisterVariableForTesting(&var);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
@@ -190,12 +190,12 @@
   ast::Variable var("ary", ast::StorageClass::kFunction, &ary4);
 
   ast::ArrayAccessorExpression expr(
-      std::make_unique<ast::ArrayAccessorExpression>(
-          std::make_unique<ast::IdentifierExpression>("ary"),
-          std::make_unique<ast::ScalarConstructorExpression>(
-              std::make_unique<ast::SintLiteral>(&i32, 3))),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 2)));
+      create<ast::ArrayAccessorExpression>(
+          create<ast::IdentifierExpression>("ary"),
+          create<ast::ScalarConstructorExpression>(
+              create<ast::SintLiteral>(&i32, 3))),
+      create<ast::ScalarConstructorExpression>(
+          create<ast::SintLiteral>(&i32, 2)));
 
   td.RegisterVariableForTesting(&var);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
@@ -237,11 +237,11 @@
   ast::Variable var("ary", ast::StorageClass::kFunction, &ary4);
 
   ast::MemberAccessorExpression expr(
-      std::make_unique<ast::ArrayAccessorExpression>(
-          std::make_unique<ast::IdentifierExpression>("ary"),
-          std::make_unique<ast::ScalarConstructorExpression>(
-              std::make_unique<ast::SintLiteral>(&i32, 2))),
-      std::make_unique<ast::IdentifierExpression>("xy"));
+      create<ast::ArrayAccessorExpression>(
+          create<ast::IdentifierExpression>("ary"),
+          create<ast::ScalarConstructorExpression>(
+              create<ast::SintLiteral>(&i32, 2))),
+      create<ast::IdentifierExpression>("xy"));
 
   td.RegisterVariableForTesting(&var);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
@@ -284,19 +284,16 @@
 
   ast::StructMemberDecorationList decos;
   ast::StructMemberList members;
-  members.push_back(
-      std::make_unique<ast::StructMember>("a", &f32, std::move(decos)));
-  members.push_back(
-      std::make_unique<ast::StructMember>("b", &f32, std::move(decos)));
+  members.push_back(create<ast::StructMember>("a", &f32, std::move(decos)));
+  members.push_back(create<ast::StructMember>("b", &f32, std::move(decos)));
 
-  auto s = std::make_unique<ast::Struct>(std::move(members));
+  auto s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("my_struct", std::move(s));
 
   ast::Variable var("ident", ast::StorageClass::kFunction, &s_type);
 
-  ast::MemberAccessorExpression expr(
-      std::make_unique<ast::IdentifierExpression>("ident"),
-      std::make_unique<ast::IdentifierExpression>("b"));
+  ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("ident"),
+                                     create<ast::IdentifierExpression>("b"));
 
   td.RegisterVariableForTesting(&var);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
@@ -337,27 +334,27 @@
   ast::StructMemberDecorationList decos;
   ast::StructMemberList inner_members;
   inner_members.push_back(
-      std::make_unique<ast::StructMember>("a", &f32, std::move(decos)));
+      create<ast::StructMember>("a", &f32, std::move(decos)));
   inner_members.push_back(
-      std::make_unique<ast::StructMember>("b", &f32, std::move(decos)));
+      create<ast::StructMember>("b", &f32, std::move(decos)));
 
   ast::type::StructType inner_struct(
-      "Inner", std::make_unique<ast::Struct>(std::move(inner_members)));
+      "Inner", create<ast::Struct>(std::move(inner_members)));
 
   ast::StructMemberList outer_members;
-  outer_members.push_back(std::make_unique<ast::StructMember>(
-      "inner", &inner_struct, std::move(decos)));
+  outer_members.push_back(
+      create<ast::StructMember>("inner", &inner_struct, std::move(decos)));
 
-  ast::type::StructType s_type(
-      "my_struct", std::make_unique<ast::Struct>(std::move(outer_members)));
+  ast::type::StructType s_type("my_struct",
+                               create<ast::Struct>(std::move(outer_members)));
 
   ast::Variable var("ident", ast::StorageClass::kFunction, &s_type);
 
   ast::MemberAccessorExpression expr(
-      std::make_unique<ast::MemberAccessorExpression>(
-          std::make_unique<ast::IdentifierExpression>("ident"),
-          std::make_unique<ast::IdentifierExpression>("inner")),
-      std::make_unique<ast::IdentifierExpression>("a"));
+      create<ast::MemberAccessorExpression>(
+          create<ast::IdentifierExpression>("ident"),
+          create<ast::IdentifierExpression>("inner")),
+      create<ast::IdentifierExpression>("a"));
 
   td.RegisterVariableForTesting(&var);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
@@ -400,29 +397,29 @@
   ast::StructMemberDecorationList decos;
   ast::StructMemberList inner_members;
   inner_members.push_back(
-      std::make_unique<ast::StructMember>("a", &f32, std::move(decos)));
+      create<ast::StructMember>("a", &f32, std::move(decos)));
   inner_members.push_back(
-      std::make_unique<ast::StructMember>("b", &f32, std::move(decos)));
+      create<ast::StructMember>("b", &f32, std::move(decos)));
 
   ast::type::StructType inner_struct(
-      "Inner", std::make_unique<ast::Struct>(std::move(inner_members)));
+      "Inner", create<ast::Struct>(std::move(inner_members)));
 
   ast::type::AliasType alias("Inner", &inner_struct);
 
   ast::StructMemberList outer_members;
   outer_members.push_back(
-      std::make_unique<ast::StructMember>("inner", &alias, std::move(decos)));
+      create<ast::StructMember>("inner", &alias, std::move(decos)));
 
-  ast::type::StructType s_type(
-      "Outer", std::make_unique<ast::Struct>(std::move(outer_members)));
+  ast::type::StructType s_type("Outer",
+                               create<ast::Struct>(std::move(outer_members)));
 
   ast::Variable var("ident", ast::StorageClass::kFunction, &s_type);
 
   ast::MemberAccessorExpression expr(
-      std::make_unique<ast::MemberAccessorExpression>(
-          std::make_unique<ast::IdentifierExpression>("ident"),
-          std::make_unique<ast::IdentifierExpression>("inner")),
-      std::make_unique<ast::IdentifierExpression>("a"));
+      create<ast::MemberAccessorExpression>(
+          create<ast::IdentifierExpression>("ident"),
+          create<ast::IdentifierExpression>("inner")),
+      create<ast::IdentifierExpression>("a"));
 
   td.RegisterVariableForTesting(&var);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
@@ -465,30 +462,30 @@
   ast::StructMemberDecorationList decos;
   ast::StructMemberList inner_members;
   inner_members.push_back(
-      std::make_unique<ast::StructMember>("a", &f32, std::move(decos)));
+      create<ast::StructMember>("a", &f32, std::move(decos)));
   inner_members.push_back(
-      std::make_unique<ast::StructMember>("b", &f32, std::move(decos)));
+      create<ast::StructMember>("b", &f32, std::move(decos)));
 
   ast::type::StructType inner_struct(
-      "Inner", std::make_unique<ast::Struct>(std::move(inner_members)));
+      "Inner", create<ast::Struct>(std::move(inner_members)));
 
   ast::StructMemberList outer_members;
-  outer_members.push_back(std::make_unique<ast::StructMember>(
-      "inner", &inner_struct, std::move(decos)));
+  outer_members.push_back(
+      create<ast::StructMember>("inner", &inner_struct, std::move(decos)));
 
-  ast::type::StructType s_type(
-      "my_struct", std::make_unique<ast::Struct>(std::move(outer_members)));
+  ast::type::StructType s_type("my_struct",
+                               create<ast::Struct>(std::move(outer_members)));
 
   ast::Variable var("ident", ast::StorageClass::kFunction, &s_type);
 
-  auto lhs = std::make_unique<ast::MemberAccessorExpression>(
-      std::make_unique<ast::MemberAccessorExpression>(
-          std::make_unique<ast::IdentifierExpression>("ident"),
-          std::make_unique<ast::IdentifierExpression>("inner")),
-      std::make_unique<ast::IdentifierExpression>("a"));
+  auto lhs = create<ast::MemberAccessorExpression>(
+      create<ast::MemberAccessorExpression>(
+          create<ast::IdentifierExpression>("ident"),
+          create<ast::IdentifierExpression>("inner")),
+      create<ast::IdentifierExpression>("a"));
 
-  auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.f));
+  auto rhs = create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.f));
 
   ast::AssignmentStatement expr(std::move(lhs), std::move(rhs));
 
@@ -535,30 +532,30 @@
   ast::StructMemberDecorationList decos;
   ast::StructMemberList inner_members;
   inner_members.push_back(
-      std::make_unique<ast::StructMember>("a", &f32, std::move(decos)));
+      create<ast::StructMember>("a", &f32, std::move(decos)));
   inner_members.push_back(
-      std::make_unique<ast::StructMember>("b", &f32, std::move(decos)));
+      create<ast::StructMember>("b", &f32, std::move(decos)));
 
   ast::type::StructType inner_struct(
-      "Inner", std::make_unique<ast::Struct>(std::move(inner_members)));
+      "Inner", create<ast::Struct>(std::move(inner_members)));
 
   ast::StructMemberList outer_members;
-  outer_members.push_back(std::make_unique<ast::StructMember>(
-      "inner", &inner_struct, std::move(decos)));
+  outer_members.push_back(
+      create<ast::StructMember>("inner", &inner_struct, std::move(decos)));
 
-  ast::type::StructType s_type(
-      "my_struct", std::make_unique<ast::Struct>(std::move(outer_members)));
+  ast::type::StructType s_type("my_struct",
+                               create<ast::Struct>(std::move(outer_members)));
 
   ast::Variable var("ident", ast::StorageClass::kFunction, &s_type);
   ast::Variable store("store", ast::StorageClass::kFunction, &f32);
 
-  auto lhs = std::make_unique<ast::IdentifierExpression>("store");
+  auto lhs = create<ast::IdentifierExpression>("store");
 
-  auto rhs = std::make_unique<ast::MemberAccessorExpression>(
-      std::make_unique<ast::MemberAccessorExpression>(
-          std::make_unique<ast::IdentifierExpression>("ident"),
-          std::make_unique<ast::IdentifierExpression>("inner")),
-      std::make_unique<ast::IdentifierExpression>("a"));
+  auto rhs = create<ast::MemberAccessorExpression>(
+      create<ast::MemberAccessorExpression>(
+          create<ast::IdentifierExpression>("ident"),
+          create<ast::IdentifierExpression>("inner")),
+      create<ast::IdentifierExpression>("a"));
 
   ast::AssignmentStatement expr(std::move(lhs), std::move(rhs));
 
@@ -601,9 +598,8 @@
 
   ast::Variable var("ident", ast::StorageClass::kFunction, &vec3);
 
-  ast::MemberAccessorExpression expr(
-      std::make_unique<ast::IdentifierExpression>("ident"),
-      std::make_unique<ast::IdentifierExpression>("y"));
+  ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("ident"),
+                                     create<ast::IdentifierExpression>("y"));
 
   td.RegisterVariableForTesting(&var);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
@@ -637,9 +633,8 @@
 
   ast::Variable var("ident", ast::StorageClass::kFunction, &vec3);
 
-  ast::MemberAccessorExpression expr(
-      std::make_unique<ast::IdentifierExpression>("ident"),
-      std::make_unique<ast::IdentifierExpression>("yx"));
+  ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("ident"),
+                                     create<ast::IdentifierExpression>("yx"));
 
   td.RegisterVariableForTesting(&var);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
@@ -673,10 +668,10 @@
   ast::Variable var("ident", ast::StorageClass::kFunction, &vec3);
 
   ast::MemberAccessorExpression expr(
-      std::make_unique<ast::MemberAccessorExpression>(
-          std::make_unique<ast::IdentifierExpression>("ident"),
-          std::make_unique<ast::IdentifierExpression>("yxz")),
-      std::make_unique<ast::IdentifierExpression>("xz"));
+      create<ast::MemberAccessorExpression>(
+          create<ast::IdentifierExpression>("ident"),
+          create<ast::IdentifierExpression>("yxz")),
+      create<ast::IdentifierExpression>("xz"));
 
   td.RegisterVariableForTesting(&var);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
@@ -711,10 +706,10 @@
   ast::Variable var("ident", ast::StorageClass::kFunction, &vec3);
 
   ast::MemberAccessorExpression expr(
-      std::make_unique<ast::MemberAccessorExpression>(
-          std::make_unique<ast::IdentifierExpression>("ident"),
-          std::make_unique<ast::IdentifierExpression>("yxz")),
-      std::make_unique<ast::IdentifierExpression>("x"));
+      create<ast::MemberAccessorExpression>(
+          create<ast::IdentifierExpression>("ident"),
+          create<ast::IdentifierExpression>("yxz")),
+      create<ast::IdentifierExpression>("x"));
 
   td.RegisterVariableForTesting(&var);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
@@ -749,11 +744,11 @@
   ast::Variable var("ident", ast::StorageClass::kFunction, &vec3);
 
   ast::ArrayAccessorExpression expr(
-      std::make_unique<ast::MemberAccessorExpression>(
-          std::make_unique<ast::IdentifierExpression>("ident"),
-          std::make_unique<ast::IdentifierExpression>("yxz")),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 1)));
+      create<ast::MemberAccessorExpression>(
+          create<ast::IdentifierExpression>("ident"),
+          create<ast::IdentifierExpression>("yxz")),
+      create<ast::ScalarConstructorExpression>(
+          create<ast::SintLiteral>(&i32, 1)));
 
   td.RegisterVariableForTesting(&var);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
@@ -799,21 +794,20 @@
 
   ast::StructMemberDecorationList decos;
   ast::StructMemberList members;
-  members.push_back(
-      std::make_unique<ast::StructMember>("baz", &vec3, std::move(decos)));
-  auto s = std::make_unique<ast::Struct>(std::move(members));
+  members.push_back(create<ast::StructMember>("baz", &vec3, std::move(decos)));
+  auto s = create<ast::Struct>(std::move(members));
   ast::type::StructType c_type("C", std::move(s));
 
   members.push_back(
-      std::make_unique<ast::StructMember>("bar", &c_type, std::move(decos)));
-  s = std::make_unique<ast::Struct>(std::move(members));
+      create<ast::StructMember>("bar", &c_type, std::move(decos)));
+  s = create<ast::Struct>(std::move(members));
   ast::type::StructType b_type("B", std::move(s));
 
   ast::type::ArrayType b_ary_type(&b_type, 3);
 
-  members.push_back(std::make_unique<ast::StructMember>("foo", &b_ary_type,
-                                                        std::move(decos)));
-  s = std::make_unique<ast::Struct>(std::move(members));
+  members.push_back(
+      create<ast::StructMember>("foo", &b_ary_type, std::move(decos)));
+  s = create<ast::Struct>(std::move(members));
   ast::type::StructType a_type("A", std::move(s));
 
   ast::type::ArrayType a_ary_type(&a_type, 2);
@@ -821,20 +815,20 @@
   ast::Variable var("index", ast::StorageClass::kFunction, &a_ary_type);
 
   ast::MemberAccessorExpression expr(
-      std::make_unique<ast::MemberAccessorExpression>(
-          std::make_unique<ast::MemberAccessorExpression>(
-              std::make_unique<ast::ArrayAccessorExpression>(
-                  std::make_unique<ast::MemberAccessorExpression>(
-                      std::make_unique<ast::ArrayAccessorExpression>(
-                          std::make_unique<ast::IdentifierExpression>("index"),
-                          std::make_unique<ast::ScalarConstructorExpression>(
-                              std::make_unique<ast::SintLiteral>(&i32, 0))),
-                      std::make_unique<ast::IdentifierExpression>("foo")),
-                  std::make_unique<ast::ScalarConstructorExpression>(
-                      std::make_unique<ast::SintLiteral>(&i32, 2))),
-              std::make_unique<ast::IdentifierExpression>("bar")),
-          std::make_unique<ast::IdentifierExpression>("baz")),
-      std::make_unique<ast::IdentifierExpression>("yx"));
+      create<ast::MemberAccessorExpression>(
+          create<ast::MemberAccessorExpression>(
+              create<ast::ArrayAccessorExpression>(
+                  create<ast::MemberAccessorExpression>(
+                      create<ast::ArrayAccessorExpression>(
+                          create<ast::IdentifierExpression>("index"),
+                          create<ast::ScalarConstructorExpression>(
+                              create<ast::SintLiteral>(&i32, 0))),
+                      create<ast::IdentifierExpression>("foo")),
+                  create<ast::ScalarConstructorExpression>(
+                      create<ast::SintLiteral>(&i32, 2))),
+              create<ast::IdentifierExpression>("bar")),
+          create<ast::IdentifierExpression>("baz")),
+      create<ast::IdentifierExpression>("yx"));
 
   td.RegisterVariableForTesting(&var);
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
@@ -888,36 +882,35 @@
   ast::ExpressionList ary_params;
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 0.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 0.5)));
-  ary_params.push_back(std::make_unique<ast::TypeConstructorExpression>(
-      &vec, std::move(vec_params)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 0.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 0.5)));
+  ary_params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec_params)));
 
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, -0.5)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, -0.5)));
-  ary_params.push_back(std::make_unique<ast::TypeConstructorExpression>(
-      &vec, std::move(vec_params)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, -0.5)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, -0.5)));
+  ary_params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec_params)));
 
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 0.5)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, -0.5)));
-  ary_params.push_back(std::make_unique<ast::TypeConstructorExpression>(
-      &vec, std::move(vec_params)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 0.5)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, -0.5)));
+  ary_params.push_back(
+      create<ast::TypeConstructorExpression>(&vec, std::move(vec_params)));
 
   ast::Variable var("pos", ast::StorageClass::kPrivate, &arr);
   var.set_is_const(true);
-  var.set_constructor(std::make_unique<ast::TypeConstructorExpression>(
-      &arr, std::move(ary_params)));
+  var.set_constructor(
+      create<ast::TypeConstructorExpression>(&arr, std::move(ary_params)));
 
-  ast::ArrayAccessorExpression expr(
-      std::make_unique<ast::IdentifierExpression>("pos"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::UintLiteral>(&u32, 1)));
+  ast::ArrayAccessorExpression expr(create<ast::IdentifierExpression>("pos"),
+                                    create<ast::ScalarConstructorExpression>(
+                                        create<ast::UintLiteral>(&u32, 1)));
 
   td.RegisterVariableForTesting(&var);
   ASSERT_TRUE(td.DetermineResultType(var.constructor())) << td.error();
diff --git a/src/writer/spirv/builder_assign_test.cc b/src/writer/spirv/builder_assign_test.cc
index cf0b0c4..58229b0 100644
--- a/src/writer/spirv/builder_assign_test.cc
+++ b/src/writer/spirv/builder_assign_test.cc
@@ -47,9 +47,9 @@
 
   ast::Variable v("var", ast::StorageClass::kOutput, &f32);
 
-  auto ident = std::make_unique<ast::IdentifierExpression>("var");
-  auto val = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f));
+  auto ident = create<ast::IdentifierExpression>("var");
+  auto val = create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f));
 
   ast::AssignmentStatement assign(std::move(ident), std::move(val));
 
@@ -81,10 +81,9 @@
 
   ast::Variable v("var", ast::StorageClass::kOutput, &vec);
 
-  auto ident = std::make_unique<ast::IdentifierExpression>("var");
+  auto ident = create<ast::IdentifierExpression>("var");
   ast::ExpressionList vals;
-  auto val =
-      std::make_unique<ast::TypeConstructorExpression>(&vec, std::move(vals));
+  auto val = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
 
   ast::AssignmentStatement assign(std::move(ident), std::move(val));
 
@@ -116,24 +115,22 @@
   ast::type::VectorType vec2(&f32, 2);
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0f)));
-  auto first =
-      std::make_unique<ast::TypeConstructorExpression>(&vec2, std::move(vals));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0f)));
+  auto first = create<ast::TypeConstructorExpression>(&vec2, std::move(vals));
 
   vals.push_back(std::move(first));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 3.0f)));
 
-  auto init =
-      std::make_unique<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  auto init = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   ast::Variable v("var", ast::StorageClass::kOutput, &vec3);
 
-  ast::AssignmentStatement assign(
-      std::make_unique<ast::IdentifierExpression>("var"), std::move(init));
+  ast::AssignmentStatement assign(create<ast::IdentifierExpression>("var"),
+                                  std::move(init));
 
   td.RegisterVariableForTesting(&v);
   ASSERT_TRUE(td.DetermineResultType(&assign)) << td.error();
@@ -169,20 +166,19 @@
   ast::type::VectorType vec3(&f32, 3);
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 3.0f)));
 
-  auto init =
-      std::make_unique<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  auto init = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   ast::Variable v("var", ast::StorageClass::kOutput, &vec3);
 
-  ast::AssignmentStatement assign(
-      std::make_unique<ast::IdentifierExpression>("var"), std::move(init));
+  ast::AssignmentStatement assign(create<ast::IdentifierExpression>("var"),
+                                  std::move(init));
 
   td.RegisterVariableForTesting(&v);
   ASSERT_TRUE(td.DetermineResultType(&assign)) << td.error();
@@ -220,22 +216,20 @@
 
   ast::StructMemberDecorationList decos;
   ast::StructMemberList members;
-  members.push_back(
-      std::make_unique<ast::StructMember>("a", &f32, std::move(decos)));
-  members.push_back(
-      std::make_unique<ast::StructMember>("b", &f32, std::move(decos)));
+  members.push_back(create<ast::StructMember>("a", &f32, std::move(decos)));
+  members.push_back(create<ast::StructMember>("b", &f32, std::move(decos)));
 
-  auto s = std::make_unique<ast::Struct>(std::move(members));
+  auto s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("my_struct", std::move(s));
 
   ast::Variable v("ident", ast::StorageClass::kFunction, &s_type);
 
-  auto ident = std::make_unique<ast::MemberAccessorExpression>(
-      std::make_unique<ast::IdentifierExpression>("ident"),
-      std::make_unique<ast::IdentifierExpression>("b"));
+  auto ident = create<ast::MemberAccessorExpression>(
+      create<ast::IdentifierExpression>("ident"),
+      create<ast::IdentifierExpression>("b"));
 
-  auto val = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 4.0f));
+  auto val = create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 4.0f));
 
   ast::AssignmentStatement assign(std::move(ident), std::move(val));
 
@@ -272,18 +266,17 @@
 
   ast::Variable v("var", ast::StorageClass::kOutput, &vec3);
 
-  auto ident = std::make_unique<ast::IdentifierExpression>("var");
+  auto ident = create<ast::IdentifierExpression>("var");
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 3.0f)));
 
-  auto val =
-      std::make_unique<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  auto val = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   ast::AssignmentStatement assign(std::move(ident), std::move(val));
 
@@ -320,11 +313,11 @@
 
   ast::Variable v("var", ast::StorageClass::kOutput, &vec3);
 
-  auto ident = std::make_unique<ast::MemberAccessorExpression>(
-      std::make_unique<ast::IdentifierExpression>("var"),
-      std::make_unique<ast::IdentifierExpression>("y"));
-  auto val = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f));
+  auto ident = create<ast::MemberAccessorExpression>(
+      create<ast::IdentifierExpression>("var"),
+      create<ast::IdentifierExpression>("y"));
+  auto val = create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f));
 
   ast::AssignmentStatement assign(std::move(ident), std::move(val));
 
@@ -365,12 +358,12 @@
 
   ast::Variable v("var", ast::StorageClass::kOutput, &vec3);
 
-  auto ident = std::make_unique<ast::ArrayAccessorExpression>(
-      std::make_unique<ast::IdentifierExpression>("var"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 1)));
-  auto val = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f));
+  auto ident = create<ast::ArrayAccessorExpression>(
+      create<ast::IdentifierExpression>("var"),
+      create<ast::ScalarConstructorExpression>(
+          create<ast::SintLiteral>(&i32, 1)));
+  auto val = create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f));
 
   ast::AssignmentStatement assign(std::move(ident), std::move(val));
 
diff --git a/src/writer/spirv/builder_binary_expression_test.cc b/src/writer/spirv/builder_binary_expression_test.cc
index d7e3bbf..1b4d2cd 100644
--- a/src/writer/spirv/builder_binary_expression_test.cc
+++ b/src/writer/spirv/builder_binary_expression_test.cc
@@ -57,10 +57,10 @@
 
   ast::type::I32Type i32;
 
-  auto lhs = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 3));
-  auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 4));
+  auto lhs = create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 3));
+  auto rhs = create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 4));
 
   ast::BinaryExpression expr(param.op, std::move(lhs), std::move(rhs));
 
@@ -83,23 +83,21 @@
   ast::type::VectorType vec3(&i32, 3);
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 1)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 1)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 1)));
-  auto lhs =
-      std::make_unique<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 1)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 1)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 1)));
+  auto lhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 1)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 1)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 1)));
-  auto rhs =
-      std::make_unique<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 1)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 1)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 1)));
+  auto rhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   ast::BinaryExpression expr(param.op, std::move(lhs), std::move(rhs));
 
@@ -123,8 +121,8 @@
 
   ast::Variable var("param", ast::StorageClass::kFunction, &i32);
 
-  auto lhs = std::make_unique<ast::IdentifierExpression>("param");
-  auto rhs = std::make_unique<ast::IdentifierExpression>("param");
+  auto lhs = create<ast::IdentifierExpression>("param");
+  auto rhs = create<ast::IdentifierExpression>("param");
 
   ast::BinaryExpression expr(param.op, std::move(lhs), std::move(rhs));
 
@@ -171,10 +169,10 @@
 
   ast::type::U32Type u32;
 
-  auto lhs = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::UintLiteral>(&u32, 3));
-  auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::UintLiteral>(&u32, 4));
+  auto lhs = create<ast::ScalarConstructorExpression>(
+      create<ast::UintLiteral>(&u32, 3));
+  auto rhs = create<ast::ScalarConstructorExpression>(
+      create<ast::UintLiteral>(&u32, 4));
 
   ast::BinaryExpression expr(param.op, std::move(lhs), std::move(rhs));
 
@@ -197,23 +195,21 @@
   ast::type::VectorType vec3(&u32, 3);
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::UintLiteral>(&u32, 1)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::UintLiteral>(&u32, 1)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::UintLiteral>(&u32, 1)));
-  auto lhs =
-      std::make_unique<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::UintLiteral>(&u32, 1)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::UintLiteral>(&u32, 1)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::UintLiteral>(&u32, 1)));
+  auto lhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::UintLiteral>(&u32, 1)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::UintLiteral>(&u32, 1)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::UintLiteral>(&u32, 1)));
-  auto rhs =
-      std::make_unique<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::UintLiteral>(&u32, 1)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::UintLiteral>(&u32, 1)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::UintLiteral>(&u32, 1)));
+  auto rhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   ast::BinaryExpression expr(param.op, std::move(lhs), std::move(rhs));
 
@@ -251,10 +247,10 @@
 
   ast::type::F32Type f32;
 
-  auto lhs = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 3.2f));
-  auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 4.5f));
+  auto lhs = create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 3.2f));
+  auto rhs = create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 4.5f));
 
   ast::BinaryExpression expr(param.op, std::move(lhs), std::move(rhs));
 
@@ -277,23 +273,21 @@
   ast::type::VectorType vec3(&f32, 3);
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  auto lhs =
-      std::make_unique<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  auto lhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  auto rhs =
-      std::make_unique<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  auto rhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   ast::BinaryExpression expr(param.op, std::move(lhs), std::move(rhs));
 
@@ -325,10 +319,10 @@
 
   ast::type::U32Type u32;
 
-  auto lhs = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::UintLiteral>(&u32, 3));
-  auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::UintLiteral>(&u32, 4));
+  auto lhs = create<ast::ScalarConstructorExpression>(
+      create<ast::UintLiteral>(&u32, 3));
+  auto rhs = create<ast::ScalarConstructorExpression>(
+      create<ast::UintLiteral>(&u32, 4));
 
   ast::BinaryExpression expr(param.op, std::move(lhs), std::move(rhs));
 
@@ -353,23 +347,21 @@
   ast::type::VectorType vec3(&u32, 3);
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::UintLiteral>(&u32, 1)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::UintLiteral>(&u32, 1)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::UintLiteral>(&u32, 1)));
-  auto lhs =
-      std::make_unique<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::UintLiteral>(&u32, 1)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::UintLiteral>(&u32, 1)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::UintLiteral>(&u32, 1)));
+  auto lhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::UintLiteral>(&u32, 1)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::UintLiteral>(&u32, 1)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::UintLiteral>(&u32, 1)));
-  auto rhs =
-      std::make_unique<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::UintLiteral>(&u32, 1)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::UintLiteral>(&u32, 1)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::UintLiteral>(&u32, 1)));
+  auto rhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   ast::BinaryExpression expr(param.op, std::move(lhs), std::move(rhs));
 
@@ -405,10 +397,10 @@
 
   ast::type::I32Type i32;
 
-  auto lhs = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 3));
-  auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 4));
+  auto lhs = create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 3));
+  auto rhs = create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 4));
 
   ast::BinaryExpression expr(param.op, std::move(lhs), std::move(rhs));
 
@@ -433,23 +425,21 @@
   ast::type::VectorType vec3(&i32, 3);
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 1)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 1)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 1)));
-  auto lhs =
-      std::make_unique<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 1)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 1)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 1)));
+  auto lhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 1)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 1)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 1)));
-  auto rhs =
-      std::make_unique<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 1)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 1)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 1)));
+  auto rhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   ast::BinaryExpression expr(param.op, std::move(lhs), std::move(rhs));
 
@@ -485,10 +475,10 @@
 
   ast::type::F32Type f32;
 
-  auto lhs = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 3.2f));
-  auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 4.5f));
+  auto lhs = create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 3.2f));
+  auto rhs = create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 4.5f));
 
   ast::BinaryExpression expr(param.op, std::move(lhs), std::move(rhs));
 
@@ -513,23 +503,21 @@
   ast::type::VectorType vec3(&f32, 3);
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  auto lhs =
-      std::make_unique<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  auto lhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  auto rhs =
-      std::make_unique<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  auto rhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   ast::BinaryExpression expr(param.op, std::move(lhs), std::move(rhs));
 
@@ -564,17 +552,16 @@
   ast::type::VectorType vec3(&f32, 3);
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  auto lhs =
-      std::make_unique<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  auto lhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
-  auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f));
+  auto rhs = create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f));
 
   ast::BinaryExpression expr(ast::BinaryOp::kMultiply, std::move(lhs),
                              std::move(rhs));
@@ -597,18 +584,17 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec3(&f32, 3);
 
-  auto lhs = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f));
+  auto lhs = create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f));
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  auto rhs =
-      std::make_unique<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  auto rhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   ast::BinaryExpression expr(ast::BinaryOp::kMultiply, std::move(lhs),
                              std::move(rhs));
@@ -631,11 +617,10 @@
   ast::type::F32Type f32;
   ast::type::MatrixType mat3(&f32, 3, 3);
 
-  auto var = std::make_unique<ast::Variable>(
-      "mat", ast::StorageClass::kFunction, &mat3);
-  auto lhs = std::make_unique<ast::IdentifierExpression>("mat");
-  auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f));
+  auto var = create<ast::Variable>("mat", ast::StorageClass::kFunction, &mat3);
+  auto lhs = create<ast::IdentifierExpression>("mat");
+  auto rhs = create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f));
 
   td.RegisterVariableForTesting(var.get());
 
@@ -665,11 +650,10 @@
   ast::type::F32Type f32;
   ast::type::MatrixType mat3(&f32, 3, 3);
 
-  auto var = std::make_unique<ast::Variable>(
-      "mat", ast::StorageClass::kFunction, &mat3);
-  auto lhs = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f));
-  auto rhs = std::make_unique<ast::IdentifierExpression>("mat");
+  auto var = create<ast::Variable>("mat", ast::StorageClass::kFunction, &mat3);
+  auto lhs = create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f));
+  auto rhs = create<ast::IdentifierExpression>("mat");
 
   td.RegisterVariableForTesting(var.get());
 
@@ -700,19 +684,17 @@
   ast::type::VectorType vec3(&f32, 3);
   ast::type::MatrixType mat3(&f32, 3, 3);
 
-  auto var = std::make_unique<ast::Variable>(
-      "mat", ast::StorageClass::kFunction, &mat3);
-  auto lhs = std::make_unique<ast::IdentifierExpression>("mat");
+  auto var = create<ast::Variable>("mat", ast::StorageClass::kFunction, &mat3);
+  auto lhs = create<ast::IdentifierExpression>("mat");
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  auto rhs =
-      std::make_unique<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  auto rhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   td.RegisterVariableForTesting(var.get());
 
@@ -744,20 +726,18 @@
   ast::type::VectorType vec3(&f32, 3);
   ast::type::MatrixType mat3(&f32, 3, 3);
 
-  auto var = std::make_unique<ast::Variable>(
-      "mat", ast::StorageClass::kFunction, &mat3);
+  auto var = create<ast::Variable>("mat", ast::StorageClass::kFunction, &mat3);
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  auto lhs =
-      std::make_unique<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  auto lhs = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
-  auto rhs = std::make_unique<ast::IdentifierExpression>("mat");
+  auto rhs = create<ast::IdentifierExpression>("mat");
 
   td.RegisterVariableForTesting(var.get());
 
@@ -789,10 +769,9 @@
   ast::type::VectorType vec3(&f32, 3);
   ast::type::MatrixType mat3(&f32, 3, 3);
 
-  auto var = std::make_unique<ast::Variable>(
-      "mat", ast::StorageClass::kFunction, &mat3);
-  auto lhs = std::make_unique<ast::IdentifierExpression>("mat");
-  auto rhs = std::make_unique<ast::IdentifierExpression>("mat");
+  auto var = create<ast::Variable>("mat", ast::StorageClass::kFunction, &mat3);
+  auto lhs = create<ast::IdentifierExpression>("mat");
+  auto rhs = create<ast::IdentifierExpression>("mat");
 
   td.RegisterVariableForTesting(var.get());
 
@@ -821,19 +800,19 @@
 TEST_F(BuilderTest, Binary_LogicalAnd) {
   ast::type::I32Type i32;
 
-  auto lhs = std::make_unique<ast::BinaryExpression>(
-      ast::BinaryOp::kEqual,
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 1)),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 2)));
+  auto lhs =
+      create<ast::BinaryExpression>(ast::BinaryOp::kEqual,
+                                    create<ast::ScalarConstructorExpression>(
+                                        create<ast::SintLiteral>(&i32, 1)),
+                                    create<ast::ScalarConstructorExpression>(
+                                        create<ast::SintLiteral>(&i32, 2)));
 
-  auto rhs = std::make_unique<ast::BinaryExpression>(
-      ast::BinaryOp::kEqual,
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 3)),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 4)));
+  auto rhs =
+      create<ast::BinaryExpression>(ast::BinaryOp::kEqual,
+                                    create<ast::ScalarConstructorExpression>(
+                                        create<ast::SintLiteral>(&i32, 3)),
+                                    create<ast::ScalarConstructorExpression>(
+                                        create<ast::SintLiteral>(&i32, 4)));
 
   ast::BinaryExpression expr(ast::BinaryOp::kLogicalAnd, std::move(lhs),
                              std::move(rhs));
@@ -867,17 +846,17 @@
 TEST_F(BuilderTest, Binary_LogicalAnd_WithLoads) {
   ast::type::BoolType bool_type;
 
-  auto a_var = std::make_unique<ast::Variable>(
-      "a", ast::StorageClass::kFunction, &bool_type);
-  a_var->set_constructor(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::BoolLiteral>(&bool_type, true)));
-  auto b_var = std::make_unique<ast::Variable>(
-      "b", ast::StorageClass::kFunction, &bool_type);
-  b_var->set_constructor(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::BoolLiteral>(&bool_type, false)));
+  auto a_var =
+      create<ast::Variable>("a", ast::StorageClass::kFunction, &bool_type);
+  a_var->set_constructor(create<ast::ScalarConstructorExpression>(
+      create<ast::BoolLiteral>(&bool_type, true)));
+  auto b_var =
+      create<ast::Variable>("b", ast::StorageClass::kFunction, &bool_type);
+  b_var->set_constructor(create<ast::ScalarConstructorExpression>(
+      create<ast::BoolLiteral>(&bool_type, false)));
 
-  auto lhs = std::make_unique<ast::IdentifierExpression>("a");
-  auto rhs = std::make_unique<ast::IdentifierExpression>("b");
+  auto lhs = create<ast::IdentifierExpression>("a");
+  auto rhs = create<ast::IdentifierExpression>("b");
 
   td.RegisterVariableForTesting(a_var.get());
   td.RegisterVariableForTesting(b_var.get());
@@ -917,19 +896,19 @@
 TEST_F(BuilderTest, Binary_LogicalOr) {
   ast::type::I32Type i32;
 
-  auto lhs = std::make_unique<ast::BinaryExpression>(
-      ast::BinaryOp::kEqual,
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 1)),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 2)));
+  auto lhs =
+      create<ast::BinaryExpression>(ast::BinaryOp::kEqual,
+                                    create<ast::ScalarConstructorExpression>(
+                                        create<ast::SintLiteral>(&i32, 1)),
+                                    create<ast::ScalarConstructorExpression>(
+                                        create<ast::SintLiteral>(&i32, 2)));
 
-  auto rhs = std::make_unique<ast::BinaryExpression>(
-      ast::BinaryOp::kEqual,
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 3)),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 4)));
+  auto rhs =
+      create<ast::BinaryExpression>(ast::BinaryOp::kEqual,
+                                    create<ast::ScalarConstructorExpression>(
+                                        create<ast::SintLiteral>(&i32, 3)),
+                                    create<ast::ScalarConstructorExpression>(
+                                        create<ast::SintLiteral>(&i32, 4)));
 
   ast::BinaryExpression expr(ast::BinaryOp::kLogicalOr, std::move(lhs),
                              std::move(rhs));
@@ -963,17 +942,17 @@
 TEST_F(BuilderTest, Binary_LogicalOr_WithLoads) {
   ast::type::BoolType bool_type;
 
-  auto a_var = std::make_unique<ast::Variable>(
-      "a", ast::StorageClass::kFunction, &bool_type);
-  a_var->set_constructor(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::BoolLiteral>(&bool_type, true)));
-  auto b_var = std::make_unique<ast::Variable>(
-      "b", ast::StorageClass::kFunction, &bool_type);
-  b_var->set_constructor(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::BoolLiteral>(&bool_type, false)));
+  auto a_var =
+      create<ast::Variable>("a", ast::StorageClass::kFunction, &bool_type);
+  a_var->set_constructor(create<ast::ScalarConstructorExpression>(
+      create<ast::BoolLiteral>(&bool_type, true)));
+  auto b_var =
+      create<ast::Variable>("b", ast::StorageClass::kFunction, &bool_type);
+  b_var->set_constructor(create<ast::ScalarConstructorExpression>(
+      create<ast::BoolLiteral>(&bool_type, false)));
 
-  auto lhs = std::make_unique<ast::IdentifierExpression>("a");
-  auto rhs = std::make_unique<ast::IdentifierExpression>("b");
+  auto lhs = create<ast::IdentifierExpression>("a");
+  auto rhs = create<ast::IdentifierExpression>("b");
 
   td.RegisterVariableForTesting(a_var.get());
   td.RegisterVariableForTesting(b_var.get());
diff --git a/src/writer/spirv/builder_bitcast_expression_test.cc b/src/writer/spirv/builder_bitcast_expression_test.cc
index bf40037..92996ca 100644
--- a/src/writer/spirv/builder_bitcast_expression_test.cc
+++ b/src/writer/spirv/builder_bitcast_expression_test.cc
@@ -36,9 +36,9 @@
   ast::type::U32Type u32;
   ast::type::F32Type f32;
 
-  ast::BitcastExpression bitcast(
-      &u32, std::make_unique<ast::ScalarConstructorExpression>(
-                std::make_unique<ast::FloatLiteral>(&f32, 2.4)));
+  ast::BitcastExpression bitcast(&u32,
+                                 create<ast::ScalarConstructorExpression>(
+                                     create<ast::FloatLiteral>(&f32, 2.4)));
 
   ASSERT_TRUE(td.DetermineResultType(&bitcast)) << td.error();
 
@@ -57,9 +57,9 @@
 TEST_F(BuilderTest, Bitcast_DuplicateType) {
   ast::type::F32Type f32;
 
-  ast::BitcastExpression bitcast(
-      &f32, std::make_unique<ast::ScalarConstructorExpression>(
-                std::make_unique<ast::FloatLiteral>(&f32, 2.4)));
+  ast::BitcastExpression bitcast(&f32,
+                                 create<ast::ScalarConstructorExpression>(
+                                     create<ast::FloatLiteral>(&f32, 2.4)));
 
   ASSERT_TRUE(td.DetermineResultType(&bitcast)) << td.error();
 
diff --git a/src/writer/spirv/builder_block_test.cc b/src/writer/spirv/builder_block_test.cc
index 586357d..505642b 100644
--- a/src/writer/spirv/builder_block_test.cc
+++ b/src/writer/spirv/builder_block_test.cc
@@ -42,28 +42,26 @@
   // serves to prove the block code is pushing new scopes as needed.
   ast::BlockStatement outer;
 
-  outer.append(std::make_unique<ast::VariableDeclStatement>(
-      std::make_unique<ast::Variable>("var", ast::StorageClass::kFunction,
-                                      &f32)));
-  outer.append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("var"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::FloatLiteral>(&f32, 1.0f))));
+  outer.append(create<ast::VariableDeclStatement>(
+      create<ast::Variable>("var", ast::StorageClass::kFunction, &f32)));
+  outer.append(create<ast::AssignmentStatement>(
+      create<ast::IdentifierExpression>("var"),
+      create<ast::ScalarConstructorExpression>(
+          create<ast::FloatLiteral>(&f32, 1.0f))));
 
-  auto inner = std::make_unique<ast::BlockStatement>();
-  inner->append(std::make_unique<ast::VariableDeclStatement>(
-      std::make_unique<ast::Variable>("var", ast::StorageClass::kFunction,
-                                      &f32)));
-  inner->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("var"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::FloatLiteral>(&f32, 2.0f))));
+  auto inner = create<ast::BlockStatement>();
+  inner->append(create<ast::VariableDeclStatement>(
+      create<ast::Variable>("var", ast::StorageClass::kFunction, &f32)));
+  inner->append(create<ast::AssignmentStatement>(
+      create<ast::IdentifierExpression>("var"),
+      create<ast::ScalarConstructorExpression>(
+          create<ast::FloatLiteral>(&f32, 2.0f))));
 
   outer.append(std::move(inner));
-  outer.append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("var"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::FloatLiteral>(&f32, 3.0f))));
+  outer.append(create<ast::AssignmentStatement>(
+      create<ast::IdentifierExpression>("var"),
+      create<ast::ScalarConstructorExpression>(
+          create<ast::FloatLiteral>(&f32, 3.0f))));
 
   ASSERT_TRUE(td.DetermineResultType(&outer)) << td.error();
 
diff --git a/src/writer/spirv/builder_call_test.cc b/src/writer/spirv/builder_call_test.cc
index 34b0207..5bcadc5 100644
--- a/src/writer/spirv/builder_call_test.cc
+++ b/src/writer/spirv/builder_call_test.cc
@@ -45,30 +45,28 @@
 
   ast::VariableList func_params;
   func_params.push_back(
-      std::make_unique<ast::Variable>("a", ast::StorageClass::kFunction, &f32));
+      create<ast::Variable>("a", ast::StorageClass::kFunction, &f32));
   func_params.push_back(
-      std::make_unique<ast::Variable>("b", ast::StorageClass::kFunction, &f32));
+      create<ast::Variable>("b", ast::StorageClass::kFunction, &f32));
 
   ast::Function a_func("a_func", std::move(func_params), &f32);
 
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<ast::ReturnStatement>(
-      std::make_unique<ast::BinaryExpression>(
-          ast::BinaryOp::kAdd, std::make_unique<ast::IdentifierExpression>("a"),
-          std::make_unique<ast::IdentifierExpression>("b"))));
+  auto body = create<ast::BlockStatement>();
+  body->append(create<ast::ReturnStatement>(create<ast::BinaryExpression>(
+      ast::BinaryOp::kAdd, create<ast::IdentifierExpression>("a"),
+      create<ast::IdentifierExpression>("b"))));
   a_func.set_body(std::move(body));
 
   ast::Function func("main", {}, &void_type);
 
   ast::ExpressionList call_params;
-  call_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  call_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
+  call_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  call_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
 
-  ast::CallExpression expr(
-      std::make_unique<ast::IdentifierExpression>("a_func"),
-      std::move(call_params));
+  ast::CallExpression expr(create<ast::IdentifierExpression>("a_func"),
+                           std::move(call_params));
 
   ASSERT_TRUE(td.DetermineFunction(&func)) << td.error();
   ASSERT_TRUE(td.DetermineFunction(&a_func)) << td.error();
@@ -109,30 +107,28 @@
 
   ast::VariableList func_params;
   func_params.push_back(
-      std::make_unique<ast::Variable>("a", ast::StorageClass::kFunction, &f32));
+      create<ast::Variable>("a", ast::StorageClass::kFunction, &f32));
   func_params.push_back(
-      std::make_unique<ast::Variable>("b", ast::StorageClass::kFunction, &f32));
+      create<ast::Variable>("b", ast::StorageClass::kFunction, &f32));
 
   ast::Function a_func("a_func", std::move(func_params), &void_type);
 
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<ast::ReturnStatement>(
-      std::make_unique<ast::BinaryExpression>(
-          ast::BinaryOp::kAdd, std::make_unique<ast::IdentifierExpression>("a"),
-          std::make_unique<ast::IdentifierExpression>("b"))));
+  auto body = create<ast::BlockStatement>();
+  body->append(create<ast::ReturnStatement>(create<ast::BinaryExpression>(
+      ast::BinaryOp::kAdd, create<ast::IdentifierExpression>("a"),
+      create<ast::IdentifierExpression>("b"))));
   a_func.set_body(std::move(body));
 
   ast::Function func("main", {}, &void_type);
 
   ast::ExpressionList call_params;
-  call_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  call_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
+  call_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  call_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
 
-  ast::CallStatement expr(std::make_unique<ast::CallExpression>(
-      std::make_unique<ast::IdentifierExpression>("a_func"),
-      std::move(call_params)));
+  ast::CallStatement expr(create<ast::CallExpression>(
+      create<ast::IdentifierExpression>("a_func"), std::move(call_params)));
 
   ASSERT_TRUE(td.DetermineFunction(&func)) << td.error();
   ASSERT_TRUE(td.DetermineFunction(&a_func)) << td.error();
diff --git a/src/writer/spirv/builder_constructor_expression_test.cc b/src/writer/spirv/builder_constructor_expression_test.cc
index 1655428..c94080e 100644
--- a/src/writer/spirv/builder_constructor_expression_test.cc
+++ b/src/writer/spirv/builder_constructor_expression_test.cc
@@ -52,7 +52,7 @@
 
 TEST_F(BuilderTest, Constructor_Const) {
   ast::type::F32Type f32;
-  auto fl = std::make_unique<ast::FloatLiteral>(&f32, 42.2f);
+  auto fl = create<ast::FloatLiteral>(&f32, 42.2f);
   ast::ScalarConstructorExpression c(std::move(fl));
 
   EXPECT_EQ(b.GenerateConstructorExpression(nullptr, &c, true), 2u);
@@ -68,12 +68,12 @@
   ast::type::VectorType vec(&f32, 3);
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 3.0f)));
 
   ast::TypeConstructorExpression t(&vec, std::move(vals));
 
@@ -96,16 +96,16 @@
   ast::type::VectorType vec(&f32, 2);
 
   ast::ExpressionList type_vals;
-  type_vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 1)));
+  type_vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 1)));
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  vals.push_back(create<ast::TypeConstructorExpression>(
       &f32, std::move(type_vals)));
 
-  type_vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 1)));
-  vals.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  type_vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 1)));
+  vals.push_back(create<ast::TypeConstructorExpression>(
       &f32, std::move(type_vals)));
 
   ast::TypeConstructorExpression t(&vec, std::move(vals));
@@ -139,8 +139,8 @@
   ast::type::AliasType alias("Int", &i32);
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.3)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.3)));
 
   ast::TypeConstructorExpression cast(&alias, std::move(params));
 
@@ -162,13 +162,13 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec(&f32, 2);
 
-  auto var = std::make_unique<ast::Variable>(
+  auto var = create<ast::Variable>(
       "ident", ast::StorageClass::kFunction, &f32);
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-  vals.push_back(std::make_unique<ast::IdentifierExpression>("ident"));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f)));
+  vals.push_back(create<ast::IdentifierExpression>("ident"));
 
   ast::TypeConstructorExpression t(&vec, std::move(vals));
 
@@ -203,10 +203,10 @@
   ast::type::VectorType vec(&u32, 2);
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 1)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 1)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 1)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 1)));
 
   ast::TypeConstructorExpression t(&vec, std::move(vals));
 
@@ -233,16 +233,16 @@
 TEST_F(BuilderTest, Constructor_Type_NonConst_Value_Fails) {
   ast::type::F32Type f32;
   ast::type::VectorType vec(&f32, 2);
-  auto rel = std::make_unique<ast::BinaryExpression>(
+  auto rel = create<ast::BinaryExpression>(
       ast::BinaryOp::kAdd,
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::FloatLiteral>(&f32, 3.0f)),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
+      create<ast::ScalarConstructorExpression>(
+          create<ast::FloatLiteral>(&f32, 3.0f)),
+      create<ast::ScalarConstructorExpression>(
+          create<ast::FloatLiteral>(&f32, 3.0f)));
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f)));
   vals.push_back(std::move(rel));
 
   ast::TypeConstructorExpression t(&vec, std::move(vals));
@@ -258,8 +258,8 @@
   ast::type::BoolType bool_type;
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::BoolLiteral>(&bool_type, true)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::BoolLiteral>(&bool_type, true)));
 
   ast::TypeConstructorExpression t(&bool_type, std::move(vals));
 
@@ -282,8 +282,8 @@
   ast::type::I32Type i32;
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 2)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 2)));
 
   ast::TypeConstructorExpression cast(&i32, std::move(params));
 
@@ -304,8 +304,8 @@
   ast::type::U32Type u32;
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::UintLiteral>(&u32, 2)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::UintLiteral>(&u32, 2)));
 
   ast::TypeConstructorExpression cast(&u32, std::move(params));
 
@@ -326,8 +326,8 @@
   ast::type::F32Type f32;
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::TypeConstructorExpression cast(&f32, std::move(params));
 
@@ -349,10 +349,10 @@
   ast::type::VectorType vec(&f32, 2);
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::TypeConstructorExpression cast(&vec, std::move(params));
 
@@ -373,12 +373,12 @@
   ast::type::VectorType vec(&f32, 3);
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::TypeConstructorExpression cast(&vec, std::move(params));
 
@@ -400,15 +400,15 @@
   ast::type::VectorType vec3(&f32, 3);
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec2, std::move(vec_params)));
 
   ast::TypeConstructorExpression cast(&vec3, std::move(params));
@@ -437,16 +437,16 @@
   ast::type::VectorType vec3(&f32, 3);
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec2, std::move(vec_params)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::TypeConstructorExpression cast(&vec3, std::move(params));
 
@@ -473,14 +473,14 @@
   ast::type::VectorType vec(&f32, 4);
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::TypeConstructorExpression cast(&vec, std::move(params));
 
@@ -502,17 +502,17 @@
   ast::type::VectorType vec4(&f32, 4);
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec2, std::move(vec_params)));
 
   ast::TypeConstructorExpression cast(&vec4, std::move(params));
@@ -541,18 +541,18 @@
   ast::type::VectorType vec4(&f32, 4);
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec2, std::move(vec_params)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::TypeConstructorExpression cast(&vec4, std::move(params));
 
@@ -580,18 +580,18 @@
   ast::type::VectorType vec4(&f32, 4);
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec2, std::move(vec_params)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::TypeConstructorExpression cast(&vec4, std::move(params));
 
@@ -619,21 +619,21 @@
   ast::type::VectorType vec4(&f32, 4);
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList vec2_params;
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec2, std::move(vec_params)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec2, std::move(vec2_params)));
 
   ast::TypeConstructorExpression cast(&vec4, std::move(params));
@@ -664,17 +664,17 @@
   ast::type::VectorType vec4(&f32, 4);
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec3, std::move(vec_params)));
 
   ast::TypeConstructorExpression cast(&vec4, std::move(params));
@@ -704,18 +704,18 @@
   ast::type::VectorType vec4(&f32, 4);
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec3, std::move(vec_params)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::TypeConstructorExpression cast(&vec4, std::move(params));
 
@@ -744,15 +744,15 @@
   ast::type::VectorType vec3(&f32, 3);
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec2, std::move(vec_params)));
 
   ast::TypeConstructorExpression cast(&vec3, std::move(params));
@@ -782,16 +782,16 @@
   ast::type::VectorType vec3(&f32, 3);
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec2, std::move(vec_params)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::TypeConstructorExpression cast(&vec3, std::move(params));
 
@@ -820,17 +820,17 @@
   ast::type::VectorType vec4(&f32, 4);
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec2, std::move(vec_params)));
 
   ast::TypeConstructorExpression cast(&vec4, std::move(params));
@@ -860,18 +860,18 @@
   ast::type::VectorType vec4(&f32, 4);
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec2, std::move(vec_params)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::TypeConstructorExpression cast(&vec4, std::move(params));
 
@@ -900,18 +900,18 @@
   ast::type::VectorType vec4(&f32, 4);
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec2, std::move(vec_params)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::TypeConstructorExpression cast(&vec4, std::move(params));
 
@@ -940,21 +940,21 @@
   ast::type::VectorType vec4(&f32, 4);
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList vec2_params;
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec2, std::move(vec_params)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec2, std::move(vec2_params)));
 
   ast::TypeConstructorExpression cast(&vec4, std::move(params));
@@ -986,17 +986,17 @@
   ast::type::VectorType vec4(&f32, 4);
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec3, std::move(vec_params)));
 
   ast::TypeConstructorExpression cast(&vec4, std::move(params));
@@ -1028,18 +1028,18 @@
   ast::type::VectorType vec4(&f32, 4);
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec3, std::move(vec_params)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::TypeConstructorExpression cast(&vec4, std::move(params));
 
@@ -1070,21 +1070,21 @@
   ast::type::MatrixType mat(&f32, 2, 2);
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList vec2_params;
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec_params)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec2_params)));
 
   ast::TypeConstructorExpression cast(&mat, std::move(params));
@@ -1109,29 +1109,29 @@
   ast::type::MatrixType mat(&f32, 2, 3);
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList vec2_params;
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList vec3_params;
-  vec3_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec3_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec3_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec3_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec_params)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec2_params)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec3_params)));
 
   ast::TypeConstructorExpression cast(&mat, std::move(params));
@@ -1156,37 +1156,37 @@
   ast::type::MatrixType mat(&f32, 2, 4);
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList vec2_params;
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList vec3_params;
-  vec3_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec3_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec3_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec3_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList vec4_params;
-  vec4_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec4_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec4_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec4_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec_params)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec2_params)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec3_params)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec4_params)));
 
   ast::TypeConstructorExpression cast(&mat, std::move(params));
@@ -1211,25 +1211,25 @@
   ast::type::MatrixType mat(&f32, 3, 2);
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList vec2_params;
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec_params)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec2_params)));
 
   ast::TypeConstructorExpression cast(&mat, std::move(params));
@@ -1254,35 +1254,35 @@
   ast::type::MatrixType mat(&f32, 3, 3);
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList vec2_params;
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList vec3_params;
-  vec3_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec3_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec3_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec3_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec3_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec3_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec_params)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec2_params)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec3_params)));
 
   ast::TypeConstructorExpression cast(&mat, std::move(params));
@@ -1307,45 +1307,45 @@
   ast::type::MatrixType mat(&f32, 3, 4);
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList vec2_params;
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList vec3_params;
-  vec3_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec3_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec3_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec3_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec3_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec3_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList vec4_params;
-  vec4_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec4_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec4_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec4_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec4_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec4_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec_params)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec2_params)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec3_params)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec4_params)));
 
   ast::TypeConstructorExpression cast(&mat, std::move(params));
@@ -1370,29 +1370,29 @@
   ast::type::MatrixType mat(&f32, 4, 2);
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList vec2_params;
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec_params)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec2_params)));
 
   ast::TypeConstructorExpression cast(&mat, std::move(params));
@@ -1417,41 +1417,41 @@
   ast::type::MatrixType mat(&f32, 4, 3);
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList vec2_params;
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList vec3_params;
-  vec3_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec3_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec3_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec3_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec3_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec3_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec3_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec3_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec_params)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec2_params)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec3_params)));
 
   ast::TypeConstructorExpression cast(&mat, std::move(params));
@@ -1476,53 +1476,53 @@
   ast::type::MatrixType mat(&f32, 4, 4);
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList vec2_params;
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList vec3_params;
-  vec3_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec3_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec3_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec3_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec3_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec3_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec3_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec3_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList vec4_params;
-  vec4_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec4_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec4_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec4_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec4_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec4_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec4_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec4_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec_params)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec2_params)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec3_params)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec4_params)));
 
   ast::TypeConstructorExpression cast(&mat, std::move(params));
@@ -1546,16 +1546,16 @@
   ast::type::ArrayType ary(&f32, 5);
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::TypeConstructorExpression cast(&ary, std::move(params));
 
@@ -1579,25 +1579,25 @@
   ast::type::ArrayType ary(&vec, 2);
 
   ast::ExpressionList vec_params;
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList vec2_params;
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec2_params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec_params)));
-  params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec2_params)));
 
   ast::TypeConstructorExpression cast(&ary, std::move(params));
@@ -1625,25 +1625,25 @@
   ast::StructMemberDecorationList decos;
   ast::StructMemberList members;
   members.push_back(
-      std::make_unique<ast::StructMember>("a", &f32, std::move(decos)));
+      create<ast::StructMember>("a", &f32, std::move(decos)));
   members.push_back(
-      std::make_unique<ast::StructMember>("b", &vec, std::move(decos)));
+      create<ast::StructMember>("b", &vec, std::move(decos)));
 
-  auto s = std::make_unique<ast::Struct>(std::move(members));
+  auto s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("my_struct", std::move(s));
 
   ast::ExpressionList vec_vals;
-  vec_vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2)));
-  vec_vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2)));
-  vec_vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2)));
+  vec_vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2)));
+  vec_vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2)));
+  vec_vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2)));
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2)));
-  vals.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2)));
+  vals.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec_vals)));
 
   ast::TypeConstructorExpression t(&s_type, std::move(vals));
@@ -1805,9 +1805,9 @@
   ast::StructMemberDecorationList decos;
   ast::StructMemberList members;
   members.push_back(
-      std::make_unique<ast::StructMember>("a", &f32, std::move(decos)));
+      create<ast::StructMember>("a", &f32, std::move(decos)));
 
-  auto s = std::make_unique<ast::Struct>(std::move(members));
+  auto s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("my_struct", std::move(s));
 
   ast::ExpressionList vals;
@@ -1831,8 +1831,8 @@
   ast::type::I32Type i32;
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::UintLiteral>(&u32, 2)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::UintLiteral>(&u32, 2)));
 
   ast::TypeConstructorExpression cast(&i32, std::move(params));
 
@@ -1855,8 +1855,8 @@
   ast::type::I32Type i32;
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 2)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 2)));
 
   ast::TypeConstructorExpression cast(&u32, std::move(params));
 
@@ -1879,8 +1879,8 @@
   ast::type::F32Type f32;
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.4)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.4)));
 
   ast::TypeConstructorExpression cast(&i32, std::move(params));
 
@@ -1903,8 +1903,8 @@
   ast::type::F32Type f32;
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.4)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.4)));
 
   ast::TypeConstructorExpression cast(&u32, std::move(params));
 
@@ -1927,8 +1927,8 @@
   ast::type::F32Type f32;
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 2)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 2)));
 
   ast::TypeConstructorExpression cast(&f32, std::move(params));
 
@@ -1951,8 +1951,8 @@
   ast::type::F32Type f32;
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::UintLiteral>(&u32, 2)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::UintLiteral>(&u32, 2)));
 
   ast::TypeConstructorExpression cast(&f32, std::move(params));
 
@@ -1977,10 +1977,10 @@
   ast::type::VectorType ivec3(&i32, 3);
 
   auto var =
-      std::make_unique<ast::Variable>("i", ast::StorageClass::kPrivate, &uvec3);
+      create<ast::Variable>("i", ast::StorageClass::kPrivate, &uvec3);
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::IdentifierExpression>("i"));
+  params.push_back(create<ast::IdentifierExpression>("i"));
 
   ast::TypeConstructorExpression cast(&ivec3, std::move(params));
 
@@ -2012,10 +2012,10 @@
   ast::type::VectorType fvec3(&f32, 3);
 
   auto var =
-      std::make_unique<ast::Variable>("i", ast::StorageClass::kPrivate, &fvec3);
+      create<ast::Variable>("i", ast::StorageClass::kPrivate, &fvec3);
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::IdentifierExpression>("i"));
+  params.push_back(create<ast::IdentifierExpression>("i"));
 
   ast::TypeConstructorExpression cast(&ivec3, std::move(params));
 
@@ -2047,10 +2047,10 @@
   ast::type::VectorType ivec3(&i32, 3);
 
   auto var =
-      std::make_unique<ast::Variable>("i", ast::StorageClass::kPrivate, &ivec3);
+      create<ast::Variable>("i", ast::StorageClass::kPrivate, &ivec3);
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::IdentifierExpression>("i"));
+  params.push_back(create<ast::IdentifierExpression>("i"));
 
   ast::TypeConstructorExpression cast(&uvec3, std::move(params));
 
@@ -2082,10 +2082,10 @@
   ast::type::VectorType fvec3(&f32, 3);
 
   auto var =
-      std::make_unique<ast::Variable>("i", ast::StorageClass::kPrivate, &fvec3);
+      create<ast::Variable>("i", ast::StorageClass::kPrivate, &fvec3);
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::IdentifierExpression>("i"));
+  params.push_back(create<ast::IdentifierExpression>("i"));
 
   ast::TypeConstructorExpression cast(&uvec3, std::move(params));
 
@@ -2117,10 +2117,10 @@
   ast::type::VectorType fvec3(&f32, 3);
 
   auto var =
-      std::make_unique<ast::Variable>("i", ast::StorageClass::kPrivate, &ivec3);
+      create<ast::Variable>("i", ast::StorageClass::kPrivate, &ivec3);
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::IdentifierExpression>("i"));
+  params.push_back(create<ast::IdentifierExpression>("i"));
 
   ast::TypeConstructorExpression cast(&fvec3, std::move(params));
 
@@ -2152,10 +2152,10 @@
   ast::type::VectorType fvec3(&f32, 3);
 
   auto var =
-      std::make_unique<ast::Variable>("i", ast::StorageClass::kPrivate, &uvec3);
+      create<ast::Variable>("i", ast::StorageClass::kPrivate, &uvec3);
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::IdentifierExpression>("i"));
+  params.push_back(create<ast::IdentifierExpression>("i"));
 
   ast::TypeConstructorExpression cast(&fvec3, std::move(params));
 
@@ -2186,12 +2186,12 @@
   ast::type::VectorType vec(&f32, 3);
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.f)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 3.f)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.f)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 3.f)));
   ast::TypeConstructorExpression t(&vec, std::move(params));
 
   ASSERT_TRUE(td.DetermineResultType(&t)) << td.error();
@@ -2206,9 +2206,9 @@
   ast::type::VectorType vec(&f32, 3);
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::IdentifierExpression>("a"));
-  params.push_back(std::make_unique<ast::IdentifierExpression>("b"));
-  params.push_back(std::make_unique<ast::IdentifierExpression>("c"));
+  params.push_back(create<ast::IdentifierExpression>("a"));
+  params.push_back(create<ast::IdentifierExpression>("b"));
+  params.push_back(create<ast::IdentifierExpression>("c"));
   ast::TypeConstructorExpression t(&vec, std::move(params));
 
   ast::Variable var_a("a", ast::StorageClass::kPrivate, &f32);
@@ -2233,23 +2233,23 @@
   ast::type::ArrayType ary(&vec, 2);
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.f)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 3.f)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.f)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 3.f)));
   auto first =
-      std::make_unique<ast::TypeConstructorExpression>(&vec, std::move(params));
+      create<ast::TypeConstructorExpression>(&vec, std::move(params));
 
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.f)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 3.f)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.f)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 3.f)));
   auto second =
-      std::make_unique<ast::TypeConstructorExpression>(&vec, std::move(params));
+      create<ast::TypeConstructorExpression>(&vec, std::move(params));
 
   ast::ExpressionList ary_params;
   ary_params.push_back(std::move(first));
@@ -2271,14 +2271,14 @@
   ast::ExpressionList vec_params;
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0)));
-  vec_params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0)));
+  vec_params.push_back(create<ast::TypeConstructorExpression>(
       &f32, std::move(params)));
 
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
-  vec_params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
+  vec_params.push_back(create<ast::TypeConstructorExpression>(
       &f32, std::move(params)));
 
   ast::TypeConstructorExpression t(&vec, std::move(vec_params));
@@ -2298,14 +2298,14 @@
   ast::ExpressionList vec_params;
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 1)));
-  vec_params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 1)));
+  vec_params.push_back(create<ast::TypeConstructorExpression>(
       &f32, std::move(params)));
 
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 2)));
-  vec_params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 2)));
+  vec_params.push_back(create<ast::TypeConstructorExpression>(
       &f32, std::move(params)));
 
   ast::TypeConstructorExpression t(&vec, std::move(vec_params));
@@ -2322,12 +2322,12 @@
   ast::type::VectorType vec(&f32, 3);
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.f)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 3.f)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.f)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 3.f)));
   ast::TypeConstructorExpression t(&vec, std::move(params));
 
   ASSERT_TRUE(td.DetermineResultType(&t)) << td.error();
@@ -2342,9 +2342,9 @@
   ast::type::VectorType vec(&f32, 3);
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::IdentifierExpression>("a"));
-  params.push_back(std::make_unique<ast::IdentifierExpression>("b"));
-  params.push_back(std::make_unique<ast::IdentifierExpression>("c"));
+  params.push_back(create<ast::IdentifierExpression>("a"));
+  params.push_back(create<ast::IdentifierExpression>("b"));
+  params.push_back(create<ast::IdentifierExpression>("c"));
   ast::TypeConstructorExpression t(&vec, std::move(params));
 
   ast::Variable var_a("a", ast::StorageClass::kPrivate, &f32);
@@ -2368,23 +2368,23 @@
   ast::type::ArrayType ary(&vec, 2);
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.f)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 3.f)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.f)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 3.f)));
   auto first =
-      std::make_unique<ast::TypeConstructorExpression>(&vec, std::move(params));
+      create<ast::TypeConstructorExpression>(&vec, std::move(params));
 
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.f)));
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 3.f)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.f)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.f)));
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 3.f)));
   auto second =
-      std::make_unique<ast::TypeConstructorExpression>(&vec, std::move(params));
+      create<ast::TypeConstructorExpression>(&vec, std::move(params));
 
   ast::ExpressionList ary_params;
   ary_params.push_back(std::move(first));
@@ -2406,14 +2406,14 @@
   ast::ExpressionList vec_params;
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 1)));
-  vec_params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 1)));
+  vec_params.push_back(create<ast::TypeConstructorExpression>(
       &f32, std::move(params)));
 
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 2)));
-  vec_params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 2)));
+  vec_params.push_back(create<ast::TypeConstructorExpression>(
       &f32, std::move(params)));
 
   ast::TypeConstructorExpression t(&vec, std::move(vec_params));
@@ -2433,14 +2433,14 @@
   ast::ExpressionList vec_params;
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 1)));
-  vec_params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 1)));
+  vec_params.push_back(create<ast::TypeConstructorExpression>(
       &f32, std::move(params)));
 
-  params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 2)));
-  vec_params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  params.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 2)));
+  vec_params.push_back(create<ast::TypeConstructorExpression>(
       &f32, std::move(params)));
 
   ast::TypeConstructorExpression t(&vec, std::move(vec_params));
@@ -2457,10 +2457,10 @@
   ast::type::VectorType vec(&u32, 2);
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 1)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 1)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 1)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 1)));
 
   ast::TypeConstructorExpression t(&vec, std::move(vals));
 
@@ -2477,25 +2477,25 @@
   ast::StructMemberDecorationList decos;
   ast::StructMemberList members;
   members.push_back(
-      std::make_unique<ast::StructMember>("a", &f32, std::move(decos)));
+      create<ast::StructMember>("a", &f32, std::move(decos)));
   members.push_back(
-      std::make_unique<ast::StructMember>("b", &vec, std::move(decos)));
+      create<ast::StructMember>("b", &vec, std::move(decos)));
 
-  auto s = std::make_unique<ast::Struct>(std::move(members));
+  auto s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("my_struct", std::move(s));
 
   ast::ExpressionList vec_vals;
-  vec_vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2)));
-  vec_vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2)));
-  vec_vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2)));
+  vec_vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2)));
+  vec_vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2)));
+  vec_vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2)));
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2)));
-  vals.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2)));
+  vals.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec_vals)));
 
   ast::TypeConstructorExpression t(&s_type, std::move(vals));
@@ -2513,24 +2513,24 @@
   ast::StructMemberDecorationList decos;
   ast::StructMemberList members;
   members.push_back(
-      std::make_unique<ast::StructMember>("a", &f32, std::move(decos)));
+      create<ast::StructMember>("a", &f32, std::move(decos)));
   members.push_back(
-      std::make_unique<ast::StructMember>("b", &vec, std::move(decos)));
+      create<ast::StructMember>("b", &vec, std::move(decos)));
 
-  auto s = std::make_unique<ast::Struct>(std::move(members));
+  auto s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("my_struct", std::move(s));
 
   ast::ExpressionList vec_vals;
-  vec_vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2)));
-  vec_vals.push_back(std::make_unique<ast::IdentifierExpression>("a"));
-  vec_vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2)));
+  vec_vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2)));
+  vec_vals.push_back(create<ast::IdentifierExpression>("a"));
+  vec_vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2)));
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2)));
-  vals.push_back(std::make_unique<ast::TypeConstructorExpression>(
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2)));
+  vals.push_back(create<ast::TypeConstructorExpression>(
       &vec, std::move(vec_vals)));
 
   ast::TypeConstructorExpression t(&s_type, std::move(vals));
diff --git a/src/writer/spirv/builder_function_decoration_test.cc b/src/writer/spirv/builder_function_decoration_test.cc
index b549526..4a22a79 100644
--- a/src/writer/spirv/builder_function_decoration_test.cc
+++ b/src/writer/spirv/builder_function_decoration_test.cc
@@ -43,8 +43,8 @@
   ast::type::VoidType void_type;
 
   ast::Function func("main", {}, &void_type);
-  func.add_decoration(std::make_unique<ast::StageDecoration>(
-      ast::PipelineStage::kVertex, Source{}));
+  func.add_decoration(
+      create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
 
   ASSERT_TRUE(b.GenerateFunction(&func)) << b.error();
   EXPECT_EQ(DumpInstructions(b.entry_points()),
@@ -67,8 +67,7 @@
   ast::type::VoidType void_type;
 
   ast::Function func("main", {}, &void_type);
-  func.add_decoration(
-      std::make_unique<ast::StageDecoration>(params.stage, Source{}));
+  func.add_decoration(create<ast::StageDecoration>(params.stage, Source{}));
 
   ASSERT_TRUE(b.GenerateFunction(&func)) << b.error();
 
@@ -94,14 +93,13 @@
   ast::type::VoidType void_type;
 
   ast::Function func("main", {}, &void_type);
-  func.add_decoration(std::make_unique<ast::StageDecoration>(
-      ast::PipelineStage::kVertex, Source{}));
-  auto v_in =
-      std::make_unique<ast::Variable>("my_in", ast::StorageClass::kInput, &f32);
-  auto v_out = std::make_unique<ast::Variable>(
-      "my_out", ast::StorageClass::kOutput, &f32);
-  auto v_wg = std::make_unique<ast::Variable>(
-      "my_wg", ast::StorageClass::kWorkgroup, &f32);
+  func.add_decoration(
+      create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
+  auto v_in = create<ast::Variable>("my_in", ast::StorageClass::kInput, &f32);
+  auto v_out =
+      create<ast::Variable>("my_out", ast::StorageClass::kOutput, &f32);
+  auto v_wg =
+      create<ast::Variable>("my_wg", ast::StorageClass::kWorkgroup, &f32);
 
   EXPECT_TRUE(b.GenerateGlobalVariable(v_in.get())) << b.error();
   EXPECT_TRUE(b.GenerateGlobalVariable(v_out.get())) << b.error();
@@ -138,28 +136,27 @@
   ast::type::VoidType void_type;
 
   ast::Function func("main", {}, &void_type);
-  func.add_decoration(std::make_unique<ast::StageDecoration>(
-      ast::PipelineStage::kVertex, Source{}));
+  func.add_decoration(
+      create<ast::StageDecoration>(ast::PipelineStage::kVertex, Source{}));
 
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("my_out"),
-      std::make_unique<ast::IdentifierExpression>("my_in")));
-  body->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("my_wg"),
-      std::make_unique<ast::IdentifierExpression>("my_wg")));
+  auto body = create<ast::BlockStatement>();
+  body->append(create<ast::AssignmentStatement>(
+      create<ast::IdentifierExpression>("my_out"),
+      create<ast::IdentifierExpression>("my_in")));
+  body->append(create<ast::AssignmentStatement>(
+      create<ast::IdentifierExpression>("my_wg"),
+      create<ast::IdentifierExpression>("my_wg")));
   // Add duplicate usages so we show they don't get output multiple times.
-  body->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("my_out"),
-      std::make_unique<ast::IdentifierExpression>("my_in")));
+  body->append(create<ast::AssignmentStatement>(
+      create<ast::IdentifierExpression>("my_out"),
+      create<ast::IdentifierExpression>("my_in")));
   func.set_body(std::move(body));
 
-  auto v_in =
-      std::make_unique<ast::Variable>("my_in", ast::StorageClass::kInput, &f32);
-  auto v_out = std::make_unique<ast::Variable>(
-      "my_out", ast::StorageClass::kOutput, &f32);
-  auto v_wg = std::make_unique<ast::Variable>(
-      "my_wg", ast::StorageClass::kWorkgroup, &f32);
+  auto v_in = create<ast::Variable>("my_in", ast::StorageClass::kInput, &f32);
+  auto v_out =
+      create<ast::Variable>("my_out", ast::StorageClass::kOutput, &f32);
+  auto v_wg =
+      create<ast::Variable>("my_wg", ast::StorageClass::kWorkgroup, &f32);
 
   td.RegisterVariableForTesting(v_in.get());
   td.RegisterVariableForTesting(v_out.get());
@@ -201,8 +198,8 @@
   ast::type::VoidType void_type;
 
   ast::Function func("main", {}, &void_type);
-  func.add_decoration(std::make_unique<ast::StageDecoration>(
-      ast::PipelineStage::kFragment, Source{}));
+  func.add_decoration(
+      create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
   ASSERT_TRUE(b.GenerateExecutionModes(&func, 3)) << b.error();
   EXPECT_EQ(DumpInstructions(b.execution_modes()),
@@ -214,8 +211,8 @@
   ast::type::VoidType void_type;
 
   ast::Function func("main", {}, &void_type);
-  func.add_decoration(std::make_unique<ast::StageDecoration>(
-      ast::PipelineStage::kCompute, Source{}));
+  func.add_decoration(
+      create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
 
   ASSERT_TRUE(b.GenerateExecutionModes(&func, 3)) << b.error();
   EXPECT_EQ(DumpInstructions(b.execution_modes()),
@@ -227,10 +224,9 @@
   ast::type::VoidType void_type;
 
   ast::Function func("main", {}, &void_type);
+  func.add_decoration(create<ast::WorkgroupDecoration>(2u, 4u, 6u, Source{}));
   func.add_decoration(
-      std::make_unique<ast::WorkgroupDecoration>(2u, 4u, 6u, Source{}));
-  func.add_decoration(std::make_unique<ast::StageDecoration>(
-      ast::PipelineStage::kCompute, Source{}));
+      create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
 
   ASSERT_TRUE(b.GenerateExecutionModes(&func, 3)) << b.error();
   EXPECT_EQ(DumpInstructions(b.execution_modes()),
@@ -242,12 +238,12 @@
   ast::type::VoidType void_type;
 
   ast::Function func1("main1", {}, &void_type);
-  func1.add_decoration(std::make_unique<ast::StageDecoration>(
-      ast::PipelineStage::kFragment, Source{}));
+  func1.add_decoration(
+      create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
   ast::Function func2("main2", {}, &void_type);
-  func2.add_decoration(std::make_unique<ast::StageDecoration>(
-      ast::PipelineStage::kFragment, Source{}));
+  func2.add_decoration(
+      create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
 
   ASSERT_TRUE(b.GenerateFunction(&func1)) << b.error();
   ASSERT_TRUE(b.GenerateFunction(&func2)) << b.error();
diff --git a/src/writer/spirv/builder_function_test.cc b/src/writer/spirv/builder_function_test.cc
index 98380d5..e7549f7 100644
--- a/src/writer/spirv/builder_function_test.cc
+++ b/src/writer/spirv/builder_function_test.cc
@@ -69,20 +69,18 @@
   ast::type::I32Type i32;
 
   ast::VariableList params;
-  auto var_a =
-      std::make_unique<ast::Variable>("a", ast::StorageClass::kFunction, &f32);
+  auto var_a = create<ast::Variable>("a", ast::StorageClass::kFunction, &f32);
   var_a->set_is_const(true);
   params.push_back(std::move(var_a));
-  auto var_b =
-      std::make_unique<ast::Variable>("b", ast::StorageClass::kFunction, &i32);
+  auto var_b = create<ast::Variable>("b", ast::StorageClass::kFunction, &i32);
   var_b->set_is_const(true);
   params.push_back(std::move(var_b));
 
   ast::Function func("a_func", std::move(params), &f32);
 
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<ast::ReturnStatement>(
-      std::make_unique<ast::IdentifierExpression>("a")));
+  auto body = create<ast::BlockStatement>();
+  body->append(
+      create<ast::ReturnStatement>(create<ast::IdentifierExpression>("a")));
   func.set_body(std::move(body));
 
   td.RegisterVariableForTesting(func.params()[0].get());
@@ -108,8 +106,8 @@
 TEST_F(BuilderTest, Function_WithBody) {
   ast::type::VoidType void_type;
 
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<ast::ReturnStatement>());
+  auto body = create<ast::BlockStatement>();
+  body->append(create<ast::ReturnStatement>());
 
   ast::Function func("a_func", {}, &void_type);
   func.set_body(std::move(body));
@@ -169,27 +167,23 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList a_deco;
-  a_deco.push_back(
-      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
-  members.push_back(
-      std::make_unique<ast::StructMember>("d", &f32, std::move(a_deco)));
+  a_deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
+  members.push_back(create<ast::StructMember>("d", &f32, std::move(a_deco)));
 
   ast::StructDecorationList s_decos;
-  s_decos.push_back(std::make_unique<ast::StructBlockDecoration>(Source{}));
+  s_decos.push_back(create<ast::StructBlockDecoration>(Source{}));
 
-  auto str =
-      std::make_unique<ast::Struct>(std::move(s_decos), std::move(members));
+  auto str = create<ast::Struct>(std::move(s_decos), std::move(members));
 
   ast::type::StructType s("Data", std::move(str));
   ast::type::AccessControlType ac(ast::AccessControl::kReadWrite, &s);
 
-  auto data_var =
-      std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
-          "data", ast::StorageClass::kStorageBuffer, &ac));
+  auto data_var = create<ast::DecoratedVariable>(
+      create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &ac));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::BindingDecoration>(0, Source{}));
-  decos.push_back(std::make_unique<ast::SetDecoration>(0, Source{}));
+  decos.push_back(create<ast::BindingDecoration>(0, Source{}));
+  decos.push_back(create<ast::SetDecoration>(0, Source{}));
   data_var->set_decorations(std::move(decos));
 
   mod.AddConstructedType(&s);
@@ -199,20 +193,18 @@
 
   {
     ast::VariableList params;
-    auto func =
-        std::make_unique<ast::Function>("a", std::move(params), &void_type);
-    func->add_decoration(std::make_unique<ast::StageDecoration>(
-        ast::PipelineStage::kCompute, Source{}));
+    auto func = create<ast::Function>("a", std::move(params), &void_type);
+    func->add_decoration(
+        create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
 
-    auto var = std::make_unique<ast::Variable>(
-        "v", ast::StorageClass::kFunction, &f32);
-    var->set_constructor(std::make_unique<ast::MemberAccessorExpression>(
-        std::make_unique<ast::IdentifierExpression>("data"),
-        std::make_unique<ast::IdentifierExpression>("d")));
+    auto var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
+    var->set_constructor(create<ast::MemberAccessorExpression>(
+        create<ast::IdentifierExpression>("data"),
+        create<ast::IdentifierExpression>("d")));
 
-    auto body = std::make_unique<ast::BlockStatement>();
-    body->append(std::make_unique<ast::VariableDeclStatement>(std::move(var)));
-    body->append(std::make_unique<ast::ReturnStatement>());
+    auto body = create<ast::BlockStatement>();
+    body->append(create<ast::VariableDeclStatement>(std::move(var)));
+    body->append(create<ast::ReturnStatement>());
     func->set_body(std::move(body));
 
     mod.AddFunction(std::move(func));
@@ -220,20 +212,18 @@
 
   {
     ast::VariableList params;
-    auto func =
-        std::make_unique<ast::Function>("b", std::move(params), &void_type);
-    func->add_decoration(std::make_unique<ast::StageDecoration>(
-        ast::PipelineStage::kCompute, Source{}));
+    auto func = create<ast::Function>("b", std::move(params), &void_type);
+    func->add_decoration(
+        create<ast::StageDecoration>(ast::PipelineStage::kCompute, Source{}));
 
-    auto var = std::make_unique<ast::Variable>(
-        "v", ast::StorageClass::kFunction, &f32);
-    var->set_constructor(std::make_unique<ast::MemberAccessorExpression>(
-        std::make_unique<ast::IdentifierExpression>("data"),
-        std::make_unique<ast::IdentifierExpression>("d")));
+    auto var = create<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
+    var->set_constructor(create<ast::MemberAccessorExpression>(
+        create<ast::IdentifierExpression>("data"),
+        create<ast::IdentifierExpression>("d")));
 
-    auto body = std::make_unique<ast::BlockStatement>();
-    body->append(std::make_unique<ast::VariableDeclStatement>(std::move(var)));
-    body->append(std::make_unique<ast::ReturnStatement>());
+    auto body = create<ast::BlockStatement>();
+    body->append(create<ast::VariableDeclStatement>(std::move(var)));
+    body->append(create<ast::ReturnStatement>());
     func->set_body(std::move(body));
 
     mod.AddFunction(std::move(func));
diff --git a/src/writer/spirv/builder_function_variable_test.cc b/src/writer/spirv/builder_function_variable_test.cc
index b03429d..7702627 100644
--- a/src/writer/spirv/builder_function_variable_test.cc
+++ b/src/writer/spirv/builder_function_variable_test.cc
@@ -70,15 +70,14 @@
   ast::type::VectorType vec(&f32, 3);
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 3.0f)));
 
-  auto init =
-      std::make_unique<ast::TypeConstructorExpression>(&vec, std::move(vals));
+  auto init = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
 
   EXPECT_TRUE(td.DetermineResultType(init.get())) << td.error();
 
@@ -112,20 +111,19 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec(&f32, 2);
 
-  auto rel = std::make_unique<ast::BinaryExpression>(
-      ast::BinaryOp::kAdd,
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::FloatLiteral>(&f32, 3.0f)),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
+  auto rel =
+      create<ast::BinaryExpression>(ast::BinaryOp::kAdd,
+                                    create<ast::ScalarConstructorExpression>(
+                                        create<ast::FloatLiteral>(&f32, 3.0f)),
+                                    create<ast::ScalarConstructorExpression>(
+                                        create<ast::FloatLiteral>(&f32, 3.0f)));
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f)));
   vals.push_back(std::move(rel));
 
-  auto init =
-      std::make_unique<ast::TypeConstructorExpression>(&vec, std::move(vals));
+  auto init = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
 
   EXPECT_TRUE(td.DetermineResultType(init.get())) << td.error();
 
@@ -170,15 +168,14 @@
   ast::type::VectorType vec(&f32, 3);
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 3.0f)));
 
-  auto init =
-      std::make_unique<ast::TypeConstructorExpression>(&vec, std::move(vals));
+  auto init = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
 
   EXPECT_TRUE(td.DetermineResultType(init.get())) << td.error();
 
diff --git a/src/writer/spirv/builder_global_variable_test.cc b/src/writer/spirv/builder_global_variable_test.cc
index 288deed..ff044d5 100644
--- a/src/writer/spirv/builder_global_variable_test.cc
+++ b/src/writer/spirv/builder_global_variable_test.cc
@@ -97,15 +97,14 @@
   ast::type::VectorType vec(&f32, 3);
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 3.0f)));
 
-  auto init =
-      std::make_unique<ast::TypeConstructorExpression>(&vec, std::move(vals));
+  auto init = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
 
   EXPECT_TRUE(td.DetermineResultType(init.get())) << td.error();
 
@@ -133,15 +132,14 @@
   ast::type::VectorType vec(&f32, 3);
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 3.0f)));
 
-  auto init =
-      std::make_unique<ast::TypeConstructorExpression>(&vec, std::move(vals));
+  auto init = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
 
   EXPECT_TRUE(td.DetermineResultType(init.get())) << td.error();
 
@@ -168,14 +166,13 @@
   ast::type::VectorType vec3(&f32, 3);
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
-  auto init =
-      std::make_unique<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 3.0f)));
+  auto init = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   EXPECT_TRUE(td.DetermineResultType(init.get())) << td.error();
 
@@ -202,19 +199,17 @@
   ast::type::VectorType vec2(&f32, 2);
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0f)));
-  auto first =
-      std::make_unique<ast::TypeConstructorExpression>(&vec2, std::move(vals));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0f)));
+  auto first = create<ast::TypeConstructorExpression>(&vec2, std::move(vals));
 
   vals.push_back(std::move(first));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 3.0f)));
 
-  auto init =
-      std::make_unique<ast::TypeConstructorExpression>(&vec3, std::move(vals));
+  auto init = create<ast::TypeConstructorExpression>(&vec3, std::move(vals));
 
   EXPECT_TRUE(td.DetermineResultType(init.get())) << td.error();
 
@@ -244,10 +239,9 @@
 
 TEST_F(BuilderTest, GlobalVar_WithLocation) {
   ast::type::F32Type f32;
-  auto v =
-      std::make_unique<ast::Variable>("var", ast::StorageClass::kOutput, &f32);
+  auto v = create<ast::Variable>("var", ast::StorageClass::kOutput, &f32);
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::LocationDecoration>(5, Source{}));
+  decos.push_back(create<ast::LocationDecoration>(5, Source{}));
 
   ast::DecoratedVariable dv(std::move(v));
   dv.set_decorations(std::move(decos));
@@ -266,11 +260,10 @@
 
 TEST_F(BuilderTest, GlobalVar_WithBindingAndSet) {
   ast::type::F32Type f32;
-  auto v =
-      std::make_unique<ast::Variable>("var", ast::StorageClass::kOutput, &f32);
+  auto v = create<ast::Variable>("var", ast::StorageClass::kOutput, &f32);
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::BindingDecoration>(2, Source{}));
-  decos.push_back(std::make_unique<ast::SetDecoration>(3, Source{}));
+  decos.push_back(create<ast::BindingDecoration>(2, Source{}));
+  decos.push_back(create<ast::SetDecoration>(3, Source{}));
 
   ast::DecoratedVariable dv(std::move(v));
   dv.set_decorations(std::move(decos));
@@ -290,11 +283,10 @@
 
 TEST_F(BuilderTest, GlobalVar_WithBuiltin) {
   ast::type::F32Type f32;
-  auto v =
-      std::make_unique<ast::Variable>("var", ast::StorageClass::kOutput, &f32);
+  auto v = create<ast::Variable>("var", ast::StorageClass::kOutput, &f32);
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::BuiltinDecoration>(
-      ast::Builtin::kPosition, Source{}));
+  decos.push_back(
+      create<ast::BuiltinDecoration>(ast::Builtin::kPosition, Source{}));
 
   ast::DecoratedVariable dv(std::move(v));
   dv.set_decorations(std::move(decos));
@@ -315,13 +307,13 @@
   ast::type::BoolType bool_type;
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(1200, Source{}));
+  decos.push_back(create<ast::ConstantIdDecoration>(1200, Source{}));
 
-  ast::DecoratedVariable v(std::make_unique<ast::Variable>(
-      "var", ast::StorageClass::kNone, &bool_type));
+  ast::DecoratedVariable v(
+      create<ast::Variable>("var", ast::StorageClass::kNone, &bool_type));
   v.set_decorations(std::move(decos));
-  v.set_constructor(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::BoolLiteral>(&bool_type, true)));
+  v.set_constructor(create<ast::ScalarConstructorExpression>(
+      create<ast::BoolLiteral>(&bool_type, true)));
 
   EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "tint_766172"
@@ -339,10 +331,10 @@
   ast::type::BoolType bool_type;
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(1200, Source{}));
+  decos.push_back(create<ast::ConstantIdDecoration>(1200, Source{}));
 
-  ast::DecoratedVariable v(std::make_unique<ast::Variable>(
-      "var", ast::StorageClass::kNone, &bool_type));
+  ast::DecoratedVariable v(
+      create<ast::Variable>("var", ast::StorageClass::kNone, &bool_type));
   v.set_decorations(std::move(decos));
 
   EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
@@ -361,13 +353,13 @@
   ast::type::F32Type f32;
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(0, Source{}));
+  decos.push_back(create<ast::ConstantIdDecoration>(0, Source{}));
 
   ast::DecoratedVariable v(
-      std::make_unique<ast::Variable>("var", ast::StorageClass::kNone, &f32));
+      create<ast::Variable>("var", ast::StorageClass::kNone, &f32));
   v.set_decorations(std::move(decos));
-  v.set_constructor(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+  v.set_constructor(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 2.0)));
 
   EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
   EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "tint_766172"
@@ -385,10 +377,10 @@
   ast::type::F32Type f32;
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(0, Source{}));
+  decos.push_back(create<ast::ConstantIdDecoration>(0, Source{}));
 
   ast::DecoratedVariable v(
-      std::make_unique<ast::Variable>("var", ast::StorageClass::kNone, &f32));
+      create<ast::Variable>("var", ast::StorageClass::kNone, &f32));
   v.set_decorations(std::move(decos));
 
   EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
@@ -407,10 +399,10 @@
   ast::type::I32Type i32;
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(0, Source{}));
+  decos.push_back(create<ast::ConstantIdDecoration>(0, Source{}));
 
   ast::DecoratedVariable v(
-      std::make_unique<ast::Variable>("var", ast::StorageClass::kNone, &i32));
+      create<ast::Variable>("var", ast::StorageClass::kNone, &i32));
   v.set_decorations(std::move(decos));
 
   EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
@@ -429,10 +421,10 @@
   ast::type::U32Type u32;
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(0, Source{}));
+  decos.push_back(create<ast::ConstantIdDecoration>(0, Source{}));
 
   ast::DecoratedVariable v(
-      std::make_unique<ast::Variable>("var", ast::StorageClass::kNone, &u32));
+      create<ast::Variable>("var", ast::StorageClass::kNone, &u32));
   v.set_decorations(std::move(decos));
 
   EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
@@ -491,13 +483,10 @@
 
   ast::StructMemberDecorationList decos;
   ast::StructMemberList members;
-  members.push_back(
-      std::make_unique<ast::StructMember>("a", &i32, std::move(decos)));
-  members.push_back(
-      std::make_unique<ast::StructMember>("b", &i32, std::move(decos)));
+  members.push_back(create<ast::StructMember>("a", &i32, std::move(decos)));
+  members.push_back(create<ast::StructMember>("b", &i32, std::move(decos)));
 
-  ast::type::StructType A("A",
-                          std::make_unique<ast::Struct>(std::move(members)));
+  ast::type::StructType A("A", create<ast::Struct>(std::move(members)));
   ast::type::AccessControlType ac{ast::AccessControl::kReadOnly, &A};
 
   ast::Variable var("b", ast::StorageClass::kStorageBuffer, &ac);
@@ -530,11 +519,9 @@
 
   ast::StructMemberDecorationList decos;
   ast::StructMemberList members;
-  members.push_back(
-      std::make_unique<ast::StructMember>("a", &i32, std::move(decos)));
+  members.push_back(create<ast::StructMember>("a", &i32, std::move(decos)));
 
-  ast::type::StructType A("A",
-                          std::make_unique<ast::Struct>(std::move(members)));
+  ast::type::StructType A("A", create<ast::Struct>(std::move(members)));
   ast::type::AliasType B("B", &A);
   ast::type::AccessControlType ac{ast::AccessControl::kReadOnly, &B};
 
@@ -566,11 +553,9 @@
 
   ast::StructMemberDecorationList decos;
   ast::StructMemberList members;
-  members.push_back(
-      std::make_unique<ast::StructMember>("a", &i32, std::move(decos)));
+  members.push_back(create<ast::StructMember>("a", &i32, std::move(decos)));
 
-  ast::type::StructType A("A",
-                          std::make_unique<ast::Struct>(std::move(members)));
+  ast::type::StructType A("A", create<ast::Struct>(std::move(members)));
   ast::type::AccessControlType ac{ast::AccessControl::kReadOnly, &A};
   ast::type::AliasType B("B", &ac);
 
@@ -602,11 +587,9 @@
 
   ast::StructMemberDecorationList decos;
   ast::StructMemberList members;
-  members.push_back(
-      std::make_unique<ast::StructMember>("a", &i32, std::move(decos)));
+  members.push_back(create<ast::StructMember>("a", &i32, std::move(decos)));
 
-  ast::type::StructType A("A",
-                          std::make_unique<ast::Struct>(std::move(members)));
+  ast::type::StructType A("A", create<ast::Struct>(std::move(members)));
   ast::type::AccessControlType read{ast::AccessControl::kReadOnly, &A};
   ast::type::AccessControlType rw{ast::AccessControl::kReadWrite, &A};
 
diff --git a/src/writer/spirv/builder_ident_expression_test.cc b/src/writer/spirv/builder_ident_expression_test.cc
index ee2939b..8014183 100644
--- a/src/writer/spirv/builder_ident_expression_test.cc
+++ b/src/writer/spirv/builder_ident_expression_test.cc
@@ -43,15 +43,14 @@
   ast::type::VectorType vec(&f32, 3);
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 3.0f)));
 
-  auto init =
-      std::make_unique<ast::TypeConstructorExpression>(&vec, std::move(vals));
+  auto init = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
 
   EXPECT_TRUE(td.DetermineResultType(init.get())) << td.error();
 
@@ -103,15 +102,14 @@
   ast::type::VectorType vec(&f32, 3);
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 3.0f)));
 
-  auto init =
-      std::make_unique<ast::TypeConstructorExpression>(&vec, std::move(vals));
+  auto init = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
 
   EXPECT_TRUE(td.DetermineResultType(init.get())) << td.error();
 
@@ -167,8 +165,8 @@
 
   td.RegisterVariableForTesting(&var);
 
-  auto lhs = std::make_unique<ast::IdentifierExpression>("var");
-  auto rhs = std::make_unique<ast::IdentifierExpression>("var");
+  auto lhs = create<ast::IdentifierExpression>("var");
+  auto rhs = create<ast::IdentifierExpression>("var");
 
   ast::BinaryExpression expr(ast::BinaryOp::kAdd, std::move(lhs),
                              std::move(rhs));
@@ -195,14 +193,14 @@
   ast::type::I32Type i32;
 
   ast::Variable var("var", ast::StorageClass::kNone, &i32);
-  var.set_constructor(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 2)));
+  var.set_constructor(create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 2)));
   var.set_is_const(true);
 
   td.RegisterVariableForTesting(&var);
 
-  auto lhs = std::make_unique<ast::IdentifierExpression>("var");
-  auto rhs = std::make_unique<ast::IdentifierExpression>("var");
+  auto lhs = create<ast::IdentifierExpression>("var");
+  auto rhs = create<ast::IdentifierExpression>("var");
 
   ast::BinaryExpression expr(ast::BinaryOp::kAdd, std::move(lhs),
                              std::move(rhs));
diff --git a/src/writer/spirv/builder_if_test.cc b/src/writer/spirv/builder_if_test.cc
index ae85486..e86a6ac 100644
--- a/src/writer/spirv/builder_if_test.cc
+++ b/src/writer/spirv/builder_if_test.cc
@@ -46,11 +46,10 @@
 
   // if (true) {
   // }
-  auto cond = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::BoolLiteral>(&bool_type, true));
+  auto cond = create<ast::ScalarConstructorExpression>(
+      create<ast::BoolLiteral>(&bool_type, true));
 
-  ast::IfStatement expr(std::move(cond),
-                        std::make_unique<ast::BlockStatement>());
+  ast::IfStatement expr(std::move(cond), create<ast::BlockStatement>());
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
@@ -76,17 +75,16 @@
   // if (true) {
   //   v = 2;
   // }
-  auto var =
-      std::make_unique<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
+  auto var = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
 
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("v"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 2))));
+  auto body = create<ast::BlockStatement>();
+  body->append(
+      create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
+                                       create<ast::ScalarConstructorExpression>(
+                                           create<ast::SintLiteral>(&i32, 2))));
 
-  auto cond = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::BoolLiteral>(&bool_type, true));
+  auto cond = create<ast::ScalarConstructorExpression>(
+      create<ast::BoolLiteral>(&bool_type, true));
 
   ast::IfStatement expr(std::move(cond), std::move(body));
 
@@ -124,27 +122,25 @@
   // } else {
   //   v = 3;
   // }
-  auto var =
-      std::make_unique<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
+  auto var = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
 
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("v"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 2))));
+  auto body = create<ast::BlockStatement>();
+  body->append(
+      create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
+                                       create<ast::ScalarConstructorExpression>(
+                                           create<ast::SintLiteral>(&i32, 2))));
 
-  auto else_body = std::make_unique<ast::BlockStatement>();
-  else_body->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("v"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 3))));
+  auto else_body = create<ast::BlockStatement>();
+  else_body->append(
+      create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
+                                       create<ast::ScalarConstructorExpression>(
+                                           create<ast::SintLiteral>(&i32, 3))));
 
   ast::ElseStatementList else_stmts;
-  else_stmts.push_back(
-      std::make_unique<ast::ElseStatement>(std::move(else_body)));
+  else_stmts.push_back(create<ast::ElseStatement>(std::move(else_body)));
 
-  auto cond = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::BoolLiteral>(&bool_type, true));
+  auto cond = create<ast::ScalarConstructorExpression>(
+      create<ast::BoolLiteral>(&bool_type, true));
 
   ast::IfStatement expr(std::move(cond), std::move(body));
   expr.set_else_statements(std::move(else_stmts));
@@ -188,30 +184,29 @@
   // } elseif (true) {
   //   v = 3;
   // }
-  auto var =
-      std::make_unique<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
+  auto var = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
 
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("v"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 2))));
+  auto body = create<ast::BlockStatement>();
+  body->append(
+      create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
+                                       create<ast::ScalarConstructorExpression>(
+                                           create<ast::SintLiteral>(&i32, 2))));
 
-  auto else_body = std::make_unique<ast::BlockStatement>();
-  else_body->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("v"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 3))));
+  auto else_body = create<ast::BlockStatement>();
+  else_body->append(
+      create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
+                                       create<ast::ScalarConstructorExpression>(
+                                           create<ast::SintLiteral>(&i32, 3))));
 
-  auto else_cond = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::BoolLiteral>(&bool_type, true));
+  auto else_cond = create<ast::ScalarConstructorExpression>(
+      create<ast::BoolLiteral>(&bool_type, true));
 
   ast::ElseStatementList else_stmts;
-  else_stmts.push_back(std::make_unique<ast::ElseStatement>(
-      std::move(else_cond), std::move(else_body)));
+  else_stmts.push_back(
+      create<ast::ElseStatement>(std::move(else_cond), std::move(else_body)));
 
-  auto cond = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::BoolLiteral>(&bool_type, true));
+  auto cond = create<ast::ScalarConstructorExpression>(
+      create<ast::BoolLiteral>(&bool_type, true));
 
   ast::IfStatement expr(std::move(cond), std::move(body));
   expr.set_else_statements(std::move(else_stmts));
@@ -264,45 +259,43 @@
   // } else {
   //   v = 5;
   // }
-  auto var =
-      std::make_unique<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
+  auto var = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
 
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("v"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 2))));
-  auto elseif_1_body = std::make_unique<ast::BlockStatement>();
-  elseif_1_body->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("v"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 3))));
-  auto elseif_2_body = std::make_unique<ast::BlockStatement>();
-  elseif_2_body->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("v"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 4))));
-  auto else_body = std::make_unique<ast::BlockStatement>();
-  else_body->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("v"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 5))));
+  auto body = create<ast::BlockStatement>();
+  body->append(
+      create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
+                                       create<ast::ScalarConstructorExpression>(
+                                           create<ast::SintLiteral>(&i32, 2))));
+  auto elseif_1_body = create<ast::BlockStatement>();
+  elseif_1_body->append(
+      create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
+                                       create<ast::ScalarConstructorExpression>(
+                                           create<ast::SintLiteral>(&i32, 3))));
+  auto elseif_2_body = create<ast::BlockStatement>();
+  elseif_2_body->append(
+      create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
+                                       create<ast::ScalarConstructorExpression>(
+                                           create<ast::SintLiteral>(&i32, 4))));
+  auto else_body = create<ast::BlockStatement>();
+  else_body->append(
+      create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
+                                       create<ast::ScalarConstructorExpression>(
+                                           create<ast::SintLiteral>(&i32, 5))));
 
-  auto elseif_1_cond = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::BoolLiteral>(&bool_type, true));
-  auto elseif_2_cond = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::BoolLiteral>(&bool_type, false));
+  auto elseif_1_cond = create<ast::ScalarConstructorExpression>(
+      create<ast::BoolLiteral>(&bool_type, true));
+  auto elseif_2_cond = create<ast::ScalarConstructorExpression>(
+      create<ast::BoolLiteral>(&bool_type, false));
 
   ast::ElseStatementList else_stmts;
-  else_stmts.push_back(std::make_unique<ast::ElseStatement>(
-      std::move(elseif_1_cond), std::move(elseif_1_body)));
-  else_stmts.push_back(std::make_unique<ast::ElseStatement>(
-      std::move(elseif_2_cond), std::move(elseif_2_body)));
-  else_stmts.push_back(
-      std::make_unique<ast::ElseStatement>(std::move(else_body)));
+  else_stmts.push_back(create<ast::ElseStatement>(std::move(elseif_1_cond),
+                                                  std::move(elseif_1_body)));
+  else_stmts.push_back(create<ast::ElseStatement>(std::move(elseif_2_cond),
+                                                  std::move(elseif_2_body)));
+  else_stmts.push_back(create<ast::ElseStatement>(std::move(else_body)));
 
-  auto cond = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::BoolLiteral>(&bool_type, true));
+  auto cond = create<ast::ScalarConstructorExpression>(
+      create<ast::BoolLiteral>(&bool_type, true));
 
   ast::IfStatement expr(std::move(cond), std::move(body));
   expr.set_else_statements(std::move(else_stmts));
@@ -363,20 +356,18 @@
   //     break;
   //   }
   // }
-  auto cond = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::BoolLiteral>(&bool_type, true));
+  auto cond = create<ast::ScalarConstructorExpression>(
+      create<ast::BoolLiteral>(&bool_type, true));
 
-  auto if_body = std::make_unique<ast::BlockStatement>();
-  if_body->append(std::make_unique<ast::BreakStatement>());
+  auto if_body = create<ast::BlockStatement>();
+  if_body->append(create<ast::BreakStatement>());
 
-  auto if_stmt =
-      std::make_unique<ast::IfStatement>(std::move(cond), std::move(if_body));
+  auto if_stmt = create<ast::IfStatement>(std::move(cond), std::move(if_body));
 
-  auto loop_body = std::make_unique<ast::BlockStatement>();
+  auto loop_body = create<ast::BlockStatement>();
   loop_body->append(std::move(if_stmt));
 
-  ast::LoopStatement expr(std::move(loop_body),
-                          std::make_unique<ast::BlockStatement>());
+  ast::LoopStatement expr(std::move(loop_body), create<ast::BlockStatement>());
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
@@ -412,25 +403,23 @@
   //     break;
   //   }
   // }
-  auto cond = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::BoolLiteral>(&bool_type, true));
+  auto cond = create<ast::ScalarConstructorExpression>(
+      create<ast::BoolLiteral>(&bool_type, true));
 
-  auto else_body = std::make_unique<ast::BlockStatement>();
-  else_body->append(std::make_unique<ast::BreakStatement>());
+  auto else_body = create<ast::BlockStatement>();
+  else_body->append(create<ast::BreakStatement>());
 
   ast::ElseStatementList else_stmts;
-  else_stmts.push_back(
-      std::make_unique<ast::ElseStatement>(std::move(else_body)));
+  else_stmts.push_back(create<ast::ElseStatement>(std::move(else_body)));
 
-  auto if_stmt = std::make_unique<ast::IfStatement>(
-      std::move(cond), std::make_unique<ast::BlockStatement>());
+  auto if_stmt =
+      create<ast::IfStatement>(std::move(cond), create<ast::BlockStatement>());
   if_stmt->set_else_statements(std::move(else_stmts));
 
-  auto loop_body = std::make_unique<ast::BlockStatement>();
+  auto loop_body = create<ast::BlockStatement>();
   loop_body->append(std::move(if_stmt));
 
-  ast::LoopStatement expr(std::move(loop_body),
-                          std::make_unique<ast::BlockStatement>());
+  ast::LoopStatement expr(std::move(loop_body), create<ast::BlockStatement>());
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
@@ -467,20 +456,18 @@
   //     continue;
   //   }
   // }
-  auto cond = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::BoolLiteral>(&bool_type, true));
+  auto cond = create<ast::ScalarConstructorExpression>(
+      create<ast::BoolLiteral>(&bool_type, true));
 
-  auto if_body = std::make_unique<ast::BlockStatement>();
-  if_body->append(std::make_unique<ast::ContinueStatement>());
+  auto if_body = create<ast::BlockStatement>();
+  if_body->append(create<ast::ContinueStatement>());
 
-  auto if_stmt =
-      std::make_unique<ast::IfStatement>(std::move(cond), std::move(if_body));
+  auto if_stmt = create<ast::IfStatement>(std::move(cond), std::move(if_body));
 
-  auto loop_body = std::make_unique<ast::BlockStatement>();
+  auto loop_body = create<ast::BlockStatement>();
   loop_body->append(std::move(if_stmt));
 
-  ast::LoopStatement expr(std::move(loop_body),
-                          std::make_unique<ast::BlockStatement>());
+  ast::LoopStatement expr(std::move(loop_body), create<ast::BlockStatement>());
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
@@ -516,25 +503,23 @@
   //     continue;
   //   }
   // }
-  auto cond = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::BoolLiteral>(&bool_type, true));
+  auto cond = create<ast::ScalarConstructorExpression>(
+      create<ast::BoolLiteral>(&bool_type, true));
 
-  auto else_body = std::make_unique<ast::BlockStatement>();
-  else_body->append(std::make_unique<ast::ContinueStatement>());
+  auto else_body = create<ast::BlockStatement>();
+  else_body->append(create<ast::ContinueStatement>());
 
   ast::ElseStatementList else_stmts;
-  else_stmts.push_back(
-      std::make_unique<ast::ElseStatement>(std::move(else_body)));
+  else_stmts.push_back(create<ast::ElseStatement>(std::move(else_body)));
 
-  auto if_stmt = std::make_unique<ast::IfStatement>(
-      std::move(cond), std::make_unique<ast::BlockStatement>());
+  auto if_stmt =
+      create<ast::IfStatement>(std::move(cond), create<ast::BlockStatement>());
   if_stmt->set_else_statements(std::move(else_stmts));
 
-  auto loop_body = std::make_unique<ast::BlockStatement>();
+  auto loop_body = create<ast::BlockStatement>();
   loop_body->append(std::move(if_stmt));
 
-  ast::LoopStatement expr(std::move(loop_body),
-                          std::make_unique<ast::BlockStatement>());
+  ast::LoopStatement expr(std::move(loop_body), create<ast::BlockStatement>());
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
@@ -569,11 +554,11 @@
   // if (true) {
   //   return;
   // }
-  auto cond = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::BoolLiteral>(&bool_type, true));
+  auto cond = create<ast::ScalarConstructorExpression>(
+      create<ast::BoolLiteral>(&bool_type, true));
 
-  auto if_body = std::make_unique<ast::BlockStatement>();
-  if_body->append(std::make_unique<ast::ReturnStatement>());
+  auto if_body = create<ast::BlockStatement>();
+  if_body->append(create<ast::ReturnStatement>());
 
   ast::IfStatement expr(std::move(cond), std::move(if_body));
 
@@ -599,13 +584,13 @@
   // if (true) {
   //   return false;
   // }
-  auto cond = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::BoolLiteral>(&bool_type, true));
-  auto cond2 = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::BoolLiteral>(&bool_type, false));
+  auto cond = create<ast::ScalarConstructorExpression>(
+      create<ast::BoolLiteral>(&bool_type, true));
+  auto cond2 = create<ast::ScalarConstructorExpression>(
+      create<ast::BoolLiteral>(&bool_type, false));
 
-  auto if_body = std::make_unique<ast::BlockStatement>();
-  if_body->append(std::make_unique<ast::ReturnStatement>(std::move(cond2)));
+  auto if_body = create<ast::BlockStatement>();
+  if_body->append(create<ast::ReturnStatement>(std::move(cond2)));
 
   ast::IfStatement expr(std::move(cond), std::move(if_body));
 
diff --git a/src/writer/spirv/builder_intrinsic_test.cc b/src/writer/spirv/builder_intrinsic_test.cc
index 04767d7..033d83a 100644
--- a/src/writer/spirv/builder_intrinsic_test.cc
+++ b/src/writer/spirv/builder_intrinsic_test.cc
@@ -64,6 +64,13 @@
     return var;
   }
 
+  /// @return a `std::unique_ptr` to a new `T` constructed with `args`
+  /// @param args the arguments to forward to the constructor for `T`
+  template <typename T, typename... ARGS>
+  std::unique_ptr<T> create(ARGS&&... args) {
+    return std::make_unique<T>(std::forward<ARGS>(args)...);
+  }
+
   Context ctx;
   ast::Module mod;
   TypeDeterminer td{&ctx, &mod};
@@ -1706,17 +1713,15 @@
 
   ast::StructMemberDecorationList decos;
   ast::StructMemberList members;
-  members.push_back(
-      std::make_unique<ast::StructMember>("a", &ary, std::move(decos)));
+  members.push_back(create<ast::StructMember>("a", &ary, std::move(decos)));
 
-  auto s = std::make_unique<ast::Struct>(std::move(members));
+  auto s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("my_struct", std::move(s));
 
   auto var = make_var("b", ast::StorageClass::kPrivate, &s_type);
 
-  auto expr =
-      call_expr("arrayLength", std::make_unique<ast::MemberAccessorExpression>(
-                                   make_expr("b"), make_expr("a")));
+  auto expr = call_expr("arrayLength", create<ast::MemberAccessorExpression>(
+                                           make_expr("b"), make_expr("a")));
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
@@ -1748,18 +1753,15 @@
 
   ast::StructMemberDecorationList decos;
   ast::StructMemberList members;
-  members.push_back(
-      std::make_unique<ast::StructMember>("z", f32(), std::move(decos)));
-  members.push_back(
-      std::make_unique<ast::StructMember>("a", &ary, std::move(decos)));
+  members.push_back(create<ast::StructMember>("z", f32(), std::move(decos)));
+  members.push_back(create<ast::StructMember>("a", &ary, std::move(decos)));
 
-  auto s = std::make_unique<ast::Struct>(std::move(members));
+  auto s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("my_struct", std::move(s));
 
   auto var = make_var("b", ast::StorageClass::kPrivate, &s_type);
-  auto expr =
-      call_expr("arrayLength", std::make_unique<ast::MemberAccessorExpression>(
-                                   make_expr("b"), make_expr("a")));
+  auto expr = call_expr("arrayLength", create<ast::MemberAccessorExpression>(
+                                           make_expr("b"), make_expr("a")));
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
@@ -1793,19 +1795,17 @@
 
   ast::StructMemberDecorationList decos;
   ast::StructMemberList members;
-  members.push_back(
-      std::make_unique<ast::StructMember>("z", f32(), std::move(decos)));
-  members.push_back(
-      std::make_unique<ast::StructMember>("a", &ary, std::move(decos)));
+  members.push_back(create<ast::StructMember>("z", f32(), std::move(decos)));
+  members.push_back(create<ast::StructMember>("a", &ary, std::move(decos)));
 
-  auto s = std::make_unique<ast::Struct>(std::move(members));
+  auto s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("my_struct", std::move(s));
 
   auto var = make_var("b", ast::StorageClass::kPrivate, &s_type);
 
   auto ptr_var = make_var("ptr_var", ast::StorageClass::kPrivate, &ptr);
-  ptr_var->set_constructor(std::make_unique<ast::MemberAccessorExpression>(
-      make_expr("b"), make_expr("a")));
+  ptr_var->set_constructor(
+      create<ast::MemberAccessorExpression>(make_expr("b"), make_expr("a")));
 
   auto expr = call_expr("arrayLength", "ptr_var");
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
diff --git a/src/writer/spirv/builder_loop_test.cc b/src/writer/spirv/builder_loop_test.cc
index d420e88..a7b265e 100644
--- a/src/writer/spirv/builder_loop_test.cc
+++ b/src/writer/spirv/builder_loop_test.cc
@@ -65,17 +65,15 @@
   // loop {
   //   v = 2;
   // }
-  auto var =
-      std::make_unique<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
+  auto var = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
 
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("v"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 2))));
+  auto body = create<ast::BlockStatement>();
+  body->append(
+      create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
+                                       create<ast::ScalarConstructorExpression>(
+                                           create<ast::SintLiteral>(&i32, 2))));
 
-  ast::LoopStatement expr(std::move(body),
-                          std::make_unique<ast::BlockStatement>());
+  ast::LoopStatement expr(std::move(body), create<ast::BlockStatement>());
 
   td.RegisterVariableForTesting(var.get());
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
@@ -113,20 +111,19 @@
   //   }
   // }
 
-  auto var =
-      std::make_unique<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
+  auto var = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
 
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("v"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 2))));
+  auto body = create<ast::BlockStatement>();
+  body->append(
+      create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
+                                       create<ast::ScalarConstructorExpression>(
+                                           create<ast::SintLiteral>(&i32, 2))));
 
-  auto continuing = std::make_unique<ast::BlockStatement>();
-  continuing->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("v"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 3))));
+  auto continuing = create<ast::BlockStatement>();
+  continuing->append(
+      create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
+                                       create<ast::ScalarConstructorExpression>(
+                                           create<ast::SintLiteral>(&i32, 3))));
   ast::LoopStatement expr(std::move(body), std::move(continuing));
 
   td.RegisterVariableForTesting(var.get());
@@ -162,11 +159,10 @@
   // loop {
   //   continue;
   // }
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<ast::ContinueStatement>());
+  auto body = create<ast::BlockStatement>();
+  body->append(create<ast::ContinueStatement>());
 
-  ast::LoopStatement expr(std::move(body),
-                          std::make_unique<ast::BlockStatement>());
+  ast::LoopStatement expr(std::move(body), create<ast::BlockStatement>());
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
@@ -190,11 +186,10 @@
   // loop {
   //   break;
   // }
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<ast::BreakStatement>());
+  auto body = create<ast::BlockStatement>();
+  body->append(create<ast::BreakStatement>());
 
-  ast::LoopStatement expr(std::move(body),
-                          std::make_unique<ast::BlockStatement>());
+  ast::LoopStatement expr(std::move(body), create<ast::BlockStatement>());
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
diff --git a/src/writer/spirv/builder_return_test.cc b/src/writer/spirv/builder_return_test.cc
index 91fe8fb..856af32 100644
--- a/src/writer/spirv/builder_return_test.cc
+++ b/src/writer/spirv/builder_return_test.cc
@@ -51,15 +51,14 @@
   ast::type::VectorType vec(&f32, 3);
 
   ast::ExpressionList vals;
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
-  vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 1.0f)));
+  vals.push_back(create<ast::ScalarConstructorExpression>(
+      create<ast::FloatLiteral>(&f32, 3.0f)));
 
-  auto val =
-      std::make_unique<ast::TypeConstructorExpression>(&vec, std::move(vals));
+  auto val = create<ast::TypeConstructorExpression>(&vec, std::move(vals));
 
   ast::ReturnStatement ret(std::move(val));
 
@@ -85,8 +84,7 @@
 
   ast::Variable var("param", ast::StorageClass::kFunction, &f32);
 
-  ast::ReturnStatement ret(
-      std::make_unique<ast::IdentifierExpression>("param"));
+  ast::ReturnStatement ret(create<ast::IdentifierExpression>("param"));
 
   td.RegisterVariableForTesting(&var);
   EXPECT_TRUE(td.DetermineResultType(&ret)) << td.error();
diff --git a/src/writer/spirv/builder_switch_test.cc b/src/writer/spirv/builder_switch_test.cc
index e7dfaaf..ed4b35e 100644
--- a/src/writer/spirv/builder_switch_test.cc
+++ b/src/writer/spirv/builder_switch_test.cc
@@ -45,8 +45,8 @@
 
   // switch (1) {
   // }
-  auto cond = std::make_unique<ast::ScalarConstructorExpression>(
-      std::make_unique<ast::SintLiteral>(&i32, 1));
+  auto cond = create<ast::ScalarConstructorExpression>(
+      create<ast::SintLiteral>(&i32, 1));
 
   ast::SwitchStatement expr(std::move(cond), ast::CaseStatementList{});
 
@@ -77,36 +77,34 @@
   //     v = 2;
   // }
 
-  auto v =
-      std::make_unique<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
-  auto a =
-      std::make_unique<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
+  auto v = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
+  auto a = create<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
 
-  auto case_1_body = std::make_unique<ast::BlockStatement>();
-  case_1_body->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("v"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 1))));
+  auto case_1_body = create<ast::BlockStatement>();
+  case_1_body->append(
+      create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
+                                       create<ast::ScalarConstructorExpression>(
+                                           create<ast::SintLiteral>(&i32, 1))));
 
-  auto case_2_body = std::make_unique<ast::BlockStatement>();
-  case_2_body->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("v"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 2))));
+  auto case_2_body = create<ast::BlockStatement>();
+  case_2_body->append(
+      create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
+                                       create<ast::ScalarConstructorExpression>(
+                                           create<ast::SintLiteral>(&i32, 2))));
 
   ast::CaseSelectorList selector_1;
-  selector_1.push_back(std::make_unique<ast::SintLiteral>(&i32, 1));
+  selector_1.push_back(create<ast::SintLiteral>(&i32, 1));
 
   ast::CaseSelectorList selector_2;
-  selector_2.push_back(std::make_unique<ast::SintLiteral>(&i32, 2));
+  selector_2.push_back(create<ast::SintLiteral>(&i32, 2));
 
   ast::CaseStatementList cases;
-  cases.push_back(std::make_unique<ast::CaseStatement>(std::move(selector_1),
-                                                       std::move(case_1_body)));
-  cases.push_back(std::make_unique<ast::CaseStatement>(std::move(selector_2),
-                                                       std::move(case_2_body)));
+  cases.push_back(create<ast::CaseStatement>(std::move(selector_1),
+                                             std::move(case_1_body)));
+  cases.push_back(create<ast::CaseStatement>(std::move(selector_2),
+                                             std::move(case_2_body)));
 
-  ast::SwitchStatement expr(std::make_unique<ast::IdentifierExpression>("a"),
+  ast::SwitchStatement expr(create<ast::IdentifierExpression>("a"),
                             std::move(cases));
 
   td.RegisterVariableForTesting(v.get());
@@ -158,22 +156,19 @@
   //     v = 1;
   //  }
 
-  auto v =
-      std::make_unique<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
-  auto a =
-      std::make_unique<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
+  auto v = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
+  auto a = create<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
 
-  auto default_body = std::make_unique<ast::BlockStatement>();
-  default_body->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("v"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 1))));
+  auto default_body = create<ast::BlockStatement>();
+  default_body->append(
+      create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
+                                       create<ast::ScalarConstructorExpression>(
+                                           create<ast::SintLiteral>(&i32, 1))));
 
   ast::CaseStatementList cases;
-  cases.push_back(
-      std::make_unique<ast::CaseStatement>(std::move(default_body)));
+  cases.push_back(create<ast::CaseStatement>(std::move(default_body)));
 
-  ast::SwitchStatement expr(std::make_unique<ast::IdentifierExpression>("a"),
+  ast::SwitchStatement expr(create<ast::IdentifierExpression>("a"),
                             std::move(cases));
 
   td.RegisterVariableForTesting(v.get());
@@ -223,45 +218,42 @@
   //      v = 3;
   //  }
 
-  auto v =
-      std::make_unique<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
-  auto a =
-      std::make_unique<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
+  auto v = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
+  auto a = create<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
 
-  auto case_1_body = std::make_unique<ast::BlockStatement>();
-  case_1_body->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("v"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 1))));
+  auto case_1_body = create<ast::BlockStatement>();
+  case_1_body->append(
+      create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
+                                       create<ast::ScalarConstructorExpression>(
+                                           create<ast::SintLiteral>(&i32, 1))));
 
-  auto case_2_body = std::make_unique<ast::BlockStatement>();
-  case_2_body->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("v"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 2))));
+  auto case_2_body = create<ast::BlockStatement>();
+  case_2_body->append(
+      create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
+                                       create<ast::ScalarConstructorExpression>(
+                                           create<ast::SintLiteral>(&i32, 2))));
 
-  auto default_body = std::make_unique<ast::BlockStatement>();
-  default_body->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("v"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 3))));
+  auto default_body = create<ast::BlockStatement>();
+  default_body->append(
+      create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
+                                       create<ast::ScalarConstructorExpression>(
+                                           create<ast::SintLiteral>(&i32, 3))));
 
   ast::CaseSelectorList selector_1;
-  selector_1.push_back(std::make_unique<ast::SintLiteral>(&i32, 1));
+  selector_1.push_back(create<ast::SintLiteral>(&i32, 1));
 
   ast::CaseSelectorList selector_2;
-  selector_2.push_back(std::make_unique<ast::SintLiteral>(&i32, 2));
-  selector_2.push_back(std::make_unique<ast::SintLiteral>(&i32, 3));
+  selector_2.push_back(create<ast::SintLiteral>(&i32, 2));
+  selector_2.push_back(create<ast::SintLiteral>(&i32, 3));
 
   ast::CaseStatementList cases;
-  cases.push_back(std::make_unique<ast::CaseStatement>(std::move(selector_1),
-                                                       std::move(case_1_body)));
-  cases.push_back(std::make_unique<ast::CaseStatement>(std::move(selector_2),
-                                                       std::move(case_2_body)));
-  cases.push_back(
-      std::make_unique<ast::CaseStatement>(std::move(default_body)));
+  cases.push_back(create<ast::CaseStatement>(std::move(selector_1),
+                                             std::move(case_1_body)));
+  cases.push_back(create<ast::CaseStatement>(std::move(selector_2),
+                                             std::move(case_2_body)));
+  cases.push_back(create<ast::CaseStatement>(std::move(default_body)));
 
-  ast::SwitchStatement expr(std::make_unique<ast::IdentifierExpression>("a"),
+  ast::SwitchStatement expr(create<ast::IdentifierExpression>("a"),
                             std::move(cases));
 
   td.RegisterVariableForTesting(v.get());
@@ -320,45 +312,42 @@
   //      v = 3;
   //  }
 
-  auto v =
-      std::make_unique<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
-  auto a =
-      std::make_unique<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
+  auto v = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
+  auto a = create<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
 
-  auto case_1_body = std::make_unique<ast::BlockStatement>();
-  case_1_body->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("v"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 1))));
-  case_1_body->append(std::make_unique<ast::FallthroughStatement>());
+  auto case_1_body = create<ast::BlockStatement>();
+  case_1_body->append(
+      create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
+                                       create<ast::ScalarConstructorExpression>(
+                                           create<ast::SintLiteral>(&i32, 1))));
+  case_1_body->append(create<ast::FallthroughStatement>());
 
-  auto case_2_body = std::make_unique<ast::BlockStatement>();
-  case_2_body->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("v"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 2))));
+  auto case_2_body = create<ast::BlockStatement>();
+  case_2_body->append(
+      create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
+                                       create<ast::ScalarConstructorExpression>(
+                                           create<ast::SintLiteral>(&i32, 2))));
 
-  auto default_body = std::make_unique<ast::BlockStatement>();
-  default_body->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("v"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 3))));
+  auto default_body = create<ast::BlockStatement>();
+  default_body->append(
+      create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
+                                       create<ast::ScalarConstructorExpression>(
+                                           create<ast::SintLiteral>(&i32, 3))));
 
   ast::CaseSelectorList selector_1;
-  selector_1.push_back(std::make_unique<ast::SintLiteral>(&i32, 1));
+  selector_1.push_back(create<ast::SintLiteral>(&i32, 1));
 
   ast::CaseSelectorList selector_2;
-  selector_2.push_back(std::make_unique<ast::SintLiteral>(&i32, 2));
+  selector_2.push_back(create<ast::SintLiteral>(&i32, 2));
 
   ast::CaseStatementList cases;
-  cases.push_back(std::make_unique<ast::CaseStatement>(std::move(selector_1),
-                                                       std::move(case_1_body)));
-  cases.push_back(std::make_unique<ast::CaseStatement>(std::move(selector_2),
-                                                       std::move(case_2_body)));
-  cases.push_back(
-      std::make_unique<ast::CaseStatement>(std::move(default_body)));
+  cases.push_back(create<ast::CaseStatement>(std::move(selector_1),
+                                             std::move(case_1_body)));
+  cases.push_back(create<ast::CaseStatement>(std::move(selector_2),
+                                             std::move(case_2_body)));
+  cases.push_back(create<ast::CaseStatement>(std::move(default_body)));
 
-  ast::SwitchStatement expr(std::make_unique<ast::IdentifierExpression>("a"),
+  ast::SwitchStatement expr(create<ast::IdentifierExpression>("a"),
                             std::move(cases));
 
   td.RegisterVariableForTesting(v.get());
@@ -413,26 +402,24 @@
   //      fallthrough;
   //  }
 
-  auto v =
-      std::make_unique<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
-  auto a =
-      std::make_unique<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
+  auto v = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
+  auto a = create<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
 
-  auto case_1_body = std::make_unique<ast::BlockStatement>();
-  case_1_body->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("v"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 1))));
-  case_1_body->append(std::make_unique<ast::FallthroughStatement>());
+  auto case_1_body = create<ast::BlockStatement>();
+  case_1_body->append(
+      create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
+                                       create<ast::ScalarConstructorExpression>(
+                                           create<ast::SintLiteral>(&i32, 1))));
+  case_1_body->append(create<ast::FallthroughStatement>());
 
   ast::CaseSelectorList selector_1;
-  selector_1.push_back(std::make_unique<ast::SintLiteral>(&i32, 1));
+  selector_1.push_back(create<ast::SintLiteral>(&i32, 1));
 
   ast::CaseStatementList cases;
-  cases.push_back(std::make_unique<ast::CaseStatement>(std::move(selector_1),
-                                                       std::move(case_1_body)));
+  cases.push_back(create<ast::CaseStatement>(std::move(selector_1),
+                                             std::move(case_1_body)));
 
-  ast::SwitchStatement expr(std::make_unique<ast::IdentifierExpression>("a"),
+  ast::SwitchStatement expr(create<ast::IdentifierExpression>("a"),
                             std::move(cases));
 
   td.RegisterVariableForTesting(v.get());
@@ -461,33 +448,31 @@
   //     v = 1;
   //  }
 
-  auto v =
-      std::make_unique<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
-  auto a =
-      std::make_unique<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
+  auto v = create<ast::Variable>("v", ast::StorageClass::kPrivate, &i32);
+  auto a = create<ast::Variable>("a", ast::StorageClass::kPrivate, &i32);
 
-  auto if_body = std::make_unique<ast::BlockStatement>();
-  if_body->append(std::make_unique<ast::BreakStatement>());
+  auto if_body = create<ast::BlockStatement>();
+  if_body->append(create<ast::BreakStatement>());
 
-  auto case_1_body = std::make_unique<ast::BlockStatement>();
-  case_1_body->append(std::make_unique<ast::IfStatement>(
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::BoolLiteral>(&bool_type, true)),
-      std::move(if_body)));
+  auto case_1_body = create<ast::BlockStatement>();
+  case_1_body->append(
+      create<ast::IfStatement>(create<ast::ScalarConstructorExpression>(
+                                   create<ast::BoolLiteral>(&bool_type, true)),
+                               std::move(if_body)));
 
-  case_1_body->append(std::make_unique<ast::AssignmentStatement>(
-      std::make_unique<ast::IdentifierExpression>("v"),
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 1))));
+  case_1_body->append(
+      create<ast::AssignmentStatement>(create<ast::IdentifierExpression>("v"),
+                                       create<ast::ScalarConstructorExpression>(
+                                           create<ast::SintLiteral>(&i32, 1))));
 
   ast::CaseSelectorList selector_1;
-  selector_1.push_back(std::make_unique<ast::SintLiteral>(&i32, 1));
+  selector_1.push_back(create<ast::SintLiteral>(&i32, 1));
 
   ast::CaseStatementList cases;
-  cases.push_back(std::make_unique<ast::CaseStatement>(std::move(selector_1),
-                                                       std::move(case_1_body)));
+  cases.push_back(create<ast::CaseStatement>(std::move(selector_1),
+                                             std::move(case_1_body)));
 
-  ast::SwitchStatement expr(std::make_unique<ast::IdentifierExpression>("a"),
+  ast::SwitchStatement expr(create<ast::IdentifierExpression>("a"),
                             std::move(cases));
 
   td.RegisterVariableForTesting(v.get());
diff --git a/src/writer/spirv/builder_type_test.cc b/src/writer/spirv/builder_type_test.cc
index e1e8362..46aa30d 100644
--- a/src/writer/spirv/builder_type_test.cc
+++ b/src/writer/spirv/builder_type_test.cc
@@ -124,7 +124,7 @@
   ast::type::I32Type i32;
 
   ast::ArrayDecorationList decos;
-  decos.push_back(std::make_unique<ast::StrideDecoration>(16u, Source{}));
+  decos.push_back(create<ast::StrideDecoration>(16u, Source{}));
 
   ast::type::ArrayType ary(&i32, 4);
   ary.set_decorations(std::move(decos));
@@ -279,7 +279,7 @@
 }
 
 TEST_F(BuilderTest_Type, GenerateStruct_Empty) {
-  auto s = std::make_unique<ast::Struct>();
+  auto s = create<ast::Struct>();
   ast::type::StructType s_type("S", std::move(s));
 
   auto id = b.GenerateTypeIfNeeded(&s_type);
@@ -298,10 +298,9 @@
 
   ast::StructMemberDecorationList decos;
   ast::StructMemberList members;
-  members.push_back(
-      std::make_unique<ast::StructMember>("a", &f32, std::move(decos)));
+  members.push_back(create<ast::StructMember>("a", &f32, std::move(decos)));
 
-  auto s = std::make_unique<ast::Struct>(std::move(members));
+  auto s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("my_struct", std::move(s));
 
   auto id = b.GenerateTypeIfNeeded(&s_type);
@@ -321,15 +320,12 @@
 
   ast::StructMemberDecorationList decos;
   ast::StructMemberList members;
-  members.push_back(
-      std::make_unique<ast::StructMember>("a", &f32, std::move(decos)));
+  members.push_back(create<ast::StructMember>("a", &f32, std::move(decos)));
 
   ast::StructDecorationList struct_decos;
-  struct_decos.push_back(
-      std::make_unique<ast::StructBlockDecoration>(Source{}));
+  struct_decos.push_back(create<ast::StructBlockDecoration>(Source{}));
 
-  auto s = std::make_unique<ast::Struct>(std::move(struct_decos),
-                                         std::move(members));
+  auto s = create<ast::Struct>(std::move(struct_decos), std::move(members));
   ast::type::StructType s_type("my_struct", std::move(s));
 
   auto id = b.GenerateTypeIfNeeded(&s_type);
@@ -350,19 +346,15 @@
   ast::type::F32Type f32;
 
   ast::StructMemberDecorationList a_decos;
-  a_decos.push_back(
-      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
+  a_decos.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
   ast::StructMemberDecorationList b_decos;
-  b_decos.push_back(
-      std::make_unique<ast::StructMemberOffsetDecoration>(8, Source{}));
+  b_decos.push_back(create<ast::StructMemberOffsetDecoration>(8, Source{}));
 
   ast::StructMemberList members;
-  members.push_back(
-      std::make_unique<ast::StructMember>("a", &f32, std::move(a_decos)));
-  members.push_back(
-      std::make_unique<ast::StructMember>("b", &f32, std::move(b_decos)));
+  members.push_back(create<ast::StructMember>("a", &f32, std::move(a_decos)));
+  members.push_back(create<ast::StructMember>("b", &f32, std::move(b_decos)));
 
-  auto s = std::make_unique<ast::Struct>(std::move(members));
+  auto s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("S", std::move(s));
 
   auto id = b.GenerateTypeIfNeeded(&s_type);
@@ -392,14 +384,14 @@
   ast::StructMemberDecorationList empty_b;
   ast::StructMemberDecorationList empty_c;
   ast::StructMemberList members;
-  members.push_back(std::make_unique<ast::StructMember>("a", &glsl_mat2x2,
-                                                        std::move(empty_a)));
-  members.push_back(std::make_unique<ast::StructMember>("b", &glsl_mat2x3,
-                                                        std::move(empty_b)));
-  members.push_back(std::make_unique<ast::StructMember>("c", &glsl_mat4x4,
-                                                        std::move(empty_c)));
+  members.push_back(
+      create<ast::StructMember>("a", &glsl_mat2x2, std::move(empty_a)));
+  members.push_back(
+      create<ast::StructMember>("b", &glsl_mat2x3, std::move(empty_b)));
+  members.push_back(
+      create<ast::StructMember>("c", &glsl_mat4x4, std::move(empty_c)));
 
-  auto s = std::make_unique<ast::Struct>(std::move(members));
+  auto s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("S", std::move(s));
 
   auto id = b.GenerateTypeIfNeeded(&s_type);
@@ -431,24 +423,21 @@
   ast::type::MatrixType glsl_mat4x4(&f32, 4, 4);
 
   ast::StructMemberDecorationList a_decos;
-  a_decos.push_back(
-      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
+  a_decos.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
   ast::StructMemberDecorationList b_decos;
-  b_decos.push_back(
-      std::make_unique<ast::StructMemberOffsetDecoration>(16, Source{}));
+  b_decos.push_back(create<ast::StructMemberOffsetDecoration>(16, Source{}));
   ast::StructMemberDecorationList c_decos;
-  c_decos.push_back(
-      std::make_unique<ast::StructMemberOffsetDecoration>(48, Source{}));
+  c_decos.push_back(create<ast::StructMemberOffsetDecoration>(48, Source{}));
 
   ast::StructMemberList members;
-  members.push_back(std::make_unique<ast::StructMember>("a", &glsl_mat2x2,
-                                                        std::move(a_decos)));
-  members.push_back(std::make_unique<ast::StructMember>("b", &glsl_mat2x3,
-                                                        std::move(b_decos)));
-  members.push_back(std::make_unique<ast::StructMember>("c", &glsl_mat4x4,
-                                                        std::move(c_decos)));
+  members.push_back(
+      create<ast::StructMember>("a", &glsl_mat2x2, std::move(a_decos)));
+  members.push_back(
+      create<ast::StructMember>("b", &glsl_mat2x3, std::move(b_decos)));
+  members.push_back(
+      create<ast::StructMember>("c", &glsl_mat4x4, std::move(c_decos)));
 
-  auto s = std::make_unique<ast::Struct>(std::move(members));
+  auto s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("S", std::move(s));
 
   auto id = b.GenerateTypeIfNeeded(&s_type);
@@ -498,24 +487,21 @@
   ast::type::ArrayType rtarr_mat4x4(&glsl_mat4x4);  // Runtime array
 
   ast::StructMemberDecorationList a_decos;
-  a_decos.push_back(
-      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
+  a_decos.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
   ast::StructMemberDecorationList b_decos;
-  b_decos.push_back(
-      std::make_unique<ast::StructMemberOffsetDecoration>(16, Source{}));
+  b_decos.push_back(create<ast::StructMemberOffsetDecoration>(16, Source{}));
   ast::StructMemberDecorationList c_decos;
-  c_decos.push_back(
-      std::make_unique<ast::StructMemberOffsetDecoration>(48, Source{}));
+  c_decos.push_back(create<ast::StructMemberOffsetDecoration>(48, Source{}));
 
   ast::StructMemberList members;
-  members.push_back(std::make_unique<ast::StructMember>("a", &glsl_mat2x2,
-                                                        std::move(a_decos)));
-  members.push_back(std::make_unique<ast::StructMember>("b", &glsl_mat2x3,
-                                                        std::move(b_decos)));
-  members.push_back(std::make_unique<ast::StructMember>("c", &glsl_mat4x4,
-                                                        std::move(c_decos)));
+  members.push_back(
+      create<ast::StructMember>("a", &glsl_mat2x2, std::move(a_decos)));
+  members.push_back(
+      create<ast::StructMember>("b", &glsl_mat2x3, std::move(b_decos)));
+  members.push_back(
+      create<ast::StructMember>("c", &glsl_mat4x4, std::move(c_decos)));
 
-  auto s = std::make_unique<ast::Struct>(std::move(members));
+  auto s = create<ast::Struct>(std::move(members));
   ast::type::StructType s_type("S", std::move(s));
 
   auto id = b.GenerateTypeIfNeeded(&s_type);
diff --git a/src/writer/spirv/builder_unary_op_expression_test.cc b/src/writer/spirv/builder_unary_op_expression_test.cc
index 29f597c..5795dee 100644
--- a/src/writer/spirv/builder_unary_op_expression_test.cc
+++ b/src/writer/spirv/builder_unary_op_expression_test.cc
@@ -41,10 +41,9 @@
 TEST_F(BuilderTest, UnaryOp_Negation_Integer) {
   ast::type::I32Type i32;
 
-  ast::UnaryOpExpression expr(
-      ast::UnaryOp::kNegation,
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::SintLiteral>(&i32, 1)));
+  ast::UnaryOpExpression expr(ast::UnaryOp::kNegation,
+                              create<ast::ScalarConstructorExpression>(
+                                  create<ast::SintLiteral>(&i32, 1)));
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
@@ -61,10 +60,9 @@
 TEST_F(BuilderTest, UnaryOp_Negation_Float) {
   ast::type::F32Type f32;
 
-  ast::UnaryOpExpression expr(
-      ast::UnaryOp::kNegation,
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::FloatLiteral>(&f32, 1)));
+  ast::UnaryOpExpression expr(ast::UnaryOp::kNegation,
+                              create<ast::ScalarConstructorExpression>(
+                                  create<ast::FloatLiteral>(&f32, 1)));
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
@@ -81,10 +79,9 @@
 TEST_F(BuilderTest, UnaryOp_Not) {
   ast::type::BoolType bool_type;
 
-  ast::UnaryOpExpression expr(
-      ast::UnaryOp::kNot,
-      std::make_unique<ast::ScalarConstructorExpression>(
-          std::make_unique<ast::BoolLiteral>(&bool_type, false)));
+  ast::UnaryOpExpression expr(ast::UnaryOp::kNot,
+                              create<ast::ScalarConstructorExpression>(
+                                  create<ast::BoolLiteral>(&bool_type, false)));
 
   ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
 
@@ -104,9 +101,8 @@
 
   ast::Variable var("param", ast::StorageClass::kFunction, &vec);
 
-  ast::UnaryOpExpression expr(
-      ast::UnaryOp::kNegation,
-      std::make_unique<ast::IdentifierExpression>("param"));
+  ast::UnaryOpExpression expr(ast::UnaryOp::kNegation,
+                              create<ast::IdentifierExpression>("param"));
 
   td.RegisterVariableForTesting(&var);
   EXPECT_TRUE(td.DetermineResultType(&expr)) << td.error();
diff --git a/src/writer/spirv/test_helper.h b/src/writer/spirv/test_helper.h
index a7ff015..03c8975 100644
--- a/src/writer/spirv/test_helper.h
+++ b/src/writer/spirv/test_helper.h
@@ -15,6 +15,9 @@
 #ifndef SRC_WRITER_SPIRV_TEST_HELPER_H_
 #define SRC_WRITER_SPIRV_TEST_HELPER_H_
 
+#include <memory>
+#include <utility>
+
 #include "gtest/gtest.h"
 #include "src/ast/module.h"
 #include "src/context.h"
@@ -26,12 +29,19 @@
 namespace spirv {
 
 /// Helper class for testing
-template <typename T>
-class TestHelperBase : public T {
+template <typename BASE>
+class TestHelperBase : public BASE {
  public:
   TestHelperBase() : td(&ctx, &mod), b(&ctx, &mod) {}
   ~TestHelperBase() = default;
 
+  /// @return a `std::unique_ptr` to a new `T` constructed with `args`
+  /// @param args the arguments to forward to the constructor for `T`
+  template <typename T, typename... ARGS>
+  std::unique_ptr<T> create(ARGS&&... args) {
+    return std::make_unique<T>(std::forward<ARGS>(args)...);
+  }
+
   /// The context
   Context ctx;
   /// The module