tint/ast: Migrate to utils::Vector

Change-Id: I10dd2feeaeb86a1ee7769d2bfd172e49c2805cb3
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/97843
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/resolver/entry_point_validation_test.cc b/src/tint/resolver/entry_point_validation_test.cc
index 5437828..38ebc81 100644
--- a/src/tint/resolver/entry_point_validation_test.cc
+++ b/src/tint/resolver/entry_point_validation_test.cc
@@ -49,8 +49,16 @@
 TEST_F(ResolverEntryPointValidationTest, ReturnTypeAttribute_Location) {
     // @fragment
     // fn main() -> @location(0) f32 { return 1.0; }
-    Func(Source{{12, 34}}, "main", {}, ty.f32(), {Return(1_f)},
-         {Stage(ast::PipelineStage::kFragment)}, {Location(0)});
+    Func(Source{{12, 34}}, "main", utils::Empty, ty.f32(),
+         utils::Vector{
+             Return(1_f),
+         },
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         },
+         utils::Vector{
+             Location(0),
+         });
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -58,8 +66,16 @@
 TEST_F(ResolverEntryPointValidationTest, ReturnTypeAttribute_Builtin) {
     // @vertex
     // fn main() -> @builtin(position) vec4<f32> { return vec4<f32>(); }
-    Func(Source{{12, 34}}, "main", {}, ty.vec4<f32>(), {Return(Construct(ty.vec4<f32>()))},
-         {Stage(ast::PipelineStage::kVertex)}, {Builtin(ast::BuiltinValue::kPosition)});
+    Func(Source{{12, 34}}, "main", utils::Empty, ty.vec4<f32>(),
+         utils::Vector{
+             Return(Construct(ty.vec4<f32>())),
+         },
+         utils::Vector{
+             Stage(ast::PipelineStage::kVertex),
+         },
+         utils::Vector{
+             Builtin(ast::BuiltinValue::kPosition),
+         });
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -69,8 +85,13 @@
     // fn main() -> f32 {
     //   return 1.0;
     // }
-    Func(Source{{12, 34}}, "main", {}, ty.vec4<f32>(), {Return(Construct(ty.vec4<f32>()))},
-         {Stage(ast::PipelineStage::kVertex)});
+    Func(Source{{12, 34}}, "main", utils::Empty, ty.vec4<f32>(),
+         utils::Vector{
+             Return(Construct(ty.vec4<f32>())),
+         },
+         utils::Vector{
+             Stage(ast::PipelineStage::kVertex),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: missing entry point IO attribute on return type");
@@ -81,9 +102,17 @@
     // fn main() -> @location(0) @builtin(position) vec4<f32> {
     //   return vec4<f32>();
     // }
-    Func(Source{{12, 34}}, "main", {}, ty.vec4<f32>(), {Return(Construct(ty.vec4<f32>()))},
-         {Stage(ast::PipelineStage::kVertex)},
-         {Location(Source{{13, 43}}, 0), Builtin(Source{{14, 52}}, ast::BuiltinValue::kPosition)});
+    Func(Source{{12, 34}}, "main", utils::Empty, ty.vec4<f32>(),
+         utils::Vector{
+             Return(Construct(ty.vec4<f32>())),
+         },
+         utils::Vector{
+             Stage(ast::PipelineStage::kVertex),
+         },
+         utils::Vector{
+             Location(Source{{13, 43}}, 0),
+             Builtin(Source{{14, 52}}, ast::BuiltinValue::kPosition),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), R"(14:52 error: multiple entry point IO attributes
@@ -99,11 +128,18 @@
     // fn main() -> Output {
     //   return Output();
     // }
-    auto* output =
-        Structure("Output", {Member("a", ty.f32(), {Location(0)}),
-                             Member("b", ty.f32(), {Builtin(ast::BuiltinValue::kFragDepth)})});
-    Func(Source{{12, 34}}, "main", {}, ty.Of(output), {Return(Construct(ty.Of(output)))},
-         {Stage(ast::PipelineStage::kFragment)});
+    auto* output = Structure(
+        "Output", utils::Vector{
+                      Member("a", ty.f32(), utils::Vector{Location(0)}),
+                      Member("b", ty.f32(), utils::Vector{Builtin(ast::BuiltinValue::kFragDepth)}),
+                  });
+    Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
+         utils::Vector{
+             Return(Construct(ty.Of(output))),
+         },
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         });
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -116,12 +152,20 @@
     // fn main() -> Output {
     //   return Output();
     // }
-    auto* output =
-        Structure("Output", {Member("a", ty.f32(),
-                                    {Location(Source{{13, 43}}, 0),
-                                     Builtin(Source{{14, 52}}, ast::BuiltinValue::kFragDepth)})});
-    Func(Source{{12, 34}}, "main", {}, ty.Of(output), {Return(Construct(ty.Of(output)))},
-         {Stage(ast::PipelineStage::kFragment)});
+    auto* output = Structure(
+        "Output",
+        utils::Vector{
+            Member("a", ty.f32(),
+                   utils::Vector{Location(Source{{13, 43}}, 0),
+                                 Builtin(Source{{14, 52}}, ast::BuiltinValue::kFragDepth)}),
+        });
+    Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
+         utils::Vector{
+             Return(Construct(ty.Of(output))),
+         },
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), R"(14:52 error: multiple entry point IO attributes
@@ -138,10 +182,18 @@
     // fn main() -> Output {
     //   return Output();
     // }
-    auto* output = Structure("Output", {Member(Source{{13, 43}}, "a", ty.f32(), {Location(0)}),
-                                        Member(Source{{14, 52}}, "b", ty.f32(), {})});
-    Func(Source{{12, 34}}, "main", {}, ty.Of(output), {Return(Construct(ty.Of(output)))},
-         {Stage(ast::PipelineStage::kFragment)});
+    auto* output =
+        Structure("Output", utils::Vector{
+                                Member(Source{{13, 43}}, "a", ty.f32(), utils::Vector{Location(0)}),
+                                Member(Source{{14, 52}}, "b", ty.f32(), {}),
+                            });
+    Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
+         utils::Vector{
+             Return(Construct(ty.Of(output))),
+         },
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -158,11 +210,18 @@
     // fn main() -> Output {
     //   return Output();
     // }
-    auto* output =
-        Structure("Output", {Member("a", ty.f32(), {Builtin(ast::BuiltinValue::kFragDepth)}),
-                             Member("b", ty.f32(), {Builtin(ast::BuiltinValue::kFragDepth)})});
-    Func(Source{{12, 34}}, "main", {}, ty.Of(output), {Return(Construct(ty.Of(output)))},
-         {Stage(ast::PipelineStage::kFragment)});
+    auto* output = Structure(
+        "Output", utils::Vector{
+                      Member("a", ty.f32(), utils::Vector{Builtin(ast::BuiltinValue::kFragDepth)}),
+                      Member("b", ty.f32(), utils::Vector{Builtin(ast::BuiltinValue::kFragDepth)}),
+                  });
+    Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
+         utils::Vector{
+             Return(Construct(ty.Of(output))),
+         },
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -174,8 +233,18 @@
 TEST_F(ResolverEntryPointValidationTest, ParameterAttribute_Location) {
     // @fragment
     // fn main(@location(0) param : f32) {}
-    auto* param = Param("param", ty.f32(), {Location(0)});
-    Func(Source{{12, 34}}, "main", {param}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+    auto* param = Param("param", ty.f32(),
+                        utils::Vector{
+                            Location(0),
+                        });
+    Func(Source{{12, 34}}, "main",
+         utils::Vector{
+             param,
+         },
+         ty.void_(), utils::Empty,
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         });
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -184,7 +253,14 @@
     // @fragment
     // fn main(param : f32) {}
     auto* param = Param(Source{{13, 43}}, "param", ty.vec4<f32>());
-    Func(Source{{12, 34}}, "main", {param}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+    Func(Source{{12, 34}}, "main",
+         utils::Vector{
+             param,
+         },
+         ty.void_(), utils::Empty,
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "13:43 error: missing entry point IO attribute on parameter");
@@ -194,9 +270,18 @@
     // @fragment
     // fn main(@location(0) @builtin(sample_index) param : u32) {}
     auto* param = Param("param", ty.u32(),
-                        {Location(Source{{13, 43}}, 0),
-                         Builtin(Source{{14, 52}}, ast::BuiltinValue::kSampleIndex)});
-    Func(Source{{12, 34}}, "main", {param}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+                        utils::Vector{
+                            Location(Source{{13, 43}}, 0),
+                            Builtin(Source{{14, 52}}, ast::BuiltinValue::kSampleIndex),
+                        });
+    Func(Source{{12, 34}}, "main",
+         utils::Vector{
+             param,
+         },
+         ty.void_(), utils::Empty,
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), R"(14:52 error: multiple entry point IO attributes
@@ -210,11 +295,20 @@
     // };
     // @fragment
     // fn main(param : Input) {}
-    auto* input =
-        Structure("Input", {Member("a", ty.f32(), {Location(0)}),
-                            Member("b", ty.u32(), {Builtin(ast::BuiltinValue::kSampleIndex)})});
+    auto* input = Structure(
+        "Input", utils::Vector{
+                     Member("a", ty.f32(), utils::Vector{Location(0)}),
+                     Member("b", ty.u32(), utils::Vector{Builtin(ast::BuiltinValue::kSampleIndex)}),
+                 });
     auto* param = Param("param", ty.Of(input));
-    Func(Source{{12, 34}}, "main", {param}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+    Func(Source{{12, 34}}, "main",
+         utils::Vector{
+             param,
+         },
+         ty.void_(), utils::Empty,
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         });
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -225,12 +319,22 @@
     // };
     // @fragment
     // fn main(param : Input) {}
-    auto* input =
-        Structure("Input", {Member("a", ty.u32(),
-                                   {Location(Source{{13, 43}}, 0),
-                                    Builtin(Source{{14, 52}}, ast::BuiltinValue::kSampleIndex)})});
+    auto* input = Structure(
+        "Input",
+        utils::Vector{
+            Member("a", ty.u32(),
+                   utils::Vector{Location(Source{{13, 43}}, 0),
+                                 Builtin(Source{{14, 52}}, ast::BuiltinValue::kSampleIndex)}),
+        });
     auto* param = Param("param", ty.Of(input));
-    Func(Source{{12, 34}}, "main", {param}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+    Func(Source{{12, 34}}, "main",
+         utils::Vector{
+             param,
+         },
+         ty.void_(), utils::Empty,
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), R"(14:52 error: multiple entry point IO attributes
@@ -245,10 +349,20 @@
     // };
     // @fragment
     // fn main(param : Input) {}
-    auto* input = Structure("Input", {Member(Source{{13, 43}}, "a", ty.f32(), {Location(0)}),
-                                      Member(Source{{14, 52}}, "b", ty.f32(), {})});
+    auto* input =
+        Structure("Input", utils::Vector{
+                               Member(Source{{13, 43}}, "a", ty.f32(), utils::Vector{Location(0)}),
+                               Member(Source{{14, 52}}, "b", ty.f32(), {}),
+                           });
     auto* param = Param("param", ty.Of(input));
-    Func(Source{{12, 34}}, "main", {param}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+    Func(Source{{12, 34}}, "main",
+         utils::Vector{
+             param,
+         },
+         ty.void_(), utils::Empty,
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), R"(14:52 error: missing entry point IO attribute
@@ -259,10 +373,23 @@
     // @fragment
     // fn main(@builtin(sample_index) param_a : u32,
     //         @builtin(sample_index) param_b : u32) {}
-    auto* param_a = Param("param_a", ty.u32(), {Builtin(ast::BuiltinValue::kSampleIndex)});
-    auto* param_b = Param("param_b", ty.u32(), {Builtin(ast::BuiltinValue::kSampleIndex)});
-    Func(Source{{12, 34}}, "main", {param_a, param_b}, ty.void_(), {},
-         {Stage(ast::PipelineStage::kFragment)});
+    auto* param_a = Param("param_a", ty.u32(),
+                          utils::Vector{
+                              Builtin(ast::BuiltinValue::kSampleIndex),
+                          });
+    auto* param_b = Param("param_b", ty.u32(),
+                          utils::Vector{
+                              Builtin(ast::BuiltinValue::kSampleIndex),
+                          });
+    Func(Source{{12, 34}}, "main",
+         utils::Vector{
+             param_a,
+             param_b,
+         },
+         ty.void_(), utils::Empty,
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -279,14 +406,27 @@
     // };
     // @fragment
     // fn main(param_a : InputA, param_b : InputB) {}
-    auto* input_a =
-        Structure("InputA", {Member("a", ty.u32(), {Builtin(ast::BuiltinValue::kSampleIndex)})});
-    auto* input_b =
-        Structure("InputB", {Member("a", ty.u32(), {Builtin(ast::BuiltinValue::kSampleIndex)})});
+    auto* input_a = Structure(
+        "InputA",
+        utils::Vector{
+            Member("a", ty.u32(), utils::Vector{Builtin(ast::BuiltinValue::kSampleIndex)}),
+        });
+    auto* input_b = Structure(
+        "InputB",
+        utils::Vector{
+            Member("a", ty.u32(), utils::Vector{Builtin(ast::BuiltinValue::kSampleIndex)}),
+        });
     auto* param_a = Param("param_a", ty.Of(input_a));
     auto* param_b = Param("param_b", ty.Of(input_b));
-    Func(Source{{12, 34}}, "main", {param_a, param_b}, ty.void_(), {},
-         {Stage(ast::PipelineStage::kFragment)});
+    Func(Source{{12, 34}}, "main",
+         utils::Vector{
+             param_a,
+             param_b,
+         },
+         ty.void_(), utils::Empty,
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -298,7 +438,10 @@
 TEST_F(ResolverEntryPointValidationTest, VertexShaderMustReturnPosition) {
     // @vertex
     // fn main() {}
-    Func(Source{{12, 34}}, "main", {}, ty.void_(), {}, {Stage(ast::PipelineStage::kVertex)});
+    Func(Source{{12, 34}}, "main", utils::Empty, ty.void_(), utils::Empty,
+         utils::Vector{
+             Stage(ast::PipelineStage::kVertex),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -477,8 +620,19 @@
 
     Enable(ast::Extension::kF16);
 
-    auto* a = Param("a", params.create_ast_type(*this), {Location(0), Flat()});
-    Func(Source{{12, 34}}, "main", {a}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+    auto* a = Param("a", params.create_ast_type(*this),
+                    utils::Vector{
+                        Location(0),
+                        Flat(),
+                    });
+    Func(Source{{12, 34}}, "main",
+         utils::Vector{
+             a,
+         },
+         ty.void_(), utils::Empty,
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         });
 
     if (params.is_valid) {
         EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -497,10 +651,19 @@
 
     Enable(ast::Extension::kF16);
 
-    auto* input =
-        Structure("Input", {Member("a", params.create_ast_type(*this), {Location(0), Flat()})});
+    auto* input = Structure(
+        "Input", utils::Vector{
+                     Member("a", params.create_ast_type(*this), utils::Vector{Location(0), Flat()}),
+                 });
     auto* a = Param("a", ty.Of(input), {});
-    Func(Source{{12, 34}}, "main", {a}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+    Func(Source{{12, 34}}, "main",
+         utils::Vector{
+             a,
+         },
+         ty.void_(), utils::Empty,
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         });
 
     if (params.is_valid) {
         EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -518,9 +681,16 @@
 
     Enable(ast::Extension::kF16);
 
-    Func(Source{{12, 34}}, "main", {}, params.create_ast_type(*this),
-         {Return(Construct(params.create_ast_type(*this)))}, {Stage(ast::PipelineStage::kFragment)},
-         {Location(0)});
+    Func(Source{{12, 34}}, "main", utils::Empty, params.create_ast_type(*this),
+         utils::Vector{
+             Return(Construct(params.create_ast_type(*this))),
+         },
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         },
+         utils::Vector{
+             Location(0),
+         });
 
     if (params.is_valid) {
         EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -541,9 +711,17 @@
 
     Enable(ast::Extension::kF16);
 
-    auto* output = Structure("Output", {Member("a", params.create_ast_type(*this), {Location(0)})});
-    Func(Source{{12, 34}}, "main", {}, ty.Of(output), {Return(Construct(ty.Of(output)))},
-         {Stage(ast::PipelineStage::kFragment)});
+    auto* output = Structure(
+        "Output", utils::Vector{
+                      Member("a", params.create_ast_type(*this), utils::Vector{Location(0)}),
+                  });
+    Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
+         utils::Vector{
+             Return(Construct(ty.Of(output))),
+         },
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         });
 
     if (params.is_valid) {
         EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -565,8 +743,19 @@
     // @fragment
     // fn frag_main(@location(0) @interpolate(flat) a: i32) {}
 
-    auto* p = Param(Source{{12, 34}}, "a", ty.i32(), {Location(0), Flat()});
-    Func("frag_main", {p}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+    auto* p = Param(Source{{12, 34}}, "a", ty.i32(),
+                    utils::Vector{
+                        Location(0),
+                        Flat(),
+                    });
+    Func("frag_main",
+         utils::Vector{
+             p,
+         },
+         ty.void_(), utils::Empty,
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         });
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -575,8 +764,18 @@
     // @fragment
     // fn frag_main(@location(0) a: bool) {}
 
-    auto* p = Param(Source{{12, 34}}, "a", ty.bool_(), {Location(Source{{34, 56}}, 0)});
-    Func("frag_main", {p}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+    auto* p = Param(Source{{12, 34}}, "a", ty.bool_(),
+                    utils::Vector{
+                        Location(Source{{34, 56}}, 0),
+                    });
+    Func("frag_main",
+         utils::Vector{
+             p,
+         },
+         ty.void_(), utils::Empty,
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -590,9 +789,16 @@
     // @fragment
     // fn frag_main()->@location(0) array<f32, 2> { return array<f32, 2>(); }
 
-    Func(Source{{12, 34}}, "frag_main", {}, ty.array<f32, 2>(),
-         {Return(Construct(ty.array<f32, 2>()))}, {Stage(ast::PipelineStage::kFragment)},
-         {Location(Source{{34, 56}}, 0)});
+    Func(Source{{12, 34}}, "frag_main", utils::Empty, ty.array<f32, 2>(),
+         utils::Vector{
+             Return(Construct(ty.array<f32, 2>())),
+         },
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         },
+         utils::Vector{
+             Location(Source{{34, 56}}, 0),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -608,9 +814,21 @@
     // };
     // @fragment
     // fn main(@location(0) param : Input) {}
-    auto* input = Structure("Input", {Member("a", ty.f32())});
-    auto* param = Param(Source{{12, 34}}, "param", ty.Of(input), {Location(Source{{13, 43}}, 0)});
-    Func(Source{{12, 34}}, "main", {param}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+    auto* input = Structure("Input", utils::Vector{
+                                         Member("a", ty.f32()),
+                                     });
+    auto* param = Param(Source{{12, 34}}, "param", ty.Of(input),
+                        utils::Vector{
+                            Location(Source{{13, 43}}, 0),
+                        });
+    Func(Source{{12, 34}}, "main",
+         utils::Vector{
+             param,
+         },
+         ty.void_(), utils::Empty,
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -629,10 +847,22 @@
     // };
     // @fragment
     // fn main(param : Input) {}
-    auto* inner = Structure("Inner", {Member(Source{{13, 43}}, "a", ty.f32(), {Location(0)})});
-    auto* input = Structure("Input", {Member(Source{{14, 52}}, "a", ty.Of(inner))});
+    auto* inner =
+        Structure("Inner", utils::Vector{
+                               Member(Source{{13, 43}}, "a", ty.f32(), utils::Vector{Location(0)}),
+                           });
+    auto* input = Structure("Input", utils::Vector{
+                                         Member(Source{{14, 52}}, "a", ty.Of(inner)),
+                                     });
     auto* param = Param("param", ty.Of(input));
-    Func(Source{{12, 34}}, "main", {param}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+    Func(Source{{12, 34}}, "main",
+         utils::Vector{
+             param,
+         },
+         ty.void_(), utils::Empty,
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -646,10 +876,19 @@
     // };
     // @fragment
     // fn main(param : Input) {}
-    auto* input =
-        Structure("Input", {Member(Source{{13, 43}}, "a", ty.array<f32>(), {Location(0)})});
+    auto* input = Structure(
+        "Input", utils::Vector{
+                     Member(Source{{13, 43}}, "a", ty.array<f32>(), utils::Vector{Location(0)}),
+                 });
     auto* param = Param("param", ty.Of(input));
-    Func(Source{{12, 34}}, "main", {param}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+    Func(Source{{12, 34}}, "main",
+         utils::Vector{
+             param,
+         },
+         ty.void_(), utils::Empty,
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -665,11 +904,20 @@
     // fn frag_main( a: S) {}
 
     auto* m = Member(Source{{34, 56}}, "m", ty.array<i32>(),
-                     ast::AttributeList{Location(Source{{12, 34}}, 0u)});
-    auto* s = Structure("S", {m});
+                     utils::Vector{
+                         Location(Source{{12, 34}}, 0u),
+                     });
+    auto* s = Structure("S", utils::Vector{m});
     auto* p = Param("a", ty.Of(s));
 
-    Func("frag_main", {p}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
+    Func("frag_main",
+         utils::Vector{
+             p,
+         },
+         ty.void_(), utils::Empty,
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -684,11 +932,19 @@
     // @fragment
     // fn frag_main() -> S {}
     auto* m = Member(Source{{34, 56}}, "m", ty.atomic<i32>(),
-                     ast::AttributeList{Location(Source{{12, 34}}, 0u)});
-    auto* s = Structure("S", {m});
+                     utils::Vector{
+                         Location(Source{{12, 34}}, 0u),
+                     });
+    auto* s = Structure("S", utils::Vector{m});
 
-    Func("frag_main", {}, ty.Of(s), {Return(Construct(ty.Of(s)))},
-         {Stage(ast::PipelineStage::kFragment)}, {});
+    Func("frag_main", utils::Empty, ty.Of(s),
+         utils::Vector{
+             Return(Construct(ty.Of(s))),
+         },
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         },
+         {});
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -702,8 +958,10 @@
     // struct S { @location(0) m: mat3x2<f32>; };
 
     auto* m = Member(Source{{34, 56}}, "m", ty.mat3x2<f32>(),
-                     ast::AttributeList{Location(Source{{12, 34}}, 0u)});
-    Structure("S", {m});
+                     utils::Vector{
+                         Location(Source{{12, 34}}, 0u),
+                     });
+    Structure("S", utils::Vector{m});
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -722,11 +980,18 @@
     // fn main() -> Output {
     //   return Output();
     // }
-    auto* output =
-        Structure("Output", {Member("a", ty.f32(), {Location(0)}),
-                             Member("b", ty.f32(), {Builtin(ast::BuiltinValue::kFragDepth)})});
-    Func(Source{{12, 34}}, "main", {}, ty.Of(output), {Return(Construct(ty.Of(output)))},
-         {Stage(ast::PipelineStage::kFragment)});
+    auto* output = Structure(
+        "Output", utils::Vector{
+                      Member("a", ty.f32(), utils::Vector{Location(0)}),
+                      Member("b", ty.f32(), utils::Vector{Builtin(ast::BuiltinValue::kFragDepth)}),
+                  });
+    Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
+         utils::Vector{
+             Return(Construct(ty.Of(output))),
+         },
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         });
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -739,9 +1004,19 @@
     // fn main() -> @location(0) Output {
     //   return Output();
     // }
-    auto* output = Structure("Output", {Member("a", ty.f32())});
-    Func(Source{{12, 34}}, "main", {}, ty.Of(output), {Return(Construct(ty.Of(output)))},
-         {Stage(ast::PipelineStage::kVertex)}, {Location(Source{{13, 43}}, 0)});
+    auto* output = Structure("Output", utils::Vector{
+                                           Member("a", ty.f32()),
+                                       });
+    Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
+         utils::Vector{
+             Return(Construct(ty.Of(output))),
+         },
+         utils::Vector{
+             Stage(ast::PipelineStage::kVertex),
+         },
+         utils::Vector{
+             Location(Source{{13, 43}}, 0),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -760,10 +1035,20 @@
     // };
     // @fragment
     // fn main() -> Output { return Output(); }
-    auto* inner = Structure("Inner", {Member(Source{{13, 43}}, "a", ty.f32(), {Location(0)})});
-    auto* output = Structure("Output", {Member(Source{{14, 52}}, "a", ty.Of(inner))});
-    Func(Source{{12, 34}}, "main", {}, ty.Of(output), {Return(Construct(ty.Of(output)))},
-         {Stage(ast::PipelineStage::kFragment)});
+    auto* inner =
+        Structure("Inner", utils::Vector{
+                               Member(Source{{13, 43}}, "a", ty.f32(), utils::Vector{Location(0)}),
+                           });
+    auto* output = Structure("Output", utils::Vector{
+                                           Member(Source{{14, 52}}, "a", ty.Of(inner)),
+                                       });
+    Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
+         utils::Vector{
+             Return(Construct(ty.Of(output))),
+         },
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -779,10 +1064,17 @@
     // fn main() -> Output {
     //   return Output();
     // }
-    auto* output = Structure("Output", {Member(Source{{13, 43}}, "a", ty.array<f32>(),
-                                               {Location(Source{{12, 34}}, 0)})});
-    Func(Source{{12, 34}}, "main", {}, ty.Of(output), {Return(Construct(ty.Of(output)))},
-         {Stage(ast::PipelineStage::kFragment)});
+    auto* output = Structure("Output", utils::Vector{
+                                           Member(Source{{13, 43}}, "a", ty.array<f32>(),
+                                                  utils::Vector{Location(Source{{12, 34}}, 0)}),
+                                       });
+    Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
+         utils::Vector{
+             Return(Construct(ty.Of(output))),
+         },
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -793,32 +1085,51 @@
 }
 
 TEST_F(LocationAttributeTests, ComputeShaderLocation_Input) {
-    Func("main", {}, ty.i32(), {Return(Expr(1_i))},
-         {Stage(ast::PipelineStage::kCompute),
-          create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i))},
-         ast::AttributeList{Location(Source{{12, 34}}, 1)});
+    Func("main", utils::Empty, ty.i32(),
+         utils::Vector{
+             Return(Expr(1_i)),
+         },
+         utils::Vector{
+             Stage(ast::PipelineStage::kCompute),
+             create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i)),
+         },
+         utils::Vector{
+             Location(Source{{12, 34}}, 1),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: attribute is not valid for compute shader output");
 }
 
 TEST_F(LocationAttributeTests, ComputeShaderLocation_Output) {
-    auto* input = Param("input", ty.i32(), ast::AttributeList{Location(Source{{12, 34}}, 0u)});
-    Func("main", {input}, ty.void_(), {},
-         {Stage(ast::PipelineStage::kCompute),
-          create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i))});
+    auto* input = Param("input", ty.i32(),
+                        utils::Vector{
+                            Location(Source{{12, 34}}, 0u),
+                        });
+    Func("main", utils::Vector{input}, ty.void_(), utils::Empty,
+         utils::Vector{
+             Stage(ast::PipelineStage::kCompute),
+             create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i)),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: attribute is not valid for compute shader inputs");
 }
 
 TEST_F(LocationAttributeTests, ComputeShaderLocationStructMember_Output) {
-    auto* m = Member("m", ty.i32(), ast::AttributeList{Location(Source{{12, 34}}, 0u)});
-    auto* s = Structure("S", {m});
-    Func(Source{{56, 78}}, "main", {}, ty.Of(s),
-         ast::StatementList{Return(Expr(Construct(ty.Of(s))))},
-         {Stage(ast::PipelineStage::kCompute),
-          create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i))});
+    auto* m = Member("m", ty.i32(),
+                     utils::Vector{
+                         Location(Source{{12, 34}}, 0u),
+                     });
+    auto* s = Structure("S", utils::Vector{m});
+    Func(Source{{56, 78}}, "main", utils::Empty, ty.Of(s),
+         utils::Vector{
+             Return(Expr(Construct(ty.Of(s)))),
+         },
+         utils::Vector{
+             Stage(ast::PipelineStage::kCompute),
+             create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i)),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -827,12 +1138,17 @@
 }
 
 TEST_F(LocationAttributeTests, ComputeShaderLocationStructMember_Input) {
-    auto* m = Member("m", ty.i32(), ast::AttributeList{Location(Source{{12, 34}}, 0u)});
-    auto* s = Structure("S", {m});
+    auto* m = Member("m", ty.i32(),
+                     utils::Vector{
+                         Location(Source{{12, 34}}, 0u),
+                     });
+    auto* s = Structure("S", utils::Vector{m});
     auto* input = Param("input", ty.Of(s));
-    Func(Source{{56, 78}}, "main", {input}, ty.void_(), {},
-         {Stage(ast::PipelineStage::kCompute),
-          create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i))});
+    Func(Source{{56, 78}}, "main", utils::Vector{input}, ty.void_(), utils::Empty,
+         utils::Vector{
+             Stage(ast::PipelineStage::kCompute),
+             create<ast::WorkgroupAttribute>(Source{{12, 34}}, Expr(1_i)),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -844,10 +1160,23 @@
     // @fragment
     // fn main(@location(1) param_a : f32,
     //         @location(1) param_b : f32) {}
-    auto* param_a = Param("param_a", ty.f32(), {Location(1)});
-    auto* param_b = Param("param_b", ty.f32(), {Location(Source{{12, 34}}, 1)});
-    Func(Source{{12, 34}}, "main", {param_a, param_b}, ty.void_(), {},
-         {Stage(ast::PipelineStage::kFragment)});
+    auto* param_a = Param("param_a", ty.f32(),
+                          utils::Vector{
+                              Location(1),
+                          });
+    auto* param_b = Param("param_b", ty.f32(),
+                          utils::Vector{
+                              Location(Source{{12, 34}}, 1),
+                          });
+    Func(Source{{12, 34}}, "main",
+         utils::Vector{
+             param_a,
+             param_b,
+         },
+         ty.void_(), utils::Empty,
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: location(1) attribute appears multiple times");
@@ -862,12 +1191,24 @@
     // };
     // @fragment
     // fn main(param_a : InputA, param_b : InputB) {}
-    auto* input_a = Structure("InputA", {Member("a", ty.f32(), {Location(1)})});
-    auto* input_b = Structure("InputB", {Member("a", ty.f32(), {Location(Source{{34, 56}}, 1)})});
+    auto* input_a = Structure("InputA", utils::Vector{
+                                            Member("a", ty.f32(), utils::Vector{Location(1)}),
+                                        });
+    auto* input_b =
+        Structure("InputB", utils::Vector{
+                                Member("a", ty.f32(), utils::Vector{Location(Source{{34, 56}}, 1)}),
+                            });
     auto* param_a = Param("param_a", ty.Of(input_a));
     auto* param_b = Param("param_b", ty.Of(input_b));
-    Func(Source{{12, 34}}, "main", {param_a, param_b}, ty.void_(), {},
-         {Stage(ast::PipelineStage::kFragment)});
+    Func(Source{{12, 34}}, "main",
+         utils::Vector{
+             param_a,
+             param_b,
+         },
+         ty.void_(), utils::Empty,
+         utils::Vector{
+             Stage(ast::PipelineStage::kFragment),
+         });
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),