ast 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: I0e68992963f52e432d4d485feae1123f35732552
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/32664
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/ast/array_accessor_expression_test.cc b/src/ast/array_accessor_expression_test.cc
index 2893797..1b1f3bd 100644
--- a/src/ast/array_accessor_expression_test.cc
+++ b/src/ast/array_accessor_expression_test.cc
@@ -24,8 +24,8 @@
 using ArrayAccessorExpressionTest = TestHelper;
 
 TEST_F(ArrayAccessorExpressionTest, Create) {
-  auto ary = std::make_unique<IdentifierExpression>("ary");
-  auto idx = std::make_unique<IdentifierExpression>("idx");
+  auto ary = create<IdentifierExpression>("ary");
+  auto idx = create<IdentifierExpression>("idx");
 
   auto* ary_ptr = ary.get();
   auto* idx_ptr = idx.get();
@@ -35,8 +35,8 @@
   ASSERT_EQ(exp.idx_expr(), idx_ptr);
 }
 TEST_F(ArrayAccessorExpressionTest, CreateWithSource) {
-  auto ary = std::make_unique<IdentifierExpression>("ary");
-  auto idx = std::make_unique<IdentifierExpression>("idx");
+  auto ary = create<IdentifierExpression>("ary");
+  auto idx = create<IdentifierExpression>("idx");
 
   ArrayAccessorExpression exp(Source{Source::Location{20, 2}}, std::move(ary),
                               std::move(idx));
@@ -51,15 +51,15 @@
 }
 
 TEST_F(ArrayAccessorExpressionTest, IsValid) {
-  auto ary = std::make_unique<IdentifierExpression>("ary");
-  auto idx = std::make_unique<IdentifierExpression>("idx");
+  auto ary = create<IdentifierExpression>("ary");
+  auto idx = create<IdentifierExpression>("idx");
 
   ArrayAccessorExpression exp(std::move(ary), std::move(idx));
   EXPECT_TRUE(exp.IsValid());
 }
 
 TEST_F(ArrayAccessorExpressionTest, IsValid_MissingArray) {
-  auto idx = std::make_unique<IdentifierExpression>("idx");
+  auto idx = create<IdentifierExpression>("idx");
 
   ArrayAccessorExpression exp;
   exp.set_idx_expr(std::move(idx));
@@ -67,7 +67,7 @@
 }
 
 TEST_F(ArrayAccessorExpressionTest, IsValid_MissingIndex) {
-  auto ary = std::make_unique<IdentifierExpression>("ary");
+  auto ary = create<IdentifierExpression>("ary");
 
   ArrayAccessorExpression exp;
   exp.set_array(std::move(ary));
@@ -75,22 +75,22 @@
 }
 
 TEST_F(ArrayAccessorExpressionTest, IsValid_InvalidArray) {
-  auto ary = std::make_unique<IdentifierExpression>("");
-  auto idx = std::make_unique<IdentifierExpression>("idx");
+  auto ary = create<IdentifierExpression>("");
+  auto idx = create<IdentifierExpression>("idx");
   ArrayAccessorExpression exp(std::move(ary), std::move(idx));
   EXPECT_FALSE(exp.IsValid());
 }
 
 TEST_F(ArrayAccessorExpressionTest, IsValid_InvalidIndex) {
-  auto ary = std::make_unique<IdentifierExpression>("ary");
-  auto idx = std::make_unique<IdentifierExpression>("");
+  auto ary = create<IdentifierExpression>("ary");
+  auto idx = create<IdentifierExpression>("");
   ArrayAccessorExpression exp(std::move(ary), std::move(idx));
   EXPECT_FALSE(exp.IsValid());
 }
 
 TEST_F(ArrayAccessorExpressionTest, ToStr) {
-  auto ary = std::make_unique<IdentifierExpression>("ary");
-  auto idx = std::make_unique<IdentifierExpression>("idx");
+  auto ary = create<IdentifierExpression>("ary");
+  auto idx = create<IdentifierExpression>("idx");
 
   ArrayAccessorExpression exp(std::move(ary), std::move(idx));
   std::ostringstream out;
diff --git a/src/ast/assignment_statement_test.cc b/src/ast/assignment_statement_test.cc
index 8ac74a9..10c9542 100644
--- a/src/ast/assignment_statement_test.cc
+++ b/src/ast/assignment_statement_test.cc
@@ -24,8 +24,8 @@
 using AssignmentStatementTest = TestHelper;
 
 TEST_F(AssignmentStatementTest, Creation) {
-  auto lhs = std::make_unique<ast::IdentifierExpression>("lhs");
-  auto rhs = std::make_unique<ast::IdentifierExpression>("rhs");
+  auto lhs = create<ast::IdentifierExpression>("lhs");
+  auto rhs = create<ast::IdentifierExpression>("rhs");
 
   auto* lhs_ptr = lhs.get();
   auto* rhs_ptr = rhs.get();
@@ -36,8 +36,8 @@
 }
 
 TEST_F(AssignmentStatementTest, CreationWithSource) {
-  auto lhs = std::make_unique<ast::IdentifierExpression>("lhs");
-  auto rhs = std::make_unique<ast::IdentifierExpression>("rhs");
+  auto lhs = create<ast::IdentifierExpression>("lhs");
+  auto rhs = create<ast::IdentifierExpression>("rhs");
 
   AssignmentStatement stmt(Source{Source::Location{20, 2}}, std::move(lhs),
                            std::move(rhs));
@@ -47,23 +47,23 @@
 }
 
 TEST_F(AssignmentStatementTest, IsAssign) {
-  auto lhs = std::make_unique<ast::IdentifierExpression>("lhs");
-  auto rhs = std::make_unique<ast::IdentifierExpression>("rhs");
+  auto lhs = create<ast::IdentifierExpression>("lhs");
+  auto rhs = create<ast::IdentifierExpression>("rhs");
 
   AssignmentStatement stmt(std::move(lhs), std::move(rhs));
   EXPECT_TRUE(stmt.IsAssign());
 }
 
 TEST_F(AssignmentStatementTest, IsValid) {
-  auto lhs = std::make_unique<ast::IdentifierExpression>("lhs");
-  auto rhs = std::make_unique<ast::IdentifierExpression>("rhs");
+  auto lhs = create<ast::IdentifierExpression>("lhs");
+  auto rhs = create<ast::IdentifierExpression>("rhs");
 
   AssignmentStatement stmt(std::move(lhs), std::move(rhs));
   EXPECT_TRUE(stmt.IsValid());
 }
 
 TEST_F(AssignmentStatementTest, IsValid_MissingLHS) {
-  auto rhs = std::make_unique<ast::IdentifierExpression>("rhs");
+  auto rhs = create<ast::IdentifierExpression>("rhs");
 
   AssignmentStatement stmt;
   stmt.set_rhs(std::move(rhs));
@@ -71,7 +71,7 @@
 }
 
 TEST_F(AssignmentStatementTest, IsValid_MissingRHS) {
-  auto lhs = std::make_unique<ast::IdentifierExpression>("lhs");
+  auto lhs = create<ast::IdentifierExpression>("lhs");
 
   AssignmentStatement stmt;
   stmt.set_lhs(std::move(lhs));
@@ -79,22 +79,22 @@
 }
 
 TEST_F(AssignmentStatementTest, IsValid_InvalidLHS) {
-  auto lhs = std::make_unique<ast::IdentifierExpression>("");
-  auto rhs = std::make_unique<ast::IdentifierExpression>("rhs");
+  auto lhs = create<ast::IdentifierExpression>("");
+  auto rhs = create<ast::IdentifierExpression>("rhs");
   AssignmentStatement stmt(std::move(lhs), std::move(rhs));
   EXPECT_FALSE(stmt.IsValid());
 }
 
 TEST_F(AssignmentStatementTest, IsValid_InvalidRHS) {
-  auto lhs = std::make_unique<ast::IdentifierExpression>("lhs");
-  auto rhs = std::make_unique<ast::IdentifierExpression>("");
+  auto lhs = create<ast::IdentifierExpression>("lhs");
+  auto rhs = create<ast::IdentifierExpression>("");
   AssignmentStatement stmt(std::move(lhs), std::move(rhs));
   EXPECT_FALSE(stmt.IsValid());
 }
 
 TEST_F(AssignmentStatementTest, ToStr) {
-  auto lhs = std::make_unique<ast::IdentifierExpression>("lhs");
-  auto rhs = std::make_unique<ast::IdentifierExpression>("rhs");
+  auto lhs = create<ast::IdentifierExpression>("lhs");
+  auto rhs = create<ast::IdentifierExpression>("rhs");
 
   AssignmentStatement stmt(std::move(lhs), std::move(rhs));
   std::ostringstream out;
diff --git a/src/ast/binary_expression_test.cc b/src/ast/binary_expression_test.cc
index 4daf6ce..395c844 100644
--- a/src/ast/binary_expression_test.cc
+++ b/src/ast/binary_expression_test.cc
@@ -26,8 +26,8 @@
 using BinaryExpressionTest = TestHelper;
 
 TEST_F(BinaryExpressionTest, Creation) {
-  auto lhs = std::make_unique<IdentifierExpression>("lhs");
-  auto rhs = std::make_unique<IdentifierExpression>("rhs");
+  auto lhs = create<IdentifierExpression>("lhs");
+  auto rhs = create<IdentifierExpression>("rhs");
 
   auto* lhs_ptr = lhs.get();
   auto* rhs_ptr = rhs.get();
@@ -39,8 +39,8 @@
 }
 
 TEST_F(BinaryExpressionTest, Creation_WithSource) {
-  auto lhs = std::make_unique<IdentifierExpression>("lhs");
-  auto rhs = std::make_unique<IdentifierExpression>("rhs");
+  auto lhs = create<IdentifierExpression>("lhs");
+  auto rhs = create<IdentifierExpression>("rhs");
 
   BinaryExpression r(Source{Source::Location{20, 2}}, BinaryOp::kEqual,
                      std::move(lhs), std::move(rhs));
@@ -55,15 +55,15 @@
 }
 
 TEST_F(BinaryExpressionTest, IsValid) {
-  auto lhs = std::make_unique<IdentifierExpression>("lhs");
-  auto rhs = std::make_unique<IdentifierExpression>("rhs");
+  auto lhs = create<IdentifierExpression>("lhs");
+  auto rhs = create<IdentifierExpression>("rhs");
 
   BinaryExpression r(BinaryOp::kEqual, std::move(lhs), std::move(rhs));
   EXPECT_TRUE(r.IsValid());
 }
 
 TEST_F(BinaryExpressionTest, IsValid_Null_LHS) {
-  auto rhs = std::make_unique<IdentifierExpression>("rhs");
+  auto rhs = create<IdentifierExpression>("rhs");
 
   BinaryExpression r;
   r.set_op(BinaryOp::kEqual);
@@ -72,15 +72,15 @@
 }
 
 TEST_F(BinaryExpressionTest, IsValid_Invalid_LHS) {
-  auto lhs = std::make_unique<IdentifierExpression>("");
-  auto rhs = std::make_unique<IdentifierExpression>("rhs");
+  auto lhs = create<IdentifierExpression>("");
+  auto rhs = create<IdentifierExpression>("rhs");
 
   BinaryExpression r(BinaryOp::kEqual, std::move(lhs), std::move(rhs));
   EXPECT_FALSE(r.IsValid());
 }
 
 TEST_F(BinaryExpressionTest, IsValid_Null_RHS) {
-  auto lhs = std::make_unique<IdentifierExpression>("lhs");
+  auto lhs = create<IdentifierExpression>("lhs");
 
   BinaryExpression r;
   r.set_op(BinaryOp::kEqual);
@@ -89,24 +89,24 @@
 }
 
 TEST_F(BinaryExpressionTest, IsValid_Invalid_RHS) {
-  auto lhs = std::make_unique<IdentifierExpression>("lhs");
-  auto rhs = std::make_unique<IdentifierExpression>("");
+  auto lhs = create<IdentifierExpression>("lhs");
+  auto rhs = create<IdentifierExpression>("");
 
   BinaryExpression r(BinaryOp::kEqual, std::move(lhs), std::move(rhs));
   EXPECT_FALSE(r.IsValid());
 }
 
 TEST_F(BinaryExpressionTest, IsValid_Binary_None) {
-  auto lhs = std::make_unique<IdentifierExpression>("lhs");
-  auto rhs = std::make_unique<IdentifierExpression>("rhs");
+  auto lhs = create<IdentifierExpression>("lhs");
+  auto rhs = create<IdentifierExpression>("rhs");
 
   BinaryExpression r(BinaryOp::kNone, std::move(lhs), std::move(rhs));
   EXPECT_FALSE(r.IsValid());
 }
 
 TEST_F(BinaryExpressionTest, ToStr) {
-  auto lhs = std::make_unique<IdentifierExpression>("lhs");
-  auto rhs = std::make_unique<IdentifierExpression>("rhs");
+  auto lhs = create<IdentifierExpression>("lhs");
+  auto rhs = create<IdentifierExpression>("rhs");
 
   BinaryExpression r(BinaryOp::kEqual, std::move(lhs), std::move(rhs));
   std::ostringstream out;
diff --git a/src/ast/bitcast_expression_test.cc b/src/ast/bitcast_expression_test.cc
index 8641442..071ad89 100644
--- a/src/ast/bitcast_expression_test.cc
+++ b/src/ast/bitcast_expression_test.cc
@@ -26,7 +26,7 @@
 
 TEST_F(BitcastExpressionTest, Create) {
   type::F32Type f32;
-  auto expr = std::make_unique<IdentifierExpression>("expr");
+  auto expr = create<IdentifierExpression>("expr");
 
   auto* expr_ptr = expr.get();
 
@@ -37,7 +37,7 @@
 
 TEST_F(BitcastExpressionTest, CreateWithSource) {
   type::F32Type f32;
-  auto expr = std::make_unique<IdentifierExpression>("expr");
+  auto expr = create<IdentifierExpression>("expr");
 
   BitcastExpression exp(Source{Source::Location{20, 2}}, &f32, std::move(expr));
   auto src = exp.source();
@@ -52,14 +52,14 @@
 
 TEST_F(BitcastExpressionTest, IsValid) {
   type::F32Type f32;
-  auto expr = std::make_unique<IdentifierExpression>("expr");
+  auto expr = create<IdentifierExpression>("expr");
 
   BitcastExpression exp(&f32, std::move(expr));
   EXPECT_TRUE(exp.IsValid());
 }
 
 TEST_F(BitcastExpressionTest, IsValid_MissingType) {
-  auto expr = std::make_unique<IdentifierExpression>("expr");
+  auto expr = create<IdentifierExpression>("expr");
 
   BitcastExpression exp;
   exp.set_expr(std::move(expr));
@@ -76,14 +76,14 @@
 
 TEST_F(BitcastExpressionTest, IsValid_InvalidExpr) {
   type::F32Type f32;
-  auto expr = std::make_unique<IdentifierExpression>("");
+  auto expr = create<IdentifierExpression>("");
   BitcastExpression e(&f32, std::move(expr));
   EXPECT_FALSE(e.IsValid());
 }
 
 TEST_F(BitcastExpressionTest, ToStr) {
   type::F32Type f32;
-  auto expr = std::make_unique<IdentifierExpression>("expr");
+  auto expr = create<IdentifierExpression>("expr");
 
   BitcastExpression exp(&f32, std::move(expr));
   std::ostringstream out;
diff --git a/src/ast/block_statement_test.cc b/src/ast/block_statement_test.cc
index 893ad38..802bb01 100644
--- a/src/ast/block_statement_test.cc
+++ b/src/ast/block_statement_test.cc
@@ -28,7 +28,7 @@
 using BlockStatementTest = TestHelper;
 
 TEST_F(BlockStatementTest, Creation) {
-  auto d = std::make_unique<DiscardStatement>();
+  auto d = create<DiscardStatement>();
   auto* ptr = d.get();
 
   BlockStatement b;
@@ -39,9 +39,9 @@
 }
 
 TEST_F(BlockStatementTest, Creation_WithInsert) {
-  auto s1 = std::make_unique<DiscardStatement>();
-  auto s2 = std::make_unique<DiscardStatement>();
-  auto s3 = std::make_unique<DiscardStatement>();
+  auto s1 = create<DiscardStatement>();
+  auto s2 = create<DiscardStatement>();
+  auto s3 = create<DiscardStatement>();
   auto* p1 = s1.get();
   auto* p2 = s2.get();
   auto* p3 = s3.get();
@@ -73,7 +73,7 @@
 
 TEST_F(BlockStatementTest, IsValid) {
   BlockStatement b;
-  b.append(std::make_unique<DiscardStatement>());
+  b.append(create<DiscardStatement>());
   EXPECT_TRUE(b.IsValid());
 }
 
@@ -84,20 +84,20 @@
 
 TEST_F(BlockStatementTest, IsValid_NullBodyStatement) {
   BlockStatement b;
-  b.append(std::make_unique<DiscardStatement>());
+  b.append(create<DiscardStatement>());
   b.append(nullptr);
   EXPECT_FALSE(b.IsValid());
 }
 
 TEST_F(BlockStatementTest, IsValid_InvalidBodyStatement) {
   BlockStatement b;
-  b.append(std::make_unique<IfStatement>());
+  b.append(create<IfStatement>());
   EXPECT_FALSE(b.IsValid());
 }
 
 TEST_F(BlockStatementTest, ToStr) {
   BlockStatement b;
-  b.append(std::make_unique<DiscardStatement>());
+  b.append(create<DiscardStatement>());
 
   std::ostringstream out;
   b.to_str(out, 2);
diff --git a/src/ast/builder.h b/src/ast/builder.h
index 692e799..77c9e2d 100644
--- a/src/ast/builder.h
+++ b/src/ast/builder.h
@@ -115,58 +115,55 @@
   /// @return an IdentifierExpression with the given name
   std::unique_ptr<ast::IdentifierExpression> make_expr(
       const std::string& name) {
-    return std::make_unique<ast::IdentifierExpression>(name);
+    return create<ast::IdentifierExpression>(name);
   }
 
   /// @param name the identifier name
   /// @return an IdentifierExpression with the given name
   std::unique_ptr<ast::IdentifierExpression> make_expr(const char* name) {
-    return std::make_unique<ast::IdentifierExpression>(name);
+    return create<ast::IdentifierExpression>(name);
   }
 
   /// @param value the float value
   /// @return a Scalar constructor for the given value
   std::unique_ptr<ast::ScalarConstructorExpression> make_expr(float value) {
-    return std::make_unique<ast::ScalarConstructorExpression>(
-        make_literal(value));
+    return create<ast::ScalarConstructorExpression>(make_literal(value));
   }
 
   /// @param value the int value
   /// @return a Scalar constructor for the given value
   std::unique_ptr<ast::ScalarConstructorExpression> make_expr(int32_t value) {
-    return std::make_unique<ast::ScalarConstructorExpression>(
-        make_literal(value));
+    return create<ast::ScalarConstructorExpression>(make_literal(value));
   }
 
   /// @param value the unsigned int value
   /// @return a Scalar constructor for the given value
   std::unique_ptr<ast::ScalarConstructorExpression> make_expr(uint32_t value) {
-    return std::make_unique<ast::ScalarConstructorExpression>(
-        make_literal(value));
+    return create<ast::ScalarConstructorExpression>(make_literal(value));
   }
 
   /// @param val the boolan value
   /// @return a boolean literal with the given value
   std::unique_ptr<ast::BoolLiteral> make_literal(bool val) {
-    return std::make_unique<ast::BoolLiteral>(bool_type(), val);
+    return create<ast::BoolLiteral>(bool_type(), val);
   }
 
   /// @param val the float value
   /// @return a float literal with the given value
   std::unique_ptr<ast::FloatLiteral> make_literal(float val) {
-    return std::make_unique<ast::FloatLiteral>(f32(), val);
+    return create<ast::FloatLiteral>(f32(), val);
   }
 
   /// @param val the unsigned int value
   /// @return a UintLiteral with the given value
   std::unique_ptr<ast::UintLiteral> make_literal(uint32_t val) {
-    return std::make_unique<ast::UintLiteral>(u32(), val);
+    return create<ast::UintLiteral>(u32(), val);
   }
 
   /// @param val the integer value
   /// @return the SintLiteral with the given value
   std::unique_ptr<ast::SintLiteral> make_literal(int32_t val) {
-    return std::make_unique<ast::SintLiteral>(i32(), val);
+    return create<ast::SintLiteral>(i32(), val);
   }
 
   /// Converts `arg` to an `ast::Expression` using `make_expr()`, then appends
@@ -198,8 +195,7 @@
                                                             ARGS&&... args) {
     ast::ExpressionList vals;
     append_expr(vals, std::forward<ARGS>(args)...);
-    return std::make_unique<ast::TypeConstructorExpression>(ty,
-                                                            std::move(vals));
+    return create<ast::TypeConstructorExpression>(ty, std::move(vals));
   }
 
   /// @param name the variable name
@@ -221,6 +217,13 @@
     return ast::CallExpression{make_expr(func), std::move(params)};
   }
 
+  /// @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)...);
+  }
+
  private:
   Context* ctx_ = nullptr;
 };
diff --git a/src/ast/call_expression_test.cc b/src/ast/call_expression_test.cc
index aae1389..6cdcbcb 100644
--- a/src/ast/call_expression_test.cc
+++ b/src/ast/call_expression_test.cc
@@ -24,10 +24,10 @@
 using CallExpressionTest = TestHelper;
 
 TEST_F(CallExpressionTest, Creation) {
-  auto func = std::make_unique<IdentifierExpression>("func");
+  auto func = create<IdentifierExpression>("func");
   ExpressionList params;
-  params.push_back(std::make_unique<IdentifierExpression>("param1"));
-  params.push_back(std::make_unique<IdentifierExpression>("param2"));
+  params.push_back(create<IdentifierExpression>("param1"));
+  params.push_back(create<IdentifierExpression>("param2"));
 
   auto* func_ptr = func.get();
   auto* param1_ptr = params[0].get();
@@ -43,7 +43,7 @@
 }
 
 TEST_F(CallExpressionTest, Creation_WithSource) {
-  auto func = std::make_unique<IdentifierExpression>("func");
+  auto func = create<IdentifierExpression>("func");
   CallExpression stmt(Source{Source::Location{20, 2}}, std::move(func), {});
   auto src = stmt.source();
   EXPECT_EQ(src.range.begin.line, 20u);
@@ -51,13 +51,13 @@
 }
 
 TEST_F(CallExpressionTest, IsCall) {
-  auto func = std::make_unique<IdentifierExpression>("func");
+  auto func = create<IdentifierExpression>("func");
   CallExpression stmt(std::move(func), {});
   EXPECT_TRUE(stmt.IsCall());
 }
 
 TEST_F(CallExpressionTest, IsValid) {
-  auto func = std::make_unique<IdentifierExpression>("func");
+  auto func = create<IdentifierExpression>("func");
   CallExpression stmt(std::move(func), {});
   EXPECT_TRUE(stmt.IsValid());
 }
@@ -68,36 +68,36 @@
 }
 
 TEST_F(CallExpressionTest, IsValid_NullParam) {
-  auto func = std::make_unique<IdentifierExpression>("func");
+  auto func = create<IdentifierExpression>("func");
   ExpressionList params;
-  params.push_back(std::make_unique<IdentifierExpression>("param1"));
+  params.push_back(create<IdentifierExpression>("param1"));
   params.push_back(nullptr);
-  params.push_back(std::make_unique<IdentifierExpression>("param2"));
+  params.push_back(create<IdentifierExpression>("param2"));
 
   CallExpression stmt(std::move(func), std::move(params));
   EXPECT_FALSE(stmt.IsValid());
 }
 
 TEST_F(CallExpressionTest, IsValid_InvalidFunction) {
-  auto func = std::make_unique<IdentifierExpression>("");
+  auto func = create<IdentifierExpression>("");
   ExpressionList params;
-  params.push_back(std::make_unique<IdentifierExpression>("param1"));
+  params.push_back(create<IdentifierExpression>("param1"));
 
   CallExpression stmt(std::move(func), std::move(params));
   EXPECT_FALSE(stmt.IsValid());
 }
 
 TEST_F(CallExpressionTest, IsValid_InvalidParam) {
-  auto func = std::make_unique<IdentifierExpression>("func");
+  auto func = create<IdentifierExpression>("func");
   ExpressionList params;
-  params.push_back(std::make_unique<IdentifierExpression>(""));
+  params.push_back(create<IdentifierExpression>(""));
 
   CallExpression stmt(std::move(func), std::move(params));
   EXPECT_FALSE(stmt.IsValid());
 }
 
 TEST_F(CallExpressionTest, ToStr_NoParams) {
-  auto func = std::make_unique<IdentifierExpression>("func");
+  auto func = create<IdentifierExpression>("func");
   CallExpression stmt(std::move(func), {});
   std::ostringstream out;
   stmt.to_str(out, 2);
@@ -110,10 +110,10 @@
 }
 
 TEST_F(CallExpressionTest, ToStr_WithParams) {
-  auto func = std::make_unique<IdentifierExpression>("func");
+  auto func = create<IdentifierExpression>("func");
   ExpressionList params;
-  params.push_back(std::make_unique<IdentifierExpression>("param1"));
-  params.push_back(std::make_unique<IdentifierExpression>("param2"));
+  params.push_back(create<IdentifierExpression>("param1"));
+  params.push_back(create<IdentifierExpression>("param2"));
 
   CallExpression stmt(std::move(func), std::move(params));
   std::ostringstream out;
diff --git a/src/ast/call_statement_test.cc b/src/ast/call_statement_test.cc
index 1337440..b9df302 100644
--- a/src/ast/call_statement_test.cc
+++ b/src/ast/call_statement_test.cc
@@ -25,8 +25,8 @@
 using CallStatementTest = TestHelper;
 
 TEST_F(CallStatementTest, Creation) {
-  auto expr = std::make_unique<ast::CallExpression>(
-      std::make_unique<ast::IdentifierExpression>("func"), ExpressionList{});
+  auto expr = create<ast::CallExpression>(
+      create<ast::IdentifierExpression>("func"), ExpressionList{});
   auto* expr_ptr = expr.get();
 
   CallStatement c(std::move(expr));
@@ -39,8 +39,8 @@
 }
 
 TEST_F(CallStatementTest, IsValid) {
-  CallStatement c(std::make_unique<ast::CallExpression>(
-      std::make_unique<ast::IdentifierExpression>("func"), ExpressionList{}));
+  CallStatement c(create<ast::CallExpression>(
+      create<ast::IdentifierExpression>("func"), ExpressionList{}));
   EXPECT_TRUE(c.IsValid());
 }
 
@@ -50,13 +50,13 @@
 }
 
 TEST_F(CallStatementTest, IsValid_InvalidExpr) {
-  CallStatement c(std::make_unique<ast::CallExpression>());
+  CallStatement c(create<ast::CallExpression>());
   EXPECT_FALSE(c.IsValid());
 }
 
 TEST_F(CallStatementTest, ToStr) {
-  CallStatement c(std::make_unique<ast::CallExpression>(
-      std::make_unique<ast::IdentifierExpression>("func"), ExpressionList{}));
+  CallStatement c(create<ast::CallExpression>(
+      create<ast::IdentifierExpression>("func"), ExpressionList{}));
 
   std::ostringstream out;
   c.to_str(out, 2);
diff --git a/src/ast/case_statement_test.cc b/src/ast/case_statement_test.cc
index 9a415c8..1d61291 100644
--- a/src/ast/case_statement_test.cc
+++ b/src/ast/case_statement_test.cc
@@ -32,10 +32,10 @@
   ast::type::I32Type i32;
 
   CaseSelectorList b;
-  b.push_back(std::make_unique<SintLiteral>(&i32, 2));
+  b.push_back(create<SintLiteral>(&i32, 2));
 
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto body = create<BlockStatement>();
+  body->append(create<DiscardStatement>());
 
   auto* int_ptr = b.back().get();
   auto* discard_ptr = body->get(0);
@@ -51,10 +51,10 @@
   ast::type::U32Type u32;
 
   CaseSelectorList b;
-  b.push_back(std::make_unique<UintLiteral>(&u32, 2));
+  b.push_back(create<UintLiteral>(&u32, 2));
 
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto body = create<BlockStatement>();
+  body->append(create<DiscardStatement>());
 
   auto* int_ptr = b.back().get();
   auto* discard_ptr = body->get(0);
@@ -69,10 +69,10 @@
 TEST_F(CaseStatementTest, Creation_WithSource) {
   ast::type::I32Type i32;
   CaseSelectorList b;
-  b.push_back(std::make_unique<SintLiteral>(&i32, 2));
+  b.push_back(create<SintLiteral>(&i32, 2));
 
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto body = create<BlockStatement>();
+  body->append(create<DiscardStatement>());
 
   CaseStatement c(Source{Source::Location{20, 2}}, std::move(b),
                   std::move(body));
@@ -82,8 +82,8 @@
 }
 
 TEST_F(CaseStatementTest, IsDefault_WithoutSelectors) {
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto body = create<BlockStatement>();
+  body->append(create<DiscardStatement>());
 
   CaseStatement c;
   c.set_body(std::move(body));
@@ -93,7 +93,7 @@
 TEST_F(CaseStatementTest, IsDefault_WithSelectors) {
   ast::type::I32Type i32;
   CaseSelectorList b;
-  b.push_back(std::make_unique<SintLiteral>(&i32, 2));
+  b.push_back(create<SintLiteral>(&i32, 2));
 
   CaseStatement c;
   c.set_selectors(std::move(b));
@@ -113,10 +113,10 @@
 TEST_F(CaseStatementTest, IsValid_NullBodyStatement) {
   ast::type::I32Type i32;
   CaseSelectorList b;
-  b.push_back(std::make_unique<SintLiteral>(&i32, 2));
+  b.push_back(create<SintLiteral>(&i32, 2));
 
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto body = create<BlockStatement>();
+  body->append(create<DiscardStatement>());
   body->append(nullptr);
 
   CaseStatement c(std::move(b), std::move(body));
@@ -126,10 +126,10 @@
 TEST_F(CaseStatementTest, IsValid_InvalidBodyStatement) {
   ast::type::I32Type i32;
   CaseSelectorList b;
-  b.push_back(std::make_unique<SintLiteral>(&i32, 2));
+  b.push_back(create<SintLiteral>(&i32, 2));
 
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<IfStatement>());
+  auto body = create<BlockStatement>();
+  body->append(create<IfStatement>());
 
   CaseStatement c({std::move(b)}, std::move(body));
   EXPECT_FALSE(c.IsValid());
@@ -138,10 +138,10 @@
 TEST_F(CaseStatementTest, ToStr_WithSelectors_i32) {
   ast::type::I32Type i32;
   CaseSelectorList b;
-  b.push_back(std::make_unique<SintLiteral>(&i32, -2));
+  b.push_back(create<SintLiteral>(&i32, -2));
 
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto body = create<BlockStatement>();
+  body->append(create<DiscardStatement>());
   CaseStatement c({std::move(b)}, std::move(body));
 
   std::ostringstream out;
@@ -155,10 +155,10 @@
 TEST_F(CaseStatementTest, ToStr_WithSelectors_u32) {
   ast::type::U32Type u32;
   CaseSelectorList b;
-  b.push_back(std::make_unique<UintLiteral>(&u32, 2));
+  b.push_back(create<UintLiteral>(&u32, 2));
 
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto body = create<BlockStatement>();
+  body->append(create<DiscardStatement>());
   CaseStatement c({std::move(b)}, std::move(body));
 
   std::ostringstream out;
@@ -173,11 +173,11 @@
   ast::type::I32Type i32;
 
   CaseSelectorList b;
-  b.push_back(std::make_unique<SintLiteral>(&i32, 1));
-  b.push_back(std::make_unique<SintLiteral>(&i32, 2));
+  b.push_back(create<SintLiteral>(&i32, 1));
+  b.push_back(create<SintLiteral>(&i32, 2));
 
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto body = create<BlockStatement>();
+  body->append(create<DiscardStatement>());
   CaseStatement c(std::move(b), std::move(body));
 
   std::ostringstream out;
@@ -189,8 +189,8 @@
 }
 
 TEST_F(CaseStatementTest, ToStr_WithoutSelectors) {
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto body = create<BlockStatement>();
+  body->append(create<DiscardStatement>());
   CaseStatement c(CaseSelectorList{}, std::move(body));
 
   std::ostringstream out;
diff --git a/src/ast/decorated_variable_test.cc b/src/ast/decorated_variable_test.cc
index 0e51135..7c82d78 100644
--- a/src/ast/decorated_variable_test.cc
+++ b/src/ast/decorated_variable_test.cc
@@ -34,7 +34,7 @@
 
 TEST_F(DecoratedVariableTest, Creation) {
   type::I32Type t;
-  auto var = std::make_unique<Variable>("my_var", StorageClass::kFunction, &t);
+  auto var = create<Variable>("my_var", StorageClass::kFunction, &t);
   DecoratedVariable dv(std::move(var));
 
   EXPECT_EQ(dv.name(), "my_var");
@@ -49,7 +49,7 @@
 TEST_F(DecoratedVariableTest, CreationWithSource) {
   Source s{Source::Range{Source::Location{27, 4}, Source::Location{27, 5}}};
   type::F32Type t;
-  auto var = std::make_unique<Variable>(s, "i", StorageClass::kPrivate, &t);
+  auto var = create<Variable>(s, "i", StorageClass::kPrivate, &t);
   DecoratedVariable dv(std::move(var));
 
   EXPECT_EQ(dv.name(), "i");
@@ -63,7 +63,7 @@
 
 TEST_F(DecoratedVariableTest, NoDecorations) {
   type::I32Type t;
-  auto var = std::make_unique<Variable>("my_var", StorageClass::kFunction, &t);
+  auto var = create<Variable>("my_var", StorageClass::kFunction, &t);
   DecoratedVariable dv(std::move(var));
   EXPECT_FALSE(dv.HasLocationDecoration());
   EXPECT_FALSE(dv.HasBuiltinDecoration());
@@ -72,14 +72,13 @@
 
 TEST_F(DecoratedVariableTest, WithDecorations) {
   type::F32Type t;
-  auto var = std::make_unique<Variable>("my_var", StorageClass::kFunction, &t);
+  auto var = create<Variable>("my_var", StorageClass::kFunction, &t);
   DecoratedVariable dv(std::move(var));
 
   VariableDecorationList decos;
-  decos.push_back(std::make_unique<LocationDecoration>(1, Source{}));
-  decos.push_back(
-      std::make_unique<BuiltinDecoration>(ast::Builtin::kPosition, Source{}));
-  decos.push_back(std::make_unique<ConstantIdDecoration>(1200, Source{}));
+  decos.push_back(create<LocationDecoration>(1, Source{}));
+  decos.push_back(create<BuiltinDecoration>(ast::Builtin::kPosition, Source{}));
+  decos.push_back(create<ConstantIdDecoration>(1200, Source{}));
 
   dv.set_decorations(std::move(decos));
 
@@ -90,11 +89,11 @@
 
 TEST_F(DecoratedVariableTest, ConstantId) {
   type::F32Type t;
-  auto var = std::make_unique<Variable>("my_var", StorageClass::kFunction, &t);
+  auto var = create<Variable>("my_var", StorageClass::kFunction, &t);
   DecoratedVariable dv(std::move(var));
 
   VariableDecorationList decos;
-  decos.push_back(std::make_unique<ConstantIdDecoration>(1200, Source{}));
+  decos.push_back(create<ConstantIdDecoration>(1200, Source{}));
   dv.set_decorations(std::move(decos));
 
   EXPECT_EQ(dv.constant_id(), 1200u);
@@ -102,7 +101,7 @@
 
 TEST_F(DecoratedVariableTest, IsValid) {
   type::I32Type t;
-  auto var = std::make_unique<Variable>("my_var", StorageClass::kNone, &t);
+  auto var = create<Variable>("my_var", StorageClass::kNone, &t);
   DecoratedVariable dv(std::move(var));
   EXPECT_TRUE(dv.IsValid());
 }
@@ -114,13 +113,13 @@
 
 TEST_F(DecoratedVariableTest, to_str) {
   type::F32Type t;
-  auto var = std::make_unique<Variable>("my_var", StorageClass::kFunction, &t);
+  auto var = create<Variable>("my_var", StorageClass::kFunction, &t);
   DecoratedVariable dv(std::move(var));
-  dv.set_constructor(std::make_unique<IdentifierExpression>("expr"));
+  dv.set_constructor(create<IdentifierExpression>("expr"));
 
   VariableDecorationList decos;
-  decos.push_back(std::make_unique<BindingDecoration>(2, Source{}));
-  decos.push_back(std::make_unique<SetDecoration>(1, Source{}));
+  decos.push_back(create<BindingDecoration>(2, Source{}));
+  decos.push_back(create<SetDecoration>(1, Source{}));
 
   dv.set_decorations(std::move(decos));
   std::ostringstream out;
diff --git a/src/ast/decoration_test.cc b/src/ast/decoration_test.cc
index 8f32546..06029e7 100644
--- a/src/ast/decoration_test.cc
+++ b/src/ast/decoration_test.cc
@@ -42,7 +42,7 @@
 }
 
 TEST_F(DecorationTest, Is) {
-  auto decoration = std::make_unique<ConstantIdDecoration>(1, Source{});
+  auto decoration = create<ConstantIdDecoration>(1, Source{});
   EXPECT_TRUE(decoration->Is<VariableDecoration>());
   EXPECT_FALSE(decoration->Is<ArrayDecoration>());
 }
diff --git a/src/ast/else_statement_test.cc b/src/ast/else_statement_test.cc
index 4e436fa..b8ae12a 100644
--- a/src/ast/else_statement_test.cc
+++ b/src/ast/else_statement_test.cc
@@ -29,10 +29,10 @@
 
 TEST_F(ElseStatementTest, Creation) {
   ast::type::BoolType bool_type;
-  auto cond = std::make_unique<ScalarConstructorExpression>(
-      std::make_unique<BoolLiteral>(&bool_type, true));
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto cond = create<ScalarConstructorExpression>(
+      create<BoolLiteral>(&bool_type, true));
+  auto body = create<BlockStatement>();
+  body->append(create<DiscardStatement>());
 
   auto* cond_ptr = cond.get();
   auto* discard_ptr = body->get(0);
@@ -44,8 +44,7 @@
 }
 
 TEST_F(ElseStatementTest, Creation_WithSource) {
-  ElseStatement e(Source{Source::Location{20, 2}},
-                  std::make_unique<BlockStatement>());
+  ElseStatement e(Source{Source::Location{20, 2}}, create<BlockStatement>());
   auto src = e.source();
   EXPECT_EQ(src.range.begin.line, 20u);
   EXPECT_EQ(src.range.begin.column, 2u);
@@ -58,9 +57,9 @@
 
 TEST_F(ElseStatementTest, HasCondition) {
   ast::type::BoolType bool_type;
-  auto cond = std::make_unique<ScalarConstructorExpression>(
-      std::make_unique<BoolLiteral>(&bool_type, true));
-  ElseStatement e(std::move(cond), std::make_unique<BlockStatement>());
+  auto cond = create<ScalarConstructorExpression>(
+      create<BoolLiteral>(&bool_type, true));
+  ElseStatement e(std::move(cond), create<BlockStatement>());
   EXPECT_TRUE(e.HasCondition());
 }
 
@@ -75,16 +74,16 @@
 }
 
 TEST_F(ElseStatementTest, IsValid_WithBody) {
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto body = create<BlockStatement>();
+  body->append(create<DiscardStatement>());
 
   ElseStatement e(std::move(body));
   EXPECT_TRUE(e.IsValid());
 }
 
 TEST_F(ElseStatementTest, IsValid_WithNullBodyStatement) {
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto body = create<BlockStatement>();
+  body->append(create<DiscardStatement>());
   body->append(nullptr);
 
   ElseStatement e(std::move(body));
@@ -92,14 +91,14 @@
 }
 
 TEST_F(ElseStatementTest, IsValid_InvalidCondition) {
-  auto cond = std::make_unique<ScalarConstructorExpression>();
-  ElseStatement e(std::move(cond), std::make_unique<BlockStatement>());
+  auto cond = create<ScalarConstructorExpression>();
+  ElseStatement e(std::move(cond), create<BlockStatement>());
   EXPECT_FALSE(e.IsValid());
 }
 
 TEST_F(ElseStatementTest, IsValid_InvalidBodyStatement) {
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<IfStatement>());
+  auto body = create<BlockStatement>();
+  body->append(create<IfStatement>());
 
   ElseStatement e(std::move(body));
   EXPECT_FALSE(e.IsValid());
@@ -107,10 +106,10 @@
 
 TEST_F(ElseStatementTest, ToStr) {
   ast::type::BoolType bool_type;
-  auto cond = std::make_unique<ScalarConstructorExpression>(
-      std::make_unique<BoolLiteral>(&bool_type, true));
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto cond = create<ScalarConstructorExpression>(
+      create<BoolLiteral>(&bool_type, true));
+  auto body = create<BlockStatement>();
+  body->append(create<DiscardStatement>());
 
   ElseStatement e(std::move(cond), std::move(body));
   std::ostringstream out;
@@ -127,8 +126,8 @@
 }
 
 TEST_F(ElseStatementTest, ToStr_NoCondition) {
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto body = create<BlockStatement>();
+  body->append(create<DiscardStatement>());
 
   ElseStatement e(std::move(body));
   std::ostringstream out;
diff --git a/src/ast/function_test.cc b/src/ast/function_test.cc
index 34c01a8..91785bc 100644
--- a/src/ast/function_test.cc
+++ b/src/ast/function_test.cc
@@ -37,8 +37,7 @@
   type::I32Type i32;
 
   VariableList params;
-  params.push_back(
-      std::make_unique<Variable>("var", StorageClass::kNone, &i32));
+  params.push_back(create<Variable>("var", StorageClass::kNone, &i32));
   auto* var_ptr = params[0].get();
 
   Function f("func", std::move(params), &void_type);
@@ -53,8 +52,7 @@
   type::I32Type i32;
 
   VariableList params;
-  params.push_back(
-      std::make_unique<Variable>("var", StorageClass::kNone, &i32));
+  params.push_back(create<Variable>("var", StorageClass::kNone, &i32));
 
   Function f(Source{Source::Location{20, 2}}, "func", std::move(params),
              &void_type);
@@ -89,25 +87,25 @@
 
   VariableDecorationList decos;
   DecoratedVariable loc1(
-      std::make_unique<ast::Variable>("loc1", StorageClass::kInput, &i32));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(0, Source{}));
+      create<ast::Variable>("loc1", StorageClass::kInput, &i32));
+  decos.push_back(create<ast::LocationDecoration>(0, Source{}));
   loc1.set_decorations(std::move(decos));
 
   DecoratedVariable loc2(
-      std::make_unique<ast::Variable>("loc2", StorageClass::kInput, &i32));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(1, Source{}));
+      create<ast::Variable>("loc2", StorageClass::kInput, &i32));
+  decos.push_back(create<ast::LocationDecoration>(1, Source{}));
   loc2.set_decorations(std::move(decos));
 
   DecoratedVariable builtin1(
-      std::make_unique<ast::Variable>("builtin1", StorageClass::kInput, &i32));
-  decos.push_back(std::make_unique<ast::BuiltinDecoration>(
-      ast::Builtin::kPosition, Source{}));
+      create<ast::Variable>("builtin1", StorageClass::kInput, &i32));
+  decos.push_back(
+      create<ast::BuiltinDecoration>(ast::Builtin::kPosition, Source{}));
   builtin1.set_decorations(std::move(decos));
 
   DecoratedVariable builtin2(
-      std::make_unique<ast::Variable>("builtin2", StorageClass::kInput, &i32));
-  decos.push_back(std::make_unique<ast::BuiltinDecoration>(
-      ast::Builtin::kFragDepth, Source{}));
+      create<ast::Variable>("builtin2", StorageClass::kInput, &i32));
+  decos.push_back(
+      create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{}));
   builtin2.set_decorations(std::move(decos));
 
   Function f("func", VariableList{}, &void_type);
@@ -132,25 +130,25 @@
 
   VariableDecorationList decos;
   DecoratedVariable loc1(
-      std::make_unique<ast::Variable>("loc1", StorageClass::kInput, &i32));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(0, Source{}));
+      create<ast::Variable>("loc1", StorageClass::kInput, &i32));
+  decos.push_back(create<ast::LocationDecoration>(0, Source{}));
   loc1.set_decorations(std::move(decos));
 
   DecoratedVariable loc2(
-      std::make_unique<ast::Variable>("loc2", StorageClass::kInput, &i32));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(1, Source{}));
+      create<ast::Variable>("loc2", StorageClass::kInput, &i32));
+  decos.push_back(create<ast::LocationDecoration>(1, Source{}));
   loc2.set_decorations(std::move(decos));
 
   DecoratedVariable builtin1(
-      std::make_unique<ast::Variable>("builtin1", StorageClass::kInput, &i32));
-  decos.push_back(std::make_unique<ast::BuiltinDecoration>(
-      ast::Builtin::kPosition, Source{}));
+      create<ast::Variable>("builtin1", StorageClass::kInput, &i32));
+  decos.push_back(
+      create<ast::BuiltinDecoration>(ast::Builtin::kPosition, Source{}));
   builtin1.set_decorations(std::move(decos));
 
   DecoratedVariable builtin2(
-      std::make_unique<ast::Variable>("builtin2", StorageClass::kInput, &i32));
-  decos.push_back(std::make_unique<ast::BuiltinDecoration>(
-      ast::Builtin::kFragDepth, Source{}));
+      create<ast::Variable>("builtin2", StorageClass::kInput, &i32));
+  decos.push_back(
+      create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth, Source{}));
   builtin2.set_decorations(std::move(decos));
 
   Function f("func", VariableList{}, &void_type);
@@ -187,11 +185,10 @@
   type::I32Type i32;
 
   VariableList params;
-  params.push_back(
-      std::make_unique<Variable>("var", StorageClass::kNone, &i32));
+  params.push_back(create<Variable>("var", StorageClass::kNone, &i32));
 
-  auto block = std::make_unique<ast::BlockStatement>();
-  block->append(std::make_unique<DiscardStatement>());
+  auto block = create<ast::BlockStatement>();
+  block->append(create<DiscardStatement>());
 
   Function f("func", std::move(params), &void_type);
   f.set_body(std::move(block));
@@ -203,8 +200,7 @@
   type::I32Type i32;
 
   VariableList params;
-  params.push_back(
-      std::make_unique<Variable>("var", StorageClass::kNone, &i32));
+  params.push_back(create<Variable>("var", StorageClass::kNone, &i32));
 
   Function f("", std::move(params), &void_type);
   EXPECT_FALSE(f.IsValid());
@@ -214,8 +210,7 @@
   type::I32Type i32;
 
   VariableList params;
-  params.push_back(
-      std::make_unique<Variable>("var", StorageClass::kNone, &i32));
+  params.push_back(create<Variable>("var", StorageClass::kNone, &i32));
 
   Function f("func", std::move(params), nullptr);
   EXPECT_FALSE(f.IsValid());
@@ -226,8 +221,7 @@
   type::I32Type i32;
 
   VariableList params;
-  params.push_back(
-      std::make_unique<Variable>("var", StorageClass::kNone, &i32));
+  params.push_back(create<Variable>("var", StorageClass::kNone, &i32));
   params.push_back(nullptr);
 
   Function f("func", std::move(params), &void_type);
@@ -238,8 +232,7 @@
   type::VoidType void_type;
 
   VariableList params;
-  params.push_back(
-      std::make_unique<Variable>("var", StorageClass::kNone, nullptr));
+  params.push_back(create<Variable>("var", StorageClass::kNone, nullptr));
 
   Function f("func", std::move(params), &void_type);
   EXPECT_FALSE(f.IsValid());
@@ -250,11 +243,10 @@
   type::I32Type i32;
 
   VariableList params;
-  params.push_back(
-      std::make_unique<Variable>("var", StorageClass::kNone, &i32));
+  params.push_back(create<Variable>("var", StorageClass::kNone, &i32));
 
-  auto block = std::make_unique<ast::BlockStatement>();
-  block->append(std::make_unique<DiscardStatement>());
+  auto block = create<ast::BlockStatement>();
+  block->append(create<DiscardStatement>());
   block->append(nullptr);
 
   Function f("func", std::move(params), &void_type);
@@ -267,11 +259,10 @@
   type::I32Type i32;
 
   VariableList params;
-  params.push_back(
-      std::make_unique<Variable>("var", StorageClass::kNone, &i32));
+  params.push_back(create<Variable>("var", StorageClass::kNone, &i32));
 
-  auto block = std::make_unique<ast::BlockStatement>();
-  block->append(std::make_unique<DiscardStatement>());
+  auto block = create<ast::BlockStatement>();
+  block->append(create<DiscardStatement>());
   block->append(nullptr);
 
   Function f("func", std::move(params), &void_type);
@@ -283,8 +274,8 @@
   type::VoidType void_type;
   type::I32Type i32;
 
-  auto block = std::make_unique<ast::BlockStatement>();
-  block->append(std::make_unique<DiscardStatement>());
+  auto block = create<ast::BlockStatement>();
+  block->append(create<DiscardStatement>());
 
   Function f("func", {}, &void_type);
   f.set_body(std::move(block));
@@ -303,12 +294,12 @@
   type::VoidType void_type;
   type::I32Type i32;
 
-  auto block = std::make_unique<ast::BlockStatement>();
-  block->append(std::make_unique<DiscardStatement>());
+  auto block = create<ast::BlockStatement>();
+  block->append(create<DiscardStatement>());
 
   Function f("func", {}, &void_type);
   f.set_body(std::move(block));
-  f.add_decoration(std::make_unique<WorkgroupDecoration>(2, 4, 6, Source{}));
+  f.add_decoration(create<WorkgroupDecoration>(2, 4, 6, Source{}));
 
   std::ostringstream out;
   f.to_str(out, 2);
@@ -326,11 +317,10 @@
   type::I32Type i32;
 
   VariableList params;
-  params.push_back(
-      std::make_unique<Variable>("var", StorageClass::kNone, &i32));
+  params.push_back(create<Variable>("var", StorageClass::kNone, &i32));
 
-  auto block = std::make_unique<ast::BlockStatement>();
-  block->append(std::make_unique<DiscardStatement>());
+  auto block = create<ast::BlockStatement>();
+  block->append(create<DiscardStatement>());
 
   Function f("func", std::move(params), &void_type);
   f.set_body(std::move(block));
@@ -364,10 +354,8 @@
   type::F32Type f32;
 
   VariableList params;
-  params.push_back(
-      std::make_unique<Variable>("var1", StorageClass::kNone, &i32));
-  params.push_back(
-      std::make_unique<Variable>("var2", StorageClass::kNone, &f32));
+  params.push_back(create<Variable>("var1", StorageClass::kNone, &i32));
+  params.push_back(create<Variable>("var2", StorageClass::kNone, &f32));
 
   Function f("func", std::move(params), &void_type);
   EXPECT_EQ(f.type_name(), "__func__void__i32__f32");
@@ -377,8 +365,8 @@
   type::VoidType void_type;
 
   VariableList params;
-  auto body = std::make_unique<ast::BlockStatement>();
-  auto stmt = std::make_unique<DiscardStatement>();
+  auto body = create<ast::BlockStatement>();
+  auto stmt = create<DiscardStatement>();
   auto* stmt_ptr = stmt.get();
   body->append(std::move(stmt));
   Function f("func", std::move(params), &void_type);
@@ -391,7 +379,7 @@
   type::VoidType void_type;
 
   VariableList params;
-  auto body = std::make_unique<ast::BlockStatement>();
+  auto body = create<ast::BlockStatement>();
   Function f("func", std::move(params), &void_type);
   f.set_body(std::move(body));
 
@@ -413,7 +401,7 @@
 TEST_F(FunctionTest, WorkgroupSize) {
   type::VoidType void_type;
   Function f("f", {}, &void_type);
-  f.add_decoration(std::make_unique<WorkgroupDecoration>(2u, 4u, 6u, Source{}));
+  f.add_decoration(create<WorkgroupDecoration>(2u, 4u, 6u, Source{}));
 
   uint32_t x = 0;
   uint32_t y = 0;
diff --git a/src/ast/if_statement_test.cc b/src/ast/if_statement_test.cc
index e36cc1f..d63368b 100644
--- a/src/ast/if_statement_test.cc
+++ b/src/ast/if_statement_test.cc
@@ -25,9 +25,9 @@
 using IfStatementTest = TestHelper;
 
 TEST_F(IfStatementTest, Creation) {
-  auto cond = std::make_unique<IdentifierExpression>("cond");
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto cond = create<IdentifierExpression>("cond");
+  auto body = create<ast::BlockStatement>();
+  body->append(create<DiscardStatement>());
 
   auto* cond_ptr = cond.get();
   auto* stmt_ptr = body->get(0);
@@ -39,9 +39,9 @@
 }
 
 TEST_F(IfStatementTest, Creation_WithSource) {
-  auto cond = std::make_unique<IdentifierExpression>("cond");
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto cond = create<IdentifierExpression>("cond");
+  auto body = create<ast::BlockStatement>();
+  body->append(create<DiscardStatement>());
 
   IfStatement stmt(Source{Source::Location{20, 2}}, std::move(cond),
                    std::move(body));
@@ -56,23 +56,23 @@
 }
 
 TEST_F(IfStatementTest, IsValid) {
-  auto cond = std::make_unique<IdentifierExpression>("cond");
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto cond = create<IdentifierExpression>("cond");
+  auto body = create<ast::BlockStatement>();
+  body->append(create<DiscardStatement>());
 
   IfStatement stmt(std::move(cond), std::move(body));
   EXPECT_TRUE(stmt.IsValid());
 }
 
 TEST_F(IfStatementTest, IsValid_WithElseStatements) {
-  auto cond = std::make_unique<IdentifierExpression>("cond");
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto cond = create<IdentifierExpression>("cond");
+  auto body = create<ast::BlockStatement>();
+  body->append(create<DiscardStatement>());
 
   ElseStatementList else_stmts;
-  else_stmts.push_back(std::make_unique<ElseStatement>());
-  else_stmts[0]->set_condition(std::make_unique<IdentifierExpression>("Ident"));
-  else_stmts.push_back(std::make_unique<ElseStatement>());
+  else_stmts.push_back(create<ElseStatement>());
+  else_stmts[0]->set_condition(create<IdentifierExpression>("Ident"));
+  else_stmts.push_back(create<ElseStatement>());
 
   IfStatement stmt(std::move(cond), std::move(body));
   stmt.set_else_statements(std::move(else_stmts));
@@ -80,26 +80,26 @@
 }
 
 TEST_F(IfStatementTest, IsValid_MissingCondition) {
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto body = create<ast::BlockStatement>();
+  body->append(create<DiscardStatement>());
 
   IfStatement stmt(nullptr, std::move(body));
   EXPECT_FALSE(stmt.IsValid());
 }
 
 TEST_F(IfStatementTest, IsValid_InvalidCondition) {
-  auto cond = std::make_unique<IdentifierExpression>("");
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto cond = create<IdentifierExpression>("");
+  auto body = create<ast::BlockStatement>();
+  body->append(create<DiscardStatement>());
 
   IfStatement stmt(std::move(cond), std::move(body));
   EXPECT_FALSE(stmt.IsValid());
 }
 
 TEST_F(IfStatementTest, IsValid_NullBodyStatement) {
-  auto cond = std::make_unique<IdentifierExpression>("cond");
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto cond = create<IdentifierExpression>("cond");
+  auto body = create<ast::BlockStatement>();
+  body->append(create<DiscardStatement>());
   body->append(nullptr);
 
   IfStatement stmt(std::move(cond), std::move(body));
@@ -107,24 +107,24 @@
 }
 
 TEST_F(IfStatementTest, IsValid_InvalidBodyStatement) {
-  auto cond = std::make_unique<IdentifierExpression>("cond");
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
-  body->append(std::make_unique<IfStatement>());
+  auto cond = create<IdentifierExpression>("cond");
+  auto body = create<ast::BlockStatement>();
+  body->append(create<DiscardStatement>());
+  body->append(create<IfStatement>());
 
   IfStatement stmt(std::move(cond), std::move(body));
   EXPECT_FALSE(stmt.IsValid());
 }
 
 TEST_F(IfStatementTest, IsValid_NullElseStatement) {
-  auto cond = std::make_unique<IdentifierExpression>("cond");
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto cond = create<IdentifierExpression>("cond");
+  auto body = create<ast::BlockStatement>();
+  body->append(create<DiscardStatement>());
 
   ElseStatementList else_stmts;
-  else_stmts.push_back(std::make_unique<ElseStatement>());
-  else_stmts[0]->set_condition(std::make_unique<IdentifierExpression>("Ident"));
-  else_stmts.push_back(std::make_unique<ElseStatement>());
+  else_stmts.push_back(create<ElseStatement>());
+  else_stmts[0]->set_condition(create<IdentifierExpression>("Ident"));
+  else_stmts.push_back(create<ElseStatement>());
   else_stmts.push_back(nullptr);
 
   IfStatement stmt(std::move(cond), std::move(body));
@@ -133,13 +133,13 @@
 }
 
 TEST_F(IfStatementTest, IsValid_InvalidElseStatement) {
-  auto cond = std::make_unique<IdentifierExpression>("cond");
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto cond = create<IdentifierExpression>("cond");
+  auto body = create<ast::BlockStatement>();
+  body->append(create<DiscardStatement>());
 
   ElseStatementList else_stmts;
-  else_stmts.push_back(std::make_unique<ElseStatement>());
-  else_stmts[0]->set_condition(std::make_unique<IdentifierExpression>(""));
+  else_stmts.push_back(create<ElseStatement>());
+  else_stmts[0]->set_condition(create<IdentifierExpression>(""));
 
   IfStatement stmt(std::move(cond), std::move(body));
   stmt.set_else_statements(std::move(else_stmts));
@@ -147,13 +147,13 @@
 }
 
 TEST_F(IfStatementTest, IsValid_MultipleElseWiththoutCondition) {
-  auto cond = std::make_unique<IdentifierExpression>("cond");
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto cond = create<IdentifierExpression>("cond");
+  auto body = create<ast::BlockStatement>();
+  body->append(create<DiscardStatement>());
 
   ElseStatementList else_stmts;
-  else_stmts.push_back(std::make_unique<ElseStatement>());
-  else_stmts.push_back(std::make_unique<ElseStatement>());
+  else_stmts.push_back(create<ElseStatement>());
+  else_stmts.push_back(create<ElseStatement>());
 
   IfStatement stmt(std::move(cond), std::move(body));
   stmt.set_else_statements(std::move(else_stmts));
@@ -161,14 +161,14 @@
 }
 
 TEST_F(IfStatementTest, IsValid_ElseNotLast) {
-  auto cond = std::make_unique<IdentifierExpression>("cond");
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto cond = create<IdentifierExpression>("cond");
+  auto body = create<ast::BlockStatement>();
+  body->append(create<DiscardStatement>());
 
   ElseStatementList else_stmts;
-  else_stmts.push_back(std::make_unique<ElseStatement>());
-  else_stmts.push_back(std::make_unique<ElseStatement>());
-  else_stmts[1]->set_condition(std::make_unique<IdentifierExpression>("ident"));
+  else_stmts.push_back(create<ElseStatement>());
+  else_stmts.push_back(create<ElseStatement>());
+  else_stmts[1]->set_condition(create<IdentifierExpression>("ident"));
 
   IfStatement stmt(std::move(cond), std::move(body));
   stmt.set_else_statements(std::move(else_stmts));
@@ -176,9 +176,9 @@
 }
 
 TEST_F(IfStatementTest, ToStr) {
-  auto cond = std::make_unique<IdentifierExpression>("cond");
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto cond = create<IdentifierExpression>("cond");
+  auto body = create<ast::BlockStatement>();
+  body->append(create<DiscardStatement>());
 
   IfStatement stmt(std::move(cond), std::move(body));
 
@@ -196,22 +196,22 @@
 }
 
 TEST_F(IfStatementTest, ToStr_WithElseStatements) {
-  auto cond = std::make_unique<IdentifierExpression>("cond");
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto cond = create<IdentifierExpression>("cond");
+  auto body = create<ast::BlockStatement>();
+  body->append(create<DiscardStatement>());
 
-  auto else_if_body = std::make_unique<BlockStatement>();
-  else_if_body->append(std::make_unique<DiscardStatement>());
+  auto else_if_body = create<BlockStatement>();
+  else_if_body->append(create<DiscardStatement>());
 
-  auto else_body = std::make_unique<BlockStatement>();
-  else_body->append(std::make_unique<DiscardStatement>());
-  else_body->append(std::make_unique<DiscardStatement>());
+  auto else_body = create<BlockStatement>();
+  else_body->append(create<DiscardStatement>());
+  else_body->append(create<DiscardStatement>());
 
   ElseStatementList else_stmts;
-  else_stmts.push_back(std::make_unique<ElseStatement>());
-  else_stmts[0]->set_condition(std::make_unique<IdentifierExpression>("ident"));
+  else_stmts.push_back(create<ElseStatement>());
+  else_stmts[0]->set_condition(create<IdentifierExpression>("ident"));
   else_stmts[0]->set_body(std::move(else_if_body));
-  else_stmts.push_back(std::make_unique<ElseStatement>());
+  else_stmts.push_back(create<ElseStatement>());
   else_stmts[1]->set_body(std::move(else_body));
 
   IfStatement stmt(std::move(cond), std::move(body));
diff --git a/src/ast/loop_statement_test.cc b/src/ast/loop_statement_test.cc
index 73f0f93..a090f9a 100644
--- a/src/ast/loop_statement_test.cc
+++ b/src/ast/loop_statement_test.cc
@@ -28,12 +28,12 @@
 using LoopStatementTest = TestHelper;
 
 TEST_F(LoopStatementTest, Creation) {
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto body = create<BlockStatement>();
+  body->append(create<DiscardStatement>());
   auto* b_ptr = body->last();
 
-  auto continuing = std::make_unique<BlockStatement>();
-  continuing->append(std::make_unique<DiscardStatement>());
+  auto continuing = create<BlockStatement>();
+  continuing->append(create<DiscardStatement>());
   auto* c_ptr = continuing->last();
 
   LoopStatement l(std::move(body), std::move(continuing));
@@ -44,11 +44,11 @@
 }
 
 TEST_F(LoopStatementTest, Creation_WithSource) {
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto body = create<BlockStatement>();
+  body->append(create<DiscardStatement>());
 
-  auto continuing = std::make_unique<BlockStatement>();
-  continuing->append(std::make_unique<DiscardStatement>());
+  auto continuing = create<BlockStatement>();
+  continuing->append(create<DiscardStatement>());
 
   LoopStatement l(Source{Source::Location{20, 2}}, std::move(body),
                   std::move(continuing));
@@ -63,79 +63,78 @@
 }
 
 TEST_F(LoopStatementTest, HasContinuing_WithoutContinuing) {
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto body = create<BlockStatement>();
+  body->append(create<DiscardStatement>());
 
   LoopStatement l(std::move(body), {});
   EXPECT_FALSE(l.has_continuing());
 }
 
 TEST_F(LoopStatementTest, HasContinuing_WithContinuing) {
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto body = create<BlockStatement>();
+  body->append(create<DiscardStatement>());
 
-  auto continuing = std::make_unique<BlockStatement>();
-  continuing->append(std::make_unique<DiscardStatement>());
+  auto continuing = create<BlockStatement>();
+  continuing->append(create<DiscardStatement>());
 
   LoopStatement l(std::move(body), std::move(continuing));
   EXPECT_TRUE(l.has_continuing());
 }
 
 TEST_F(LoopStatementTest, IsValid) {
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto body = create<BlockStatement>();
+  body->append(create<DiscardStatement>());
 
-  auto continuing = std::make_unique<BlockStatement>();
-  continuing->append(std::make_unique<DiscardStatement>());
+  auto continuing = create<BlockStatement>();
+  continuing->append(create<DiscardStatement>());
 
   LoopStatement l(std::move(body), std::move(continuing));
   EXPECT_TRUE(l.IsValid());
 }
 
 TEST_F(LoopStatementTest, IsValid_WithoutContinuing) {
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto body = create<BlockStatement>();
+  body->append(create<DiscardStatement>());
 
-  LoopStatement l(std::move(body), std::make_unique<BlockStatement>());
+  LoopStatement l(std::move(body), create<BlockStatement>());
   EXPECT_TRUE(l.IsValid());
 }
 
 TEST_F(LoopStatementTest, IsValid_WithoutBody) {
-  LoopStatement l(std::make_unique<BlockStatement>(),
-                  std::make_unique<BlockStatement>());
+  LoopStatement l(create<BlockStatement>(), create<BlockStatement>());
   EXPECT_TRUE(l.IsValid());
 }
 
 TEST_F(LoopStatementTest, IsValid_NullBodyStatement) {
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto body = create<BlockStatement>();
+  body->append(create<DiscardStatement>());
   body->append(nullptr);
 
-  auto continuing = std::make_unique<BlockStatement>();
-  continuing->append(std::make_unique<DiscardStatement>());
+  auto continuing = create<BlockStatement>();
+  continuing->append(create<DiscardStatement>());
 
   LoopStatement l(std::move(body), std::move(continuing));
   EXPECT_FALSE(l.IsValid());
 }
 
 TEST_F(LoopStatementTest, IsValid_InvalidBodyStatement) {
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
-  body->append(std::make_unique<IfStatement>());
+  auto body = create<BlockStatement>();
+  body->append(create<DiscardStatement>());
+  body->append(create<IfStatement>());
 
-  auto continuing = std::make_unique<BlockStatement>();
-  continuing->append(std::make_unique<DiscardStatement>());
+  auto continuing = create<BlockStatement>();
+  continuing->append(create<DiscardStatement>());
 
   LoopStatement l(std::move(body), std::move(continuing));
   EXPECT_FALSE(l.IsValid());
 }
 
 TEST_F(LoopStatementTest, IsValid_NullContinuingStatement) {
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto body = create<BlockStatement>();
+  body->append(create<DiscardStatement>());
 
-  auto continuing = std::make_unique<BlockStatement>();
-  continuing->append(std::make_unique<DiscardStatement>());
+  auto continuing = create<BlockStatement>();
+  continuing->append(create<DiscardStatement>());
   continuing->append(nullptr);
 
   LoopStatement l(std::move(body), std::move(continuing));
@@ -143,20 +142,20 @@
 }
 
 TEST_F(LoopStatementTest, IsValid_InvalidContinuingStatement) {
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto body = create<BlockStatement>();
+  body->append(create<DiscardStatement>());
 
-  auto continuing = std::make_unique<BlockStatement>();
-  continuing->append(std::make_unique<DiscardStatement>());
-  continuing->append(std::make_unique<IfStatement>());
+  auto continuing = create<BlockStatement>();
+  continuing->append(create<DiscardStatement>());
+  continuing->append(create<IfStatement>());
 
   LoopStatement l(std::move(body), std::move(continuing));
   EXPECT_FALSE(l.IsValid());
 }
 
 TEST_F(LoopStatementTest, ToStr) {
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto body = create<BlockStatement>();
+  body->append(create<DiscardStatement>());
 
   LoopStatement l(std::move(body), {});
   std::ostringstream out;
@@ -168,11 +167,11 @@
 }
 
 TEST_F(LoopStatementTest, ToStr_WithContinuing) {
-  auto body = std::make_unique<BlockStatement>();
-  body->append(std::make_unique<DiscardStatement>());
+  auto body = create<BlockStatement>();
+  body->append(create<DiscardStatement>());
 
-  auto continuing = std::make_unique<BlockStatement>();
-  continuing->append(std::make_unique<DiscardStatement>());
+  auto continuing = create<BlockStatement>();
+  continuing->append(create<DiscardStatement>());
 
   LoopStatement l(std::move(body), std::move(continuing));
   std::ostringstream out;
diff --git a/src/ast/member_accessor_expression_test.cc b/src/ast/member_accessor_expression_test.cc
index 4c49327..6dc2a9e 100644
--- a/src/ast/member_accessor_expression_test.cc
+++ b/src/ast/member_accessor_expression_test.cc
@@ -26,8 +26,8 @@
 using MemberAccessorExpressionTest = TestHelper;
 
 TEST_F(MemberAccessorExpressionTest, Creation) {
-  auto str = std::make_unique<IdentifierExpression>("structure");
-  auto mem = std::make_unique<IdentifierExpression>("member");
+  auto str = create<IdentifierExpression>("structure");
+  auto mem = create<IdentifierExpression>("member");
 
   auto* str_ptr = str.get();
   auto* mem_ptr = mem.get();
@@ -38,8 +38,8 @@
 }
 
 TEST_F(MemberAccessorExpressionTest, Creation_WithSource) {
-  auto str = std::make_unique<IdentifierExpression>("structure");
-  auto mem = std::make_unique<IdentifierExpression>("member");
+  auto str = create<IdentifierExpression>("structure");
+  auto mem = create<IdentifierExpression>("member");
 
   MemberAccessorExpression stmt(Source{Source::Location{20, 2}}, std::move(str),
                                 std::move(mem));
@@ -54,15 +54,15 @@
 }
 
 TEST_F(MemberAccessorExpressionTest, IsValid) {
-  auto str = std::make_unique<IdentifierExpression>("structure");
-  auto mem = std::make_unique<IdentifierExpression>("member");
+  auto str = create<IdentifierExpression>("structure");
+  auto mem = create<IdentifierExpression>("member");
 
   MemberAccessorExpression stmt(std::move(str), std::move(mem));
   EXPECT_TRUE(stmt.IsValid());
 }
 
 TEST_F(MemberAccessorExpressionTest, IsValid_NullStruct) {
-  auto mem = std::make_unique<IdentifierExpression>("member");
+  auto mem = create<IdentifierExpression>("member");
 
   MemberAccessorExpression stmt;
   stmt.set_member(std::move(mem));
@@ -70,15 +70,15 @@
 }
 
 TEST_F(MemberAccessorExpressionTest, IsValid_InvalidStruct) {
-  auto str = std::make_unique<IdentifierExpression>("");
-  auto mem = std::make_unique<IdentifierExpression>("member");
+  auto str = create<IdentifierExpression>("");
+  auto mem = create<IdentifierExpression>("member");
 
   MemberAccessorExpression stmt(std::move(str), std::move(mem));
   EXPECT_FALSE(stmt.IsValid());
 }
 
 TEST_F(MemberAccessorExpressionTest, IsValid_NullMember) {
-  auto str = std::make_unique<IdentifierExpression>("structure");
+  auto str = create<IdentifierExpression>("structure");
 
   MemberAccessorExpression stmt;
   stmt.set_structure(std::move(str));
@@ -86,16 +86,16 @@
 }
 
 TEST_F(MemberAccessorExpressionTest, IsValid_InvalidMember) {
-  auto str = std::make_unique<IdentifierExpression>("structure");
-  auto mem = std::make_unique<IdentifierExpression>("");
+  auto str = create<IdentifierExpression>("structure");
+  auto mem = create<IdentifierExpression>("");
 
   MemberAccessorExpression stmt(std::move(str), std::move(mem));
   EXPECT_FALSE(stmt.IsValid());
 }
 
 TEST_F(MemberAccessorExpressionTest, ToStr) {
-  auto str = std::make_unique<IdentifierExpression>("structure");
-  auto mem = std::make_unique<IdentifierExpression>("member");
+  auto str = create<IdentifierExpression>("structure");
+  auto mem = create<IdentifierExpression>("member");
 
   MemberAccessorExpression stmt(std::move(str), std::move(mem));
   std::ostringstream out;
diff --git a/src/ast/module_test.cc b/src/ast/module_test.cc
index f5fd5ae..eaddc07 100644
--- a/src/ast/module_test.cc
+++ b/src/ast/module_test.cc
@@ -48,7 +48,7 @@
   type::F32Type f32;
   Module m;
 
-  auto func = std::make_unique<Function>("main", VariableList{}, &f32);
+  auto func = create<Function>("main", VariableList{}, &f32);
   auto* func_ptr = func.get();
   m.AddFunction(std::move(func));
   EXPECT_EQ(func_ptr, m.FindFunctionByName("main"));
@@ -66,7 +66,7 @@
 
 TEST_F(ModuleTest, IsValid_GlobalVariable) {
   type::F32Type f32;
-  auto var = std::make_unique<Variable>("var", StorageClass::kInput, &f32);
+  auto var = create<Variable>("var", StorageClass::kInput, &f32);
 
   Module m;
   m.AddGlobalVariable(std::move(var));
@@ -80,7 +80,7 @@
 }
 
 TEST_F(ModuleTest, IsValid_Invalid_GlobalVariable) {
-  auto var = std::make_unique<Variable>("var", StorageClass::kInput, nullptr);
+  auto var = create<Variable>("var", StorageClass::kInput, nullptr);
 
   Module m;
   m.AddGlobalVariable(std::move(var));
@@ -124,7 +124,7 @@
 
 TEST_F(ModuleTest, IsValid_Function) {
   type::F32Type f32;
-  auto func = std::make_unique<Function>("main", VariableList(), &f32);
+  auto func = create<Function>("main", VariableList(), &f32);
 
   Module m;
   m.AddFunction(std::move(func));
@@ -138,7 +138,7 @@
 }
 
 TEST_F(ModuleTest, IsValid_Invalid_Function) {
-  auto func = std::make_unique<Function>();
+  auto func = create<Function>();
 
   Module m;
   m.AddFunction(std::move(func));
diff --git a/src/ast/return_statement_test.cc b/src/ast/return_statement_test.cc
index 0a68f9ba..02bf3d2 100644
--- a/src/ast/return_statement_test.cc
+++ b/src/ast/return_statement_test.cc
@@ -26,7 +26,7 @@
 using ReturnStatementTest = TestHelper;
 
 TEST_F(ReturnStatementTest, Creation) {
-  auto expr = std::make_unique<IdentifierExpression>("expr");
+  auto expr = create<IdentifierExpression>("expr");
   auto* expr_ptr = expr.get();
 
   ReturnStatement r(std::move(expr));
@@ -51,7 +51,7 @@
 }
 
 TEST_F(ReturnStatementTest, HasValue_WithValue) {
-  auto expr = std::make_unique<IdentifierExpression>("expr");
+  auto expr = create<IdentifierExpression>("expr");
   ReturnStatement r(std::move(expr));
   EXPECT_TRUE(r.has_value());
 }
@@ -62,19 +62,19 @@
 }
 
 TEST_F(ReturnStatementTest, IsValid_WithValue) {
-  auto expr = std::make_unique<IdentifierExpression>("expr");
+  auto expr = create<IdentifierExpression>("expr");
   ReturnStatement r(std::move(expr));
   EXPECT_TRUE(r.IsValid());
 }
 
 TEST_F(ReturnStatementTest, IsValid_InvalidValue) {
-  auto expr = std::make_unique<IdentifierExpression>("");
+  auto expr = create<IdentifierExpression>("");
   ReturnStatement r(std::move(expr));
   EXPECT_FALSE(r.IsValid());
 }
 
 TEST_F(ReturnStatementTest, ToStr_WithValue) {
-  auto expr = std::make_unique<IdentifierExpression>("expr");
+  auto expr = create<IdentifierExpression>("expr");
   ReturnStatement r(std::move(expr));
   std::ostringstream out;
   r.to_str(out, 2);
diff --git a/src/ast/scalar_constructor_expression_test.cc b/src/ast/scalar_constructor_expression_test.cc
index b82dbfa..9ca57a7 100644
--- a/src/ast/scalar_constructor_expression_test.cc
+++ b/src/ast/scalar_constructor_expression_test.cc
@@ -26,7 +26,7 @@
 
 TEST_F(ScalarConstructorExpressionTest, Creation) {
   ast::type::BoolType bool_type;
-  auto b = std::make_unique<BoolLiteral>(&bool_type, true);
+  auto b = create<BoolLiteral>(&bool_type, true);
   auto* b_ptr = b.get();
   ScalarConstructorExpression c(std::move(b));
   EXPECT_EQ(c.literal(), b_ptr);
@@ -34,7 +34,7 @@
 
 TEST_F(ScalarConstructorExpressionTest, Creation_WithSource) {
   ast::type::BoolType bool_type;
-  auto b = std::make_unique<BoolLiteral>(&bool_type, true);
+  auto b = create<BoolLiteral>(&bool_type, true);
   ScalarConstructorExpression c(Source{Source::Location{20, 2}}, std::move(b));
   auto src = c.source();
   EXPECT_EQ(src.range.begin.line, 20u);
@@ -43,7 +43,7 @@
 
 TEST_F(ScalarConstructorExpressionTest, IsValid) {
   ast::type::BoolType bool_type;
-  auto b = std::make_unique<BoolLiteral>(&bool_type, true);
+  auto b = create<BoolLiteral>(&bool_type, true);
   ScalarConstructorExpression c(std::move(b));
   EXPECT_TRUE(c.IsValid());
 }
@@ -55,7 +55,7 @@
 
 TEST_F(ScalarConstructorExpressionTest, ToStr) {
   ast::type::BoolType bool_type;
-  auto b = std::make_unique<BoolLiteral>(&bool_type, true);
+  auto b = create<BoolLiteral>(&bool_type, true);
   ScalarConstructorExpression c(std::move(b));
   std::ostringstream out;
   c.to_str(out, 2);
diff --git a/src/ast/struct_member_test.cc b/src/ast/struct_member_test.cc
index 20912bc..4981a2c 100644
--- a/src/ast/struct_member_test.cc
+++ b/src/ast/struct_member_test.cc
@@ -30,8 +30,7 @@
 TEST_F(StructMemberTest, Creation) {
   type::I32Type i32;
   StructMemberDecorationList decorations;
-  decorations.emplace_back(
-      std::make_unique<StructMemberOffsetDecoration>(4, Source{}));
+  decorations.emplace_back(create<StructMemberOffsetDecoration>(4, Source{}));
 
   StructMember st{"a", &i32, std::move(decorations)};
   EXPECT_EQ(st.name(), "a");
@@ -78,8 +77,7 @@
 TEST_F(StructMemberTest, IsValid_Null_Decoration) {
   type::I32Type i32;
   StructMemberDecorationList decorations;
-  decorations.emplace_back(
-      std::make_unique<StructMemberOffsetDecoration>(4, Source{}));
+  decorations.emplace_back(create<StructMemberOffsetDecoration>(4, Source{}));
   decorations.push_back(nullptr);
 
   StructMember st{"a", &i32, std::move(decorations)};
@@ -89,8 +87,7 @@
 TEST_F(StructMemberTest, ToStr) {
   type::I32Type i32;
   StructMemberDecorationList decorations;
-  decorations.emplace_back(
-      std::make_unique<StructMemberOffsetDecoration>(4, Source{}));
+  decorations.emplace_back(create<StructMemberOffsetDecoration>(4, Source{}));
 
   StructMember st{"a", &i32, std::move(decorations)};
   std::ostringstream out;
diff --git a/src/ast/struct_test.cc b/src/ast/struct_test.cc
index 540a4a8..e61a7de 100644
--- a/src/ast/struct_test.cc
+++ b/src/ast/struct_test.cc
@@ -33,7 +33,7 @@
   type::I32Type i32;
   StructMemberList members;
   members.push_back(
-      std::make_unique<StructMember>("a", &i32, StructMemberDecorationList()));
+      create<StructMember>("a", &i32, StructMemberDecorationList()));
 
   Struct s{std::move(members)};
   EXPECT_EQ(s.members().size(), 1u);
@@ -49,10 +49,10 @@
 
   StructMemberList members;
   members.push_back(
-      std::make_unique<StructMember>("a", &i32, StructMemberDecorationList()));
+      create<StructMember>("a", &i32, StructMemberDecorationList()));
 
   StructDecorationList decos;
-  decos.push_back(std::make_unique<StructBlockDecoration>(Source{}));
+  decos.push_back(create<StructBlockDecoration>(Source{}));
 
   Struct s{std::move(decos), std::move(members)};
   EXPECT_EQ(s.members().size(), 1u);
@@ -69,10 +69,10 @@
 
   StructMemberList members;
   members.emplace_back(
-      std::make_unique<StructMember>("a", &i32, StructMemberDecorationList()));
+      create<StructMember>("a", &i32, StructMemberDecorationList()));
 
   StructDecorationList decos;
-  decos.push_back(std::make_unique<StructBlockDecoration>(Source{}));
+  decos.push_back(create<StructBlockDecoration>(Source{}));
 
   Struct s{
       Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 8}}},
@@ -96,7 +96,7 @@
 
   StructMemberList members;
   members.push_back(
-      std::make_unique<StructMember>("a", &i32, StructMemberDecorationList()));
+      create<StructMember>("a", &i32, StructMemberDecorationList()));
   members.push_back(nullptr);
 
   Struct s{std::move(members)};
@@ -108,7 +108,7 @@
 
   StructMemberList members;
   members.push_back(
-      std::make_unique<StructMember>("", &i32, StructMemberDecorationList()));
+      create<StructMember>("", &i32, StructMemberDecorationList()));
 
   Struct s{std::move(members)};
   EXPECT_FALSE(s.IsValid());
@@ -119,10 +119,10 @@
 
   StructMemberList members;
   members.emplace_back(
-      std::make_unique<StructMember>("a", &i32, StructMemberDecorationList()));
+      create<StructMember>("a", &i32, StructMemberDecorationList()));
 
   StructDecorationList decos;
-  decos.push_back(std::make_unique<StructBlockDecoration>(Source{}));
+  decos.push_back(create<StructBlockDecoration>(Source{}));
 
   Struct s{std::move(decos), std::move(members)};
 
diff --git a/src/ast/switch_statement_test.cc b/src/ast/switch_statement_test.cc
index 4b78e79..8bf21b7 100644
--- a/src/ast/switch_statement_test.cc
+++ b/src/ast/switch_statement_test.cc
@@ -32,12 +32,12 @@
   ast::type::I32Type i32;
 
   CaseSelectorList lit;
-  lit.push_back(std::make_unique<SintLiteral>(&i32, 1));
+  lit.push_back(create<SintLiteral>(&i32, 1));
 
-  auto ident = std::make_unique<IdentifierExpression>("ident");
+  auto ident = create<IdentifierExpression>("ident");
   CaseStatementList body;
-  body.push_back(std::make_unique<CaseStatement>(
-      std::move(lit), std::make_unique<ast::BlockStatement>()));
+  body.push_back(
+      create<CaseStatement>(std::move(lit), create<ast::BlockStatement>()));
 
   auto* ident_ptr = ident.get();
   auto* case_ptr = body[0].get();
@@ -49,7 +49,7 @@
 }
 
 TEST_F(SwitchStatementTest, Creation_WithSource) {
-  auto ident = std::make_unique<IdentifierExpression>("ident");
+  auto ident = create<IdentifierExpression>("ident");
 
   SwitchStatement stmt(Source{Source::Location{20, 2}}, std::move(ident),
                        CaseStatementList());
@@ -67,12 +67,12 @@
   ast::type::I32Type i32;
 
   CaseSelectorList lit;
-  lit.push_back(std::make_unique<SintLiteral>(&i32, 2));
+  lit.push_back(create<SintLiteral>(&i32, 2));
 
-  auto ident = std::make_unique<IdentifierExpression>("ident");
+  auto ident = create<IdentifierExpression>("ident");
   CaseStatementList body;
-  body.push_back(std::make_unique<CaseStatement>(
-      std::move(lit), std::make_unique<ast::BlockStatement>()));
+  body.push_back(
+      create<CaseStatement>(std::move(lit), create<ast::BlockStatement>()));
 
   SwitchStatement stmt(std::move(ident), std::move(body));
   EXPECT_TRUE(stmt.IsValid());
@@ -82,11 +82,11 @@
   ast::type::I32Type i32;
 
   CaseSelectorList lit;
-  lit.push_back(std::make_unique<SintLiteral>(&i32, 2));
+  lit.push_back(create<SintLiteral>(&i32, 2));
 
   CaseStatementList body;
-  body.push_back(std::make_unique<CaseStatement>(
-      std::move(lit), std::make_unique<ast::BlockStatement>()));
+  body.push_back(
+      create<CaseStatement>(std::move(lit), create<ast::BlockStatement>()));
 
   SwitchStatement stmt;
   stmt.set_body(std::move(body));
@@ -97,12 +97,12 @@
   ast::type::I32Type i32;
 
   CaseSelectorList lit;
-  lit.push_back(std::make_unique<SintLiteral>(&i32, 2));
+  lit.push_back(create<SintLiteral>(&i32, 2));
 
-  auto ident = std::make_unique<IdentifierExpression>("");
+  auto ident = create<IdentifierExpression>("");
   CaseStatementList body;
-  body.push_back(std::make_unique<CaseStatement>(
-      std::move(lit), std::make_unique<ast::BlockStatement>()));
+  body.push_back(
+      create<CaseStatement>(std::move(lit), create<ast::BlockStatement>()));
 
   SwitchStatement stmt(std::move(ident), std::move(body));
   EXPECT_FALSE(stmt.IsValid());
@@ -112,12 +112,12 @@
   ast::type::I32Type i32;
 
   CaseSelectorList lit;
-  lit.push_back(std::make_unique<SintLiteral>(&i32, 2));
+  lit.push_back(create<SintLiteral>(&i32, 2));
 
-  auto ident = std::make_unique<IdentifierExpression>("ident");
+  auto ident = create<IdentifierExpression>("ident");
   CaseStatementList body;
-  body.push_back(std::make_unique<CaseStatement>(
-      std::move(lit), std::make_unique<ast::BlockStatement>()));
+  body.push_back(
+      create<CaseStatement>(std::move(lit), create<ast::BlockStatement>()));
   body.push_back(nullptr);
 
   SwitchStatement stmt(std::move(ident), std::move(body));
@@ -125,21 +125,21 @@
 }
 
 TEST_F(SwitchStatementTest, IsValid_Invalid_BodyStatement) {
-  auto ident = std::make_unique<IdentifierExpression>("ident");
+  auto ident = create<IdentifierExpression>("ident");
 
-  auto case_body = std::make_unique<ast::BlockStatement>();
+  auto case_body = create<ast::BlockStatement>();
   case_body->append(nullptr);
 
   CaseStatementList body;
-  body.push_back(std::make_unique<CaseStatement>(CaseSelectorList{},
-                                                 std::move(case_body)));
+  body.push_back(
+      create<CaseStatement>(CaseSelectorList{}, std::move(case_body)));
 
   SwitchStatement stmt(std::move(ident), std::move(body));
   EXPECT_FALSE(stmt.IsValid());
 }
 
 TEST_F(SwitchStatementTest, ToStr_Empty) {
-  auto ident = std::make_unique<IdentifierExpression>("ident");
+  auto ident = create<IdentifierExpression>("ident");
 
   SwitchStatement stmt(std::move(ident), {});
   std::ostringstream out;
@@ -156,12 +156,12 @@
   ast::type::I32Type i32;
 
   CaseSelectorList lit;
-  lit.push_back(std::make_unique<SintLiteral>(&i32, 2));
+  lit.push_back(create<SintLiteral>(&i32, 2));
 
-  auto ident = std::make_unique<IdentifierExpression>("ident");
+  auto ident = create<IdentifierExpression>("ident");
   CaseStatementList body;
-  body.push_back(std::make_unique<CaseStatement>(
-      std::move(lit), std::make_unique<ast::BlockStatement>()));
+  body.push_back(
+      create<CaseStatement>(std::move(lit), create<ast::BlockStatement>()));
 
   SwitchStatement stmt(std::move(ident), std::move(body));
   std::ostringstream out;
diff --git a/src/ast/test_helper.h b/src/ast/test_helper.h
index a00623f..596d0ce 100644
--- a/src/ast/test_helper.h
+++ b/src/ast/test_helper.h
@@ -15,6 +15,9 @@
 #ifndef SRC_AST_TEST_HELPER_H_
 #define SRC_AST_TEST_HELPER_H_
 
+#include <memory>
+#include <utility>
+
 #include "gtest/gtest.h"
 
 namespace tint {
@@ -26,6 +29,13 @@
  public:
   TestHelperBase() {}
   ~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)...);
+  }
 };
 using TestHelper = TestHelperBase<testing::Test>;
 
diff --git a/src/ast/type_constructor_expression_test.cc b/src/ast/type_constructor_expression_test.cc
index c3df0fb..8a30a62 100644
--- a/src/ast/type_constructor_expression_test.cc
+++ b/src/ast/type_constructor_expression_test.cc
@@ -32,7 +32,7 @@
 TEST_F(TypeConstructorExpressionTest, Creation) {
   type::F32Type f32;
   ExpressionList expr;
-  expr.push_back(std::make_unique<IdentifierExpression>("expr"));
+  expr.push_back(create<IdentifierExpression>("expr"));
   auto* expr_ptr = expr[0].get();
 
   TypeConstructorExpression t(&f32, std::move(expr));
@@ -44,7 +44,7 @@
 TEST_F(TypeConstructorExpressionTest, Creation_WithSource) {
   type::F32Type f32;
   ExpressionList expr;
-  expr.push_back(std::make_unique<IdentifierExpression>("expr"));
+  expr.push_back(create<IdentifierExpression>("expr"));
 
   TypeConstructorExpression t(Source{Source::Location{20, 2}}, &f32,
                               std::move(expr));
@@ -61,7 +61,7 @@
 TEST_F(TypeConstructorExpressionTest, IsValid) {
   type::F32Type f32;
   ExpressionList expr;
-  expr.push_back(std::make_unique<IdentifierExpression>("expr"));
+  expr.push_back(create<IdentifierExpression>("expr"));
 
   TypeConstructorExpression t(&f32, std::move(expr));
   EXPECT_TRUE(t.IsValid());
@@ -77,7 +77,7 @@
 
 TEST_F(TypeConstructorExpressionTest, IsValid_NullType) {
   ExpressionList expr;
-  expr.push_back(std::make_unique<IdentifierExpression>("expr"));
+  expr.push_back(create<IdentifierExpression>("expr"));
 
   TypeConstructorExpression t;
   t.set_values(std::move(expr));
@@ -87,7 +87,7 @@
 TEST_F(TypeConstructorExpressionTest, IsValid_NullValue) {
   type::F32Type f32;
   ExpressionList expr;
-  expr.push_back(std::make_unique<IdentifierExpression>("expr"));
+  expr.push_back(create<IdentifierExpression>("expr"));
   expr.push_back(nullptr);
 
   TypeConstructorExpression t(&f32, std::move(expr));
@@ -97,7 +97,7 @@
 TEST_F(TypeConstructorExpressionTest, IsValid_InvalidValue) {
   type::F32Type f32;
   ExpressionList expr;
-  expr.push_back(std::make_unique<IdentifierExpression>(""));
+  expr.push_back(create<IdentifierExpression>(""));
 
   TypeConstructorExpression t(&f32, std::move(expr));
   EXPECT_FALSE(t.IsValid());
@@ -107,9 +107,9 @@
   type::F32Type f32;
   type::VectorType vec(&f32, 3);
   ExpressionList expr;
-  expr.push_back(std::make_unique<IdentifierExpression>("expr_1"));
-  expr.push_back(std::make_unique<IdentifierExpression>("expr_2"));
-  expr.push_back(std::make_unique<IdentifierExpression>("expr_3"));
+  expr.push_back(create<IdentifierExpression>("expr_1"));
+  expr.push_back(create<IdentifierExpression>("expr_2"));
+  expr.push_back(create<IdentifierExpression>("expr_3"));
 
   TypeConstructorExpression t(&vec, std::move(expr));
   std::ostringstream out;
diff --git a/src/ast/unary_op_expression_test.cc b/src/ast/unary_op_expression_test.cc
index b23fa61..4adc29d 100644
--- a/src/ast/unary_op_expression_test.cc
+++ b/src/ast/unary_op_expression_test.cc
@@ -26,7 +26,7 @@
 using UnaryOpExpressionTest = TestHelper;
 
 TEST_F(UnaryOpExpressionTest, Creation) {
-  auto ident = std::make_unique<IdentifierExpression>("ident");
+  auto ident = create<IdentifierExpression>("ident");
   auto* ident_ptr = ident.get();
 
   UnaryOpExpression u(UnaryOp::kNot, std::move(ident));
@@ -35,7 +35,7 @@
 }
 
 TEST_F(UnaryOpExpressionTest, Creation_WithSource) {
-  auto ident = std::make_unique<IdentifierExpression>("ident");
+  auto ident = create<IdentifierExpression>("ident");
   UnaryOpExpression u(Source{Source::Location{20, 2}}, UnaryOp::kNot,
                       std::move(ident));
   auto src = u.source();
@@ -49,7 +49,7 @@
 }
 
 TEST_F(UnaryOpExpressionTest, IsValid) {
-  auto ident = std::make_unique<IdentifierExpression>("ident");
+  auto ident = create<IdentifierExpression>("ident");
   UnaryOpExpression u(UnaryOp::kNot, std::move(ident));
   EXPECT_TRUE(u.IsValid());
 }
@@ -61,13 +61,13 @@
 }
 
 TEST_F(UnaryOpExpressionTest, IsValid_InvalidExpression) {
-  auto ident = std::make_unique<IdentifierExpression>("");
+  auto ident = create<IdentifierExpression>("");
   UnaryOpExpression u(UnaryOp::kNot, std::move(ident));
   EXPECT_FALSE(u.IsValid());
 }
 
 TEST_F(UnaryOpExpressionTest, ToStr) {
-  auto ident = std::make_unique<IdentifierExpression>("ident");
+  auto ident = create<IdentifierExpression>("ident");
   UnaryOpExpression u(UnaryOp::kNot, std::move(ident));
   std::ostringstream out;
   u.to_str(out, 2);
diff --git a/src/ast/variable_decl_statement_test.cc b/src/ast/variable_decl_statement_test.cc
index 7a104d0..b32e2c1 100644
--- a/src/ast/variable_decl_statement_test.cc
+++ b/src/ast/variable_decl_statement_test.cc
@@ -26,7 +26,7 @@
 
 TEST_F(VariableDeclStatementTest, Creation) {
   type::F32Type f32;
-  auto var = std::make_unique<Variable>("a", StorageClass::kNone, &f32);
+  auto var = create<Variable>("a", StorageClass::kNone, &f32);
   auto* var_ptr = var.get();
 
   VariableDeclStatement stmt(std::move(var));
@@ -35,7 +35,7 @@
 
 TEST_F(VariableDeclStatementTest, Creation_WithSource) {
   type::F32Type f32;
-  auto var = std::make_unique<Variable>("a", StorageClass::kNone, &f32);
+  auto var = create<Variable>("a", StorageClass::kNone, &f32);
 
   VariableDeclStatement stmt(Source{Source::Location{20, 2}}, std::move(var));
   auto src = stmt.source();
@@ -50,14 +50,14 @@
 
 TEST_F(VariableDeclStatementTest, IsValid) {
   type::F32Type f32;
-  auto var = std::make_unique<Variable>("a", StorageClass::kNone, &f32);
+  auto var = create<Variable>("a", StorageClass::kNone, &f32);
   VariableDeclStatement stmt(std::move(var));
   EXPECT_TRUE(stmt.IsValid());
 }
 
 TEST_F(VariableDeclStatementTest, IsValid_InvalidVariable) {
   type::F32Type f32;
-  auto var = std::make_unique<Variable>("", StorageClass::kNone, &f32);
+  auto var = create<Variable>("", StorageClass::kNone, &f32);
   VariableDeclStatement stmt(std::move(var));
   EXPECT_FALSE(stmt.IsValid());
 }
@@ -69,7 +69,7 @@
 
 TEST_F(VariableDeclStatementTest, ToStr) {
   type::F32Type f32;
-  auto var = std::make_unique<Variable>("a", StorageClass::kNone, &f32);
+  auto var = create<Variable>("a", StorageClass::kNone, &f32);
 
   VariableDeclStatement stmt(Source{Source::Location{20, 2}}, std::move(var));
   std::ostringstream out;
diff --git a/src/ast/variable_test.cc b/src/ast/variable_test.cc
index 4898d6b..0643b84 100644
--- a/src/ast/variable_test.cc
+++ b/src/ast/variable_test.cc
@@ -80,7 +80,7 @@
 TEST_F(VariableTest, IsValid_WithConstructor) {
   type::I32Type t;
   Variable v{"my_var", StorageClass::kNone, &t};
-  v.set_constructor(std::make_unique<IdentifierExpression>("ident"));
+  v.set_constructor(create<IdentifierExpression>("ident"));
   EXPECT_TRUE(v.IsValid());
 }
 
@@ -103,7 +103,7 @@
 TEST_F(VariableTest, IsValid_InvalidConstructor) {
   type::I32Type t;
   Variable v{"my_var", StorageClass::kNone, &t};
-  v.set_constructor(std::make_unique<IdentifierExpression>(""));
+  v.set_constructor(create<IdentifierExpression>(""));
   EXPECT_FALSE(v.IsValid());
 }