writer/wgsl 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: I69cb8eb0a4943831fc9233e4dcce2ee65b682738
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/32674
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/writer/wgsl/generator_impl_alias_type_test.cc b/src/writer/wgsl/generator_impl_alias_type_test.cc
index 346783b..bf47d1f 100644
--- a/src/writer/wgsl/generator_impl_alias_type_test.cc
+++ b/src/writer/wgsl/generator_impl_alias_type_test.cc
@@ -44,16 +44,14 @@
   ast::type::F32Type f32;
 
   ast::StructMemberList members;
-  members.push_back(std::make_unique<ast::StructMember>(
-      "a", &f32, ast::StructMemberDecorationList{}));
+  members.push_back(
+      create<ast::StructMember>("a", &f32, ast::StructMemberDecorationList{}));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(
-      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
-  members.push_back(
-      std::make_unique<ast::StructMember>("b", &i32, std::move(b_deco)));
+  b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
+  members.push_back(create<ast::StructMember>("b", &i32, std::move(b_deco)));
 
-  auto str = std::make_unique<ast::Struct>();
+  auto str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("A", std::move(str));
@@ -75,16 +73,14 @@
   ast::type::F32Type f32;
 
   ast::StructMemberList members;
-  members.push_back(std::make_unique<ast::StructMember>(
-      "a", &f32, ast::StructMemberDecorationList{}));
+  members.push_back(
+      create<ast::StructMember>("a", &f32, ast::StructMemberDecorationList{}));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(
-      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
-  members.push_back(
-      std::make_unique<ast::StructMember>("b", &i32, std::move(b_deco)));
+  b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
+  members.push_back(create<ast::StructMember>("b", &i32, std::move(b_deco)));
 
-  auto str = std::make_unique<ast::Struct>();
+  auto str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("A", std::move(str));
diff --git a/src/writer/wgsl/generator_impl_array_accessor_test.cc b/src/writer/wgsl/generator_impl_array_accessor_test.cc
index ca34234..1096b04 100644
--- a/src/writer/wgsl/generator_impl_array_accessor_test.cc
+++ b/src/writer/wgsl/generator_impl_array_accessor_test.cc
@@ -32,9 +32,9 @@
 
 TEST_F(WgslGeneratorImplTest, EmitExpression_ArrayAccessor) {
   ast::type::I32Type i32;
-  auto lit = std::make_unique<ast::SintLiteral>(&i32, 5);
-  auto idx = std::make_unique<ast::ScalarConstructorExpression>(std::move(lit));
-  auto ary = std::make_unique<ast::IdentifierExpression>("ary");
+  auto lit = create<ast::SintLiteral>(&i32, 5);
+  auto idx = create<ast::ScalarConstructorExpression>(std::move(lit));
+  auto ary = create<ast::IdentifierExpression>("ary");
 
   ast::ArrayAccessorExpression expr(std::move(ary), std::move(idx));
 
@@ -43,8 +43,8 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitArrayAccessor) {
-  auto ary = std::make_unique<ast::IdentifierExpression>("ary");
-  auto idx = std::make_unique<ast::IdentifierExpression>("idx");
+  auto ary = create<ast::IdentifierExpression>("ary");
+  auto idx = create<ast::IdentifierExpression>("idx");
 
   ast::ArrayAccessorExpression expr(std::move(ary), std::move(idx));
 
diff --git a/src/writer/wgsl/generator_impl_assign_test.cc b/src/writer/wgsl/generator_impl_assign_test.cc
index ae2e6e8..4204437 100644
--- a/src/writer/wgsl/generator_impl_assign_test.cc
+++ b/src/writer/wgsl/generator_impl_assign_test.cc
@@ -29,8 +29,8 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, Emit_Assign) {
-  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");
   ast::AssignmentStatement assign(std::move(lhs), std::move(rhs));
 
   gen.increment_indent();
diff --git a/src/writer/wgsl/generator_impl_binary_test.cc b/src/writer/wgsl/generator_impl_binary_test.cc
index 963e1c1..c1a35c7 100644
--- a/src/writer/wgsl/generator_impl_binary_test.cc
+++ b/src/writer/wgsl/generator_impl_binary_test.cc
@@ -37,8 +37,8 @@
 TEST_P(WgslBinaryTest, Emit) {
   auto params = GetParam();
 
-  auto left = std::make_unique<ast::IdentifierExpression>("left");
-  auto right = std::make_unique<ast::IdentifierExpression>("right");
+  auto left = create<ast::IdentifierExpression>("left");
+  auto right = create<ast::IdentifierExpression>("right");
 
   ast::BinaryExpression expr(params.op, std::move(left), std::move(right));
 
diff --git a/src/writer/wgsl/generator_impl_bitcast_test.cc b/src/writer/wgsl/generator_impl_bitcast_test.cc
index ee0e204..793bd20 100644
--- a/src/writer/wgsl/generator_impl_bitcast_test.cc
+++ b/src/writer/wgsl/generator_impl_bitcast_test.cc
@@ -30,7 +30,7 @@
 
 TEST_F(WgslGeneratorImplTest, EmitExpression_Bitcast) {
   ast::type::F32Type f32;
-  auto id = std::make_unique<ast::IdentifierExpression>("id");
+  auto id = create<ast::IdentifierExpression>("id");
   ast::BitcastExpression bitcast(&f32, std::move(id));
 
   ASSERT_TRUE(gen.EmitExpression(&bitcast)) << gen.error();
diff --git a/src/writer/wgsl/generator_impl_block_test.cc b/src/writer/wgsl/generator_impl_block_test.cc
index 80c88bb..85e00aa 100644
--- a/src/writer/wgsl/generator_impl_block_test.cc
+++ b/src/writer/wgsl/generator_impl_block_test.cc
@@ -29,7 +29,7 @@
 
 TEST_F(WgslGeneratorImplTest, Emit_Block) {
   ast::BlockStatement b;
-  b.append(std::make_unique<ast::DiscardStatement>());
+  b.append(create<ast::DiscardStatement>());
 
   gen.increment_indent();
 
@@ -42,7 +42,7 @@
 
 TEST_F(WgslGeneratorImplTest, Emit_Block_WithoutNewline) {
   ast::BlockStatement b;
-  b.append(std::make_unique<ast::DiscardStatement>());
+  b.append(create<ast::DiscardStatement>());
 
   gen.increment_indent();
 
diff --git a/src/writer/wgsl/generator_impl_call_test.cc b/src/writer/wgsl/generator_impl_call_test.cc
index b04c1e0..3c3f221 100644
--- a/src/writer/wgsl/generator_impl_call_test.cc
+++ b/src/writer/wgsl/generator_impl_call_test.cc
@@ -29,7 +29,7 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, EmitExpression_Call_WithoutParams) {
-  auto id = std::make_unique<ast::IdentifierExpression>("my_func");
+  auto id = create<ast::IdentifierExpression>("my_func");
   ast::CallExpression call(std::move(id), {});
 
   ASSERT_TRUE(gen.EmitExpression(&call)) << gen.error();
@@ -37,10 +37,10 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitExpression_Call_WithParams) {
-  auto id = std::make_unique<ast::IdentifierExpression>("my_func");
+  auto id = create<ast::IdentifierExpression>("my_func");
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::IdentifierExpression>("param1"));
-  params.push_back(std::make_unique<ast::IdentifierExpression>("param2"));
+  params.push_back(create<ast::IdentifierExpression>("param1"));
+  params.push_back(create<ast::IdentifierExpression>("param2"));
   ast::CallExpression call(std::move(id), std::move(params));
 
   ASSERT_TRUE(gen.EmitExpression(&call)) << gen.error();
@@ -48,13 +48,13 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitStatement_Call) {
-  auto id = std::make_unique<ast::IdentifierExpression>("my_func");
+  auto id = create<ast::IdentifierExpression>("my_func");
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::IdentifierExpression>("param1"));
-  params.push_back(std::make_unique<ast::IdentifierExpression>("param2"));
+  params.push_back(create<ast::IdentifierExpression>("param1"));
+  params.push_back(create<ast::IdentifierExpression>("param2"));
 
   ast::CallStatement call(
-      std::make_unique<ast::CallExpression>(std::move(id), std::move(params)));
+      create<ast::CallExpression>(std::move(id), std::move(params)));
 
   gen.increment_indent();
   ASSERT_TRUE(gen.EmitStatement(&call)) << gen.error();
diff --git a/src/writer/wgsl/generator_impl_case_test.cc b/src/writer/wgsl/generator_impl_case_test.cc
index 0f6dbb6..3830b51 100644
--- a/src/writer/wgsl/generator_impl_case_test.cc
+++ b/src/writer/wgsl/generator_impl_case_test.cc
@@ -33,11 +33,11 @@
 TEST_F(WgslGeneratorImplTest, Emit_Case) {
   ast::type::I32Type i32;
 
-  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::CaseSelectorList lit;
-  lit.push_back(std::make_unique<ast::SintLiteral>(&i32, 5));
+  lit.push_back(create<ast::SintLiteral>(&i32, 5));
   ast::CaseStatement c(std::move(lit), std::move(body));
 
   gen.increment_indent();
@@ -52,12 +52,12 @@
 TEST_F(WgslGeneratorImplTest, Emit_Case_MultipleSelectors) {
   ast::type::I32Type i32;
 
-  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::CaseSelectorList lit;
-  lit.push_back(std::make_unique<ast::SintLiteral>(&i32, 5));
-  lit.push_back(std::make_unique<ast::SintLiteral>(&i32, 6));
+  lit.push_back(create<ast::SintLiteral>(&i32, 5));
+  lit.push_back(create<ast::SintLiteral>(&i32, 6));
   ast::CaseStatement c(std::move(lit), std::move(body));
 
   gen.increment_indent();
@@ -72,8 +72,8 @@
 TEST_F(WgslGeneratorImplTest, Emit_Case_Default) {
   ast::CaseStatement c;
 
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<ast::BreakStatement>());
+  auto body = create<ast::BlockStatement>();
+  body->append(create<ast::BreakStatement>());
   c.set_body(std::move(body));
 
   gen.increment_indent();
diff --git a/src/writer/wgsl/generator_impl_cast_test.cc b/src/writer/wgsl/generator_impl_cast_test.cc
index b69043c..5d64f46 100644
--- a/src/writer/wgsl/generator_impl_cast_test.cc
+++ b/src/writer/wgsl/generator_impl_cast_test.cc
@@ -32,7 +32,7 @@
   ast::type::F32Type f32;
 
   ast::ExpressionList params;
-  params.push_back(std::make_unique<ast::IdentifierExpression>("id"));
+  params.push_back(create<ast::IdentifierExpression>("id"));
 
   ast::TypeConstructorExpression cast(&f32, std::move(params));
 
diff --git a/src/writer/wgsl/generator_impl_constructor_test.cc b/src/writer/wgsl/generator_impl_constructor_test.cc
index b7620ce..7c3c474 100644
--- a/src/writer/wgsl/generator_impl_constructor_test.cc
+++ b/src/writer/wgsl/generator_impl_constructor_test.cc
@@ -37,7 +37,7 @@
 
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Bool) {
   ast::type::BoolType bool_type;
-  auto lit = std::make_unique<ast::BoolLiteral>(&bool_type, false);
+  auto lit = create<ast::BoolLiteral>(&bool_type, false);
   ast::ScalarConstructorExpression expr(std::move(lit));
 
   ASSERT_TRUE(gen.EmitConstructor(&expr)) << gen.error();
@@ -46,7 +46,7 @@
 
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Int) {
   ast::type::I32Type i32;
-  auto lit = std::make_unique<ast::SintLiteral>(&i32, -12345);
+  auto lit = create<ast::SintLiteral>(&i32, -12345);
   ast::ScalarConstructorExpression expr(std::move(lit));
 
   ASSERT_TRUE(gen.EmitConstructor(&expr)) << gen.error();
@@ -55,7 +55,7 @@
 
 TEST_F(WgslGeneratorImplTest, EmitConstructor_UInt) {
   ast::type::U32Type u32;
-  auto lit = std::make_unique<ast::UintLiteral>(&u32, 56779);
+  auto lit = create<ast::UintLiteral>(&u32, 56779);
   ast::ScalarConstructorExpression expr(std::move(lit));
 
   ASSERT_TRUE(gen.EmitConstructor(&expr)) << gen.error();
@@ -65,8 +65,7 @@
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Float) {
   ast::type::F32Type f32;
   // Use a number close to 1<<30 but whose decimal representation ends in 0.
-  auto lit = std::make_unique<ast::FloatLiteral>(
-      &f32, static_cast<float>((1 << 30) - 4));
+  auto lit = create<ast::FloatLiteral>(&f32, static_cast<float>((1 << 30) - 4));
   ast::ScalarConstructorExpression expr(std::move(lit));
 
   ASSERT_TRUE(gen.EmitConstructor(&expr)) << gen.error();
@@ -76,10 +75,9 @@
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Float) {
   ast::type::F32Type f32;
 
-  auto lit = std::make_unique<ast::FloatLiteral>(&f32, -1.2e-5);
+  auto lit = create<ast::FloatLiteral>(&f32, -1.2e-5);
   ast::ExpressionList values;
-  values.push_back(
-      std::make_unique<ast::ScalarConstructorExpression>(std::move(lit)));
+  values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit)));
 
   ast::TypeConstructorExpression expr(&f32, std::move(values));
 
@@ -90,10 +88,9 @@
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Bool) {
   ast::type::BoolType b;
 
-  auto lit = std::make_unique<ast::BoolLiteral>(&b, true);
+  auto lit = create<ast::BoolLiteral>(&b, true);
   ast::ExpressionList values;
-  values.push_back(
-      std::make_unique<ast::ScalarConstructorExpression>(std::move(lit)));
+  values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit)));
 
   ast::TypeConstructorExpression expr(&b, std::move(values));
 
@@ -104,10 +101,9 @@
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Int) {
   ast::type::I32Type i32;
 
-  auto lit = std::make_unique<ast::SintLiteral>(&i32, -12345);
+  auto lit = create<ast::SintLiteral>(&i32, -12345);
   ast::ExpressionList values;
-  values.push_back(
-      std::make_unique<ast::ScalarConstructorExpression>(std::move(lit)));
+  values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit)));
 
   ast::TypeConstructorExpression expr(&i32, std::move(values));
 
@@ -118,10 +114,9 @@
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Uint) {
   ast::type::U32Type u32;
 
-  auto lit = std::make_unique<ast::UintLiteral>(&u32, 12345);
+  auto lit = create<ast::UintLiteral>(&u32, 12345);
   ast::ExpressionList values;
-  values.push_back(
-      std::make_unique<ast::ScalarConstructorExpression>(std::move(lit)));
+  values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit)));
 
   ast::TypeConstructorExpression expr(&u32, std::move(values));
 
@@ -133,16 +128,13 @@
   ast::type::F32Type f32;
   ast::type::VectorType vec(&f32, 3);
 
-  auto lit1 = std::make_unique<ast::FloatLiteral>(&f32, 1.f);
-  auto lit2 = std::make_unique<ast::FloatLiteral>(&f32, 2.f);
-  auto lit3 = std::make_unique<ast::FloatLiteral>(&f32, 3.f);
+  auto lit1 = create<ast::FloatLiteral>(&f32, 1.f);
+  auto lit2 = create<ast::FloatLiteral>(&f32, 2.f);
+  auto lit3 = create<ast::FloatLiteral>(&f32, 3.f);
   ast::ExpressionList values;
-  values.push_back(
-      std::make_unique<ast::ScalarConstructorExpression>(std::move(lit1)));
-  values.push_back(
-      std::make_unique<ast::ScalarConstructorExpression>(std::move(lit2)));
-  values.push_back(
-      std::make_unique<ast::ScalarConstructorExpression>(std::move(lit3)));
+  values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit1)));
+  values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit2)));
+  values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit3)));
 
   ast::TypeConstructorExpression expr(&vec, std::move(values));
 
@@ -159,19 +151,17 @@
   ast::ExpressionList mat_values;
 
   for (size_t i = 0; i < 3; i++) {
-    auto lit1 = std::make_unique<ast::FloatLiteral>(
-        &f32, static_cast<float>(1 + (i * 2)));
-    auto lit2 = std::make_unique<ast::FloatLiteral>(
-        &f32, static_cast<float>(2 + (i * 2)));
+    auto lit1 =
+        create<ast::FloatLiteral>(&f32, static_cast<float>(1 + (i * 2)));
+    auto lit2 =
+        create<ast::FloatLiteral>(&f32, static_cast<float>(2 + (i * 2)));
 
     ast::ExpressionList values;
-    values.push_back(
-        std::make_unique<ast::ScalarConstructorExpression>(std::move(lit1)));
-    values.push_back(
-        std::make_unique<ast::ScalarConstructorExpression>(std::move(lit2)));
+    values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit1)));
+    values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit2)));
 
-    mat_values.push_back(std::make_unique<ast::TypeConstructorExpression>(
-        &vec, std::move(values)));
+    mat_values.push_back(
+        create<ast::TypeConstructorExpression>(&vec, std::move(values)));
   }
 
   ast::TypeConstructorExpression expr(&mat, std::move(mat_values));
@@ -191,23 +181,20 @@
   ast::ExpressionList ary_values;
 
   for (size_t i = 0; i < 3; i++) {
-    auto lit1 = std::make_unique<ast::FloatLiteral>(
-        &f32, static_cast<float>(1 + (i * 3)));
-    auto lit2 = std::make_unique<ast::FloatLiteral>(
-        &f32, static_cast<float>(2 + (i * 3)));
-    auto lit3 = std::make_unique<ast::FloatLiteral>(
-        &f32, static_cast<float>(3 + (i * 3)));
+    auto lit1 =
+        create<ast::FloatLiteral>(&f32, static_cast<float>(1 + (i * 3)));
+    auto lit2 =
+        create<ast::FloatLiteral>(&f32, static_cast<float>(2 + (i * 3)));
+    auto lit3 =
+        create<ast::FloatLiteral>(&f32, static_cast<float>(3 + (i * 3)));
 
     ast::ExpressionList values;
-    values.push_back(
-        std::make_unique<ast::ScalarConstructorExpression>(std::move(lit1)));
-    values.push_back(
-        std::make_unique<ast::ScalarConstructorExpression>(std::move(lit2)));
-    values.push_back(
-        std::make_unique<ast::ScalarConstructorExpression>(std::move(lit3)));
+    values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit1)));
+    values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit2)));
+    values.push_back(create<ast::ScalarConstructorExpression>(std::move(lit3)));
 
-    ary_values.push_back(std::make_unique<ast::TypeConstructorExpression>(
-        &vec, std::move(values)));
+    ary_values.push_back(
+        create<ast::TypeConstructorExpression>(&vec, std::move(values)));
   }
 
   ast::TypeConstructorExpression expr(&ary, std::move(ary_values));
diff --git a/src/writer/wgsl/generator_impl_function_test.cc b/src/writer/wgsl/generator_impl_function_test.cc
index 08f77f2..85dac8e 100644
--- a/src/writer/wgsl/generator_impl_function_test.cc
+++ b/src/writer/wgsl/generator_impl_function_test.cc
@@ -43,9 +43,9 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, Emit_Function) {
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<ast::DiscardStatement>());
-  body->append(std::make_unique<ast::ReturnStatement>());
+  auto body = create<ast::BlockStatement>();
+  body->append(create<ast::DiscardStatement>());
+  body->append(create<ast::ReturnStatement>());
 
   ast::type::VoidType void_type;
   ast::Function func("my_func", {}, &void_type);
@@ -62,17 +62,15 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_Function_WithParams) {
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<ast::DiscardStatement>());
-  body->append(std::make_unique<ast::ReturnStatement>());
+  auto body = create<ast::BlockStatement>();
+  body->append(create<ast::DiscardStatement>());
+  body->append(create<ast::ReturnStatement>());
 
   ast::type::F32Type f32;
   ast::type::I32Type i32;
   ast::VariableList params;
-  params.push_back(
-      std::make_unique<ast::Variable>("a", ast::StorageClass::kNone, &f32));
-  params.push_back(
-      std::make_unique<ast::Variable>("b", ast::StorageClass::kNone, &i32));
+  params.push_back(create<ast::Variable>("a", ast::StorageClass::kNone, &f32));
+  params.push_back(create<ast::Variable>("b", ast::StorageClass::kNone, &i32));
 
   ast::type::VoidType void_type;
   ast::Function func("my_func", std::move(params), &void_type);
@@ -89,14 +87,13 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_Function_WithDecoration_WorkgroupSize) {
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<ast::DiscardStatement>());
-  body->append(std::make_unique<ast::ReturnStatement>());
+  auto body = create<ast::BlockStatement>();
+  body->append(create<ast::DiscardStatement>());
+  body->append(create<ast::ReturnStatement>());
 
   ast::type::VoidType void_type;
   ast::Function func("my_func", {}, &void_type);
-  func.add_decoration(
-      std::make_unique<ast::WorkgroupDecoration>(2u, 4u, 6u, Source{}));
+  func.add_decoration(create<ast::WorkgroupDecoration>(2u, 4u, 6u, Source{}));
   func.set_body(std::move(body));
 
   gen.increment_indent();
@@ -111,14 +108,14 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_Function_WithDecoration_Stage) {
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<ast::DiscardStatement>());
-  body->append(std::make_unique<ast::ReturnStatement>());
+  auto body = create<ast::BlockStatement>();
+  body->append(create<ast::DiscardStatement>());
+  body->append(create<ast::ReturnStatement>());
 
   ast::type::VoidType void_type;
   ast::Function func("my_func", {}, &void_type);
-  func.add_decoration(std::make_unique<ast::StageDecoration>(
-      ast::PipelineStage::kFragment, Source{}));
+  func.add_decoration(
+      create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
   func.set_body(std::move(body));
 
   gen.increment_indent();
@@ -133,16 +130,15 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_Function_WithDecoration_Multiple) {
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<ast::DiscardStatement>());
-  body->append(std::make_unique<ast::ReturnStatement>());
+  auto body = create<ast::BlockStatement>();
+  body->append(create<ast::DiscardStatement>());
+  body->append(create<ast::ReturnStatement>());
 
   ast::type::VoidType void_type;
   ast::Function func("my_func", {}, &void_type);
-  func.add_decoration(std::make_unique<ast::StageDecoration>(
-      ast::PipelineStage::kFragment, Source{}));
   func.add_decoration(
-      std::make_unique<ast::WorkgroupDecoration>(2u, 4u, 6u, Source{}));
+      create<ast::StageDecoration>(ast::PipelineStage::kFragment, Source{}));
+  func.add_decoration(create<ast::WorkgroupDecoration>(2u, 4u, 6u, Source{}));
   func.set_body(std::move(body));
 
   gen.increment_indent();
@@ -180,27 +176,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);
@@ -210,20 +202,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));
@@ -231,20 +221,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/wgsl/generator_impl_if_test.cc b/src/writer/wgsl/generator_impl_if_test.cc
index f024782..465b711 100644
--- a/src/writer/wgsl/generator_impl_if_test.cc
+++ b/src/writer/wgsl/generator_impl_if_test.cc
@@ -28,9 +28,9 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, Emit_If) {
-  auto cond = std::make_unique<ast::IdentifierExpression>("cond");
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<ast::DiscardStatement>());
+  auto cond = create<ast::IdentifierExpression>("cond");
+  auto body = create<ast::BlockStatement>();
+  body->append(create<ast::DiscardStatement>());
 
   ast::IfStatement i(std::move(cond), std::move(body));
 
@@ -44,17 +44,17 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_IfWithElseIf) {
-  auto else_cond = std::make_unique<ast::IdentifierExpression>("else_cond");
-  auto else_body = std::make_unique<ast::BlockStatement>();
-  else_body->append(std::make_unique<ast::DiscardStatement>());
+  auto else_cond = create<ast::IdentifierExpression>("else_cond");
+  auto else_body = create<ast::BlockStatement>();
+  else_body->append(create<ast::DiscardStatement>());
 
   ast::ElseStatementList elses;
-  elses.push_back(std::make_unique<ast::ElseStatement>(std::move(else_cond),
-                                                       std::move(else_body)));
+  elses.push_back(
+      create<ast::ElseStatement>(std::move(else_cond), std::move(else_body)));
 
-  auto cond = std::make_unique<ast::IdentifierExpression>("cond");
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<ast::DiscardStatement>());
+  auto cond = create<ast::IdentifierExpression>("cond");
+  auto body = create<ast::BlockStatement>();
+  body->append(create<ast::DiscardStatement>());
 
   ast::IfStatement i(std::move(cond), std::move(body));
   i.set_else_statements(std::move(elses));
@@ -71,15 +71,15 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_IfWithElse) {
-  auto else_body = std::make_unique<ast::BlockStatement>();
-  else_body->append(std::make_unique<ast::DiscardStatement>());
+  auto else_body = create<ast::BlockStatement>();
+  else_body->append(create<ast::DiscardStatement>());
 
   ast::ElseStatementList elses;
-  elses.push_back(std::make_unique<ast::ElseStatement>(std::move(else_body)));
+  elses.push_back(create<ast::ElseStatement>(std::move(else_body)));
 
-  auto cond = std::make_unique<ast::IdentifierExpression>("cond");
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<ast::DiscardStatement>());
+  auto cond = create<ast::IdentifierExpression>("cond");
+  auto body = create<ast::BlockStatement>();
+  body->append(create<ast::DiscardStatement>());
 
   ast::IfStatement i(std::move(cond), std::move(body));
   i.set_else_statements(std::move(elses));
@@ -96,22 +96,22 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_IfWithMultiple) {
-  auto else_cond = std::make_unique<ast::IdentifierExpression>("else_cond");
+  auto else_cond = create<ast::IdentifierExpression>("else_cond");
 
-  auto else_body = std::make_unique<ast::BlockStatement>();
-  else_body->append(std::make_unique<ast::DiscardStatement>());
+  auto else_body = create<ast::BlockStatement>();
+  else_body->append(create<ast::DiscardStatement>());
 
-  auto else_body_2 = std::make_unique<ast::BlockStatement>();
-  else_body_2->append(std::make_unique<ast::DiscardStatement>());
+  auto else_body_2 = create<ast::BlockStatement>();
+  else_body_2->append(create<ast::DiscardStatement>());
 
   ast::ElseStatementList elses;
-  elses.push_back(std::make_unique<ast::ElseStatement>(std::move(else_cond),
-                                                       std::move(else_body)));
-  elses.push_back(std::make_unique<ast::ElseStatement>(std::move(else_body_2)));
+  elses.push_back(
+      create<ast::ElseStatement>(std::move(else_cond), std::move(else_body)));
+  elses.push_back(create<ast::ElseStatement>(std::move(else_body_2)));
 
-  auto cond = std::make_unique<ast::IdentifierExpression>("cond");
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<ast::DiscardStatement>());
+  auto cond = create<ast::IdentifierExpression>("cond");
+  auto body = create<ast::BlockStatement>();
+  body->append(create<ast::DiscardStatement>());
 
   ast::IfStatement i(std::move(cond), std::move(body));
   i.set_else_statements(std::move(elses));
diff --git a/src/writer/wgsl/generator_impl_loop_test.cc b/src/writer/wgsl/generator_impl_loop_test.cc
index 2371ac6..f411ad6 100644
--- a/src/writer/wgsl/generator_impl_loop_test.cc
+++ b/src/writer/wgsl/generator_impl_loop_test.cc
@@ -28,8 +28,8 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, Emit_Loop) {
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<ast::DiscardStatement>());
+  auto body = create<ast::BlockStatement>();
+  body->append(create<ast::DiscardStatement>());
   ast::LoopStatement l(std::move(body), {});
 
   gen.increment_indent();
@@ -42,11 +42,11 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_LoopWithContinuing) {
-  auto body = std::make_unique<ast::BlockStatement>();
-  body->append(std::make_unique<ast::DiscardStatement>());
+  auto body = create<ast::BlockStatement>();
+  body->append(create<ast::DiscardStatement>());
 
-  auto continuing = std::make_unique<ast::BlockStatement>();
-  continuing->append(std::make_unique<ast::DiscardStatement>());
+  auto continuing = create<ast::BlockStatement>();
+  continuing->append(create<ast::DiscardStatement>());
 
   ast::LoopStatement l(std::move(body), std::move(continuing));
 
diff --git a/src/writer/wgsl/generator_impl_member_accessor_test.cc b/src/writer/wgsl/generator_impl_member_accessor_test.cc
index 437bb0a..501f551 100644
--- a/src/writer/wgsl/generator_impl_member_accessor_test.cc
+++ b/src/writer/wgsl/generator_impl_member_accessor_test.cc
@@ -28,8 +28,8 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, EmitExpression_MemberAccessor) {
-  auto str = std::make_unique<ast::IdentifierExpression>("str");
-  auto mem = std::make_unique<ast::IdentifierExpression>("mem");
+  auto str = create<ast::IdentifierExpression>("str");
+  auto mem = create<ast::IdentifierExpression>("mem");
 
   ast::MemberAccessorExpression expr(std::move(str), std::move(mem));
 
diff --git a/src/writer/wgsl/generator_impl_return_test.cc b/src/writer/wgsl/generator_impl_return_test.cc
index 1d90af8..fdf2f63 100644
--- a/src/writer/wgsl/generator_impl_return_test.cc
+++ b/src/writer/wgsl/generator_impl_return_test.cc
@@ -38,7 +38,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_ReturnWithValue) {
-  auto expr = std::make_unique<ast::IdentifierExpression>("expr");
+  auto expr = create<ast::IdentifierExpression>("expr");
   ast::ReturnStatement r(std::move(expr));
 
   gen.increment_indent();
diff --git a/src/writer/wgsl/generator_impl_switch_test.cc b/src/writer/wgsl/generator_impl_switch_test.cc
index 8994ba8..491e2f0 100644
--- a/src/writer/wgsl/generator_impl_switch_test.cc
+++ b/src/writer/wgsl/generator_impl_switch_test.cc
@@ -32,26 +32,26 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, Emit_Switch) {
-  auto def = std::make_unique<ast::CaseStatement>();
-  auto def_body = std::make_unique<ast::BlockStatement>();
-  def_body->append(std::make_unique<ast::BreakStatement>());
+  auto def = create<ast::CaseStatement>();
+  auto def_body = create<ast::BlockStatement>();
+  def_body->append(create<ast::BreakStatement>());
   def->set_body(std::move(def_body));
 
   ast::type::I32Type i32;
   ast::CaseSelectorList case_val;
-  case_val.push_back(std::make_unique<ast::SintLiteral>(&i32, 5));
+  case_val.push_back(create<ast::SintLiteral>(&i32, 5));
 
-  auto case_body = std::make_unique<ast::BlockStatement>();
-  case_body->append(std::make_unique<ast::BreakStatement>());
+  auto case_body = create<ast::BlockStatement>();
+  case_body->append(create<ast::BreakStatement>());
 
-  auto case_stmt = std::make_unique<ast::CaseStatement>(std::move(case_val),
-                                                        std::move(case_body));
+  auto case_stmt =
+      create<ast::CaseStatement>(std::move(case_val), std::move(case_body));
 
   ast::CaseStatementList body;
   body.push_back(std::move(case_stmt));
   body.push_back(std::move(def));
 
-  auto cond = std::make_unique<ast::IdentifierExpression>("cond");
+  auto cond = create<ast::IdentifierExpression>("cond");
   ast::SwitchStatement s(std::move(cond), std::move(body));
 
   gen.increment_indent();
diff --git a/src/writer/wgsl/generator_impl_test.cc b/src/writer/wgsl/generator_impl_test.cc
index 2f6da33..20f72f4 100644
--- a/src/writer/wgsl/generator_impl_test.cc
+++ b/src/writer/wgsl/generator_impl_test.cc
@@ -32,8 +32,8 @@
 TEST_F(WgslGeneratorImplTest, Generate) {
   ast::type::VoidType void_type;
 
-  mod.AddFunction(std::make_unique<ast::Function>(
-      "my_func", ast::VariableList{}, &void_type));
+  mod.AddFunction(
+      create<ast::Function>("my_func", ast::VariableList{}, &void_type));
 
   ASSERT_TRUE(gen.Generate(mod)) << gen.error();
   EXPECT_EQ(gen.result(), R"(fn my_func() -> void {
diff --git a/src/writer/wgsl/generator_impl_type_test.cc b/src/writer/wgsl/generator_impl_type_test.cc
index aeaf721..5d0864b 100644
--- a/src/writer/wgsl/generator_impl_type_test.cc
+++ b/src/writer/wgsl/generator_impl_type_test.cc
@@ -64,7 +64,7 @@
 TEST_F(WgslGeneratorImplTest, EmitType_Array_Decoration) {
   ast::type::BoolType b;
   ast::ArrayDecorationList decos;
-  decos.push_back(std::make_unique<ast::StrideDecoration>(16u, Source{}));
+  decos.push_back(create<ast::StrideDecoration>(16u, Source{}));
 
   ast::type::ArrayType a(&b, 4);
   a.set_decorations(std::move(decos));
@@ -76,8 +76,8 @@
 TEST_F(WgslGeneratorImplTest, EmitType_Array_MultipleDecorations) {
   ast::type::BoolType b;
   ast::ArrayDecorationList decos;
-  decos.push_back(std::make_unique<ast::StrideDecoration>(16u, Source{}));
-  decos.push_back(std::make_unique<ast::StrideDecoration>(32u, Source{}));
+  decos.push_back(create<ast::StrideDecoration>(16u, Source{}));
+  decos.push_back(create<ast::StrideDecoration>(32u, Source{}));
 
   ast::type::ArrayType a(&b, 4);
   a.set_decorations(std::move(decos));
@@ -136,16 +136,14 @@
   ast::type::F32Type f32;
 
   ast::StructMemberList members;
-  members.push_back(std::make_unique<ast::StructMember>(
-      "a", &i32, ast::StructMemberDecorationList{}));
+  members.push_back(
+      create<ast::StructMember>("a", &i32, ast::StructMemberDecorationList{}));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(
-      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
-  members.push_back(
-      std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
+  b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
+  members.push_back(create<ast::StructMember>("b", &f32, std::move(b_deco)));
 
-  auto str = std::make_unique<ast::Struct>();
+  auto str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("S", std::move(str));
@@ -159,16 +157,14 @@
   ast::type::F32Type f32;
 
   ast::StructMemberList members;
-  members.push_back(std::make_unique<ast::StructMember>(
-      "a", &i32, ast::StructMemberDecorationList{}));
+  members.push_back(
+      create<ast::StructMember>("a", &i32, ast::StructMemberDecorationList{}));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(
-      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
-  members.push_back(
-      std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
+  b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
+  members.push_back(create<ast::StructMember>("b", &f32, std::move(b_deco)));
 
-  auto str = std::make_unique<ast::Struct>();
+  auto str = create<ast::Struct>();
   str->set_members(std::move(members));
 
   ast::type::StructType s("S", std::move(str));
@@ -187,20 +183,17 @@
   ast::type::F32Type f32;
 
   ast::StructMemberList members;
-  members.push_back(std::make_unique<ast::StructMember>(
-      "a", &i32, ast::StructMemberDecorationList{}));
+  members.push_back(
+      create<ast::StructMember>("a", &i32, ast::StructMemberDecorationList{}));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(
-      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
-  members.push_back(
-      std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
+  b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
+  members.push_back(create<ast::StructMember>("b", &f32, std::move(b_deco)));
 
   ast::StructDecorationList decos;
-  decos.push_back(std::make_unique<ast::StructBlockDecoration>(Source{}));
+  decos.push_back(create<ast::StructBlockDecoration>(Source{}));
 
-  auto str =
-      std::make_unique<ast::Struct>(std::move(decos), std::move(members));
+  auto str = create<ast::Struct>(std::move(decos), std::move(members));
 
   ast::type::StructType s("S", std::move(str));
 
diff --git a/src/writer/wgsl/generator_impl_unary_op_test.cc b/src/writer/wgsl/generator_impl_unary_op_test.cc
index 5ed2345..7c9ec68 100644
--- a/src/writer/wgsl/generator_impl_unary_op_test.cc
+++ b/src/writer/wgsl/generator_impl_unary_op_test.cc
@@ -38,7 +38,7 @@
 TEST_P(WgslUnaryOpTest, Emit) {
   auto params = GetParam();
 
-  auto expr = std::make_unique<ast::IdentifierExpression>("expr");
+  auto expr = create<ast::IdentifierExpression>("expr");
   ast::UnaryOpExpression op(params.op, std::move(expr));
 
   ASSERT_TRUE(gen.EmitExpression(&op)) << gen.error();
diff --git a/src/writer/wgsl/generator_impl_variable_decl_statement_test.cc b/src/writer/wgsl/generator_impl_variable_decl_statement_test.cc
index 828b23a..93a3ec6 100644
--- a/src/writer/wgsl/generator_impl_variable_decl_statement_test.cc
+++ b/src/writer/wgsl/generator_impl_variable_decl_statement_test.cc
@@ -32,8 +32,7 @@
 
 TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement) {
   ast::type::F32Type f32;
-  auto var =
-      std::make_unique<ast::Variable>("a", ast::StorageClass::kNone, &f32);
+  auto var = create<ast::Variable>("a", ast::StorageClass::kNone, &f32);
 
   ast::VariableDeclStatement stmt(std::move(var));
 
@@ -48,8 +47,7 @@
   // storage class.  Rely on defaulting.
   // https://github.com/gpuweb/gpuweb/issues/654
   ast::type::F32Type f32;
-  auto var =
-      std::make_unique<ast::Variable>("a", ast::StorageClass::kFunction, &f32);
+  auto var = create<ast::Variable>("a", ast::StorageClass::kFunction, &f32);
 
   ast::VariableDeclStatement stmt(std::move(var));
 
@@ -61,8 +59,7 @@
 
 TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Private) {
   ast::type::F32Type f32;
-  auto var =
-      std::make_unique<ast::Variable>("a", ast::StorageClass::kPrivate, &f32);
+  auto var = create<ast::Variable>("a", ast::StorageClass::kPrivate, &f32);
 
   ast::VariableDeclStatement stmt(std::move(var));
 
diff --git a/src/writer/wgsl/generator_impl_variable_test.cc b/src/writer/wgsl/generator_impl_variable_test.cc
index 4414596..1c980b9 100644
--- a/src/writer/wgsl/generator_impl_variable_test.cc
+++ b/src/writer/wgsl/generator_impl_variable_test.cc
@@ -55,7 +55,7 @@
   ast::type::F32Type f32;
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::LocationDecoration>(2, Source{}));
+  decos.push_back(create<ast::LocationDecoration>(2, Source{}));
 
   ast::DecoratedVariable dv;
   dv.set_name("a");
@@ -71,12 +71,12 @@
   ast::type::F32Type f32;
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::BuiltinDecoration>(
-      ast::Builtin::kPosition, Source{}));
-  decos.push_back(std::make_unique<ast::BindingDecoration>(0, Source{}));
-  decos.push_back(std::make_unique<ast::SetDecoration>(1, Source{}));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(2, Source{}));
-  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(42, Source{}));
+  decos.push_back(
+      create<ast::BuiltinDecoration>(ast::Builtin::kPosition, Source{}));
+  decos.push_back(create<ast::BindingDecoration>(0, Source{}));
+  decos.push_back(create<ast::SetDecoration>(1, Source{}));
+  decos.push_back(create<ast::LocationDecoration>(2, Source{}));
+  decos.push_back(create<ast::ConstantIdDecoration>(42, Source{}));
 
   ast::DecoratedVariable dv;
   dv.set_name("a");
@@ -91,7 +91,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitVariable_Constructor) {
-  auto ident = std::make_unique<ast::IdentifierExpression>("initializer");
+  auto ident = create<ast::IdentifierExpression>("initializer");
 
   ast::type::F32Type f32;
   ast::Variable v("a", ast::StorageClass::kNone, &f32);
@@ -103,7 +103,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitVariable_Const) {
-  auto ident = std::make_unique<ast::IdentifierExpression>("initializer");
+  auto ident = create<ast::IdentifierExpression>("initializer");
 
   ast::type::F32Type f32;
   ast::Variable v("a", ast::StorageClass::kNone, &f32);
diff --git a/src/writer/wgsl/test_helper.h b/src/writer/wgsl/test_helper.h
index 91e37af..7c3bd9e 100644
--- a/src/writer/wgsl/test_helper.h
+++ b/src/writer/wgsl/test_helper.h
@@ -15,6 +15,9 @@
 #ifndef SRC_WRITER_WGSL_TEST_HELPER_H_
 #define SRC_WRITER_WGSL_TEST_HELPER_H_
 
+#include <memory>
+#include <utility>
+
 #include "gtest/gtest.h"
 #include "src/ast/module.h"
 #include "src/context.h"
@@ -26,13 +29,20 @@
 namespace wgsl {
 
 /// Helper class for testing
-template <typename T>
-class TestHelperBase : public T {
+template <typename BASE>
+class TestHelperBase : public BASE {
  public:
   TestHelperBase() : td(&ctx, &mod), gen(&ctx) {}
 
   ~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