tint: Rename ProgramBuilder::Construct() to Call()

Once all ast::Type derived classes are removed, there will be no
distinction between a type initializer / conversion and a function call.

Bug: tint:1810
Change-Id: Ic10fd1a0364a564d24dbe2499af0f1424641596c
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/118980
Auto-Submit: Ben Clayton <bclayton@google.com>
Reviewed-by: James Price <jrprice@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@chromium.org>
diff --git a/src/tint/ast/call_expression_test.cc b/src/tint/ast/call_expression_test.cc
index 774d6a2..12b446a 100644
--- a/src/tint/ast/call_expression_test.cc
+++ b/src/tint/ast/call_expression_test.cc
@@ -55,7 +55,7 @@
         Expr("param2"),
     };
 
-    auto* stmt = Construct(type, params);
+    auto* stmt = Call(type, params);
     EXPECT_EQ(stmt->target.name, nullptr);
     EXPECT_EQ(stmt->target.type, type);
 
@@ -67,7 +67,7 @@
 
 TEST_F(CallExpressionTest, CreationType_WithSource) {
     auto* type = ty.f32();
-    auto* stmt = Construct(Source{{20, 2}}, type);
+    auto* stmt = Call(Source{{20, 2}}, type);
     EXPECT_EQ(stmt->target.name, nullptr);
     EXPECT_EQ(stmt->target.type, type);
 
@@ -95,7 +95,7 @@
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b;
-            b.Construct(static_cast<Type*>(nullptr));
+            b.Call(static_cast<Type*>(nullptr));
         },
         "internal compiler error");
 }
@@ -128,7 +128,7 @@
         {
             ProgramBuilder b1;
             ProgramBuilder b2;
-            b1.Construct(b2.ty.f32());
+            b1.Call(b2.ty.f32());
         },
         "internal compiler error");
 }
diff --git a/src/tint/inspector/inspector_test.cc b/src/tint/inspector/inspector_test.cc
index da78956..61e7a88 100644
--- a/src/tint/inspector/inspector_test.cc
+++ b/src/tint/inspector/inspector_test.cc
@@ -547,7 +547,7 @@
                                                    });
     Func("foo", utils::Empty, ty.Of(interface),
          utils::Vector{
-             Return(Construct(ty.Of(interface))),
+             Return(Call(ty.Of(interface))),
          },
          utils::Vector{
              Stage(ast::PipelineStage::kFragment),
diff --git a/src/tint/program_builder.h b/src/tint/program_builder.h
index e832334..236d1ae 100644
--- a/src/tint/program_builder.h
+++ b/src/tint/program_builder.h
@@ -163,12 +163,29 @@
 /// To construct a Program, populate the builder and then `std::move` it to a
 /// Program.
 class ProgramBuilder {
-    /// A helper used to disable overloads if the first type in `TYPES` is a
-    /// Source. Used to avoid ambiguities in overloads that take a Source as the
-    /// first parameter and those that perfectly-forward the first argument.
+    /// Evaluates to true if T is a Source
+    template <typename T>
+    static constexpr const bool IsSource = std::is_same_v<T, Source>;
+
+    /// Evaluates to true if T is a Number or bool.
+    template <typename T>
+    static constexpr const bool IsScalar =
+        std::is_integral_v<UnwrapNumber<T>> || std::is_floating_point_v<UnwrapNumber<T>> ||
+        std::is_same_v<T, bool>;
+
+    /// A helper used to disable overloads if the first type in `TYPES` is a Source. Used to avoid
+    /// ambiguities in overloads that take a Source as the first parameter and those that
+    /// perfectly-forward the first argument.
     template <typename... TYPES>
     using DisableIfSource =
-        traits::EnableIfIsNotType<traits::Decay<traits::NthTypeOf<0, TYPES..., void>>, Source>;
+        traits::EnableIf<!IsSource<traits::Decay<traits::NthTypeOf<0, TYPES..., void>>>>;
+
+    /// A helper used to disable overloads if the first type in `TYPES` is a scalar type. Used to
+    /// avoid ambiguities in overloads that take a scalar as the first parameter and those that
+    /// perfectly-forward the first argument.
+    template <typename... TYPES>
+    using DisableIfScalar =
+        traits::EnableIf<!IsScalar<traits::Decay<traits::NthTypeOf<0, TYPES..., void>>>>;
 
     /// A helper used to disable overloads if the first type in `TYPES` is a utils::Vector,
     /// utils::VectorRef or utils::VectorRef.
@@ -1404,35 +1421,6 @@
         return list;
     }
 
-    /// @param args the arguments for the type constructor
-    /// @return an `ast::CallExpression` of type `ty`, with the values
-    /// of `args` converted to `ast::Expression`s using `Expr()`
-    template <typename T, typename... ARGS>
-    const ast::CallExpression* Construct(ARGS&&... args) {
-        return Construct(ty.Of<T>(), std::forward<ARGS>(args)...);
-    }
-
-    /// @param type the type to construct
-    /// @param args the arguments for the constructor
-    /// @return an `ast::CallExpression` of `type` constructed with the
-    /// values `args`.
-    template <typename... ARGS>
-    const ast::CallExpression* Construct(const ast::Type* type, ARGS&&... args) {
-        return Construct(source_, type, std::forward<ARGS>(args)...);
-    }
-
-    /// @param source the source information
-    /// @param type the type to construct
-    /// @param args the arguments for the constructor
-    /// @return an `ast::CallExpression` of `type` constructed with the
-    /// values `args`.
-    template <typename... ARGS>
-    const ast::CallExpression* Construct(const Source& source,
-                                         const ast::Type* type,
-                                         ARGS&&... args) {
-        return create<ast::CallExpression>(source, type, ExprList(std::forward<ARGS>(args)...));
-    }
-
     /// @param expr the expression for the bitcast
     /// @return an `ast::BitcastExpression` of type `ty`, with the values of
     /// `expr` converted to `ast::Expression`s using `Expr()`
@@ -1469,7 +1457,7 @@
     /// type `type`, constructed with the values `args`.
     template <typename... ARGS>
     const ast::CallExpression* vec(const ast::Type* type, uint32_t size, ARGS&&... args) {
-        return Construct(ty.vec(type, size), std::forward<ARGS>(args)...);
+        return Call(ty.vec(type, size), std::forward<ARGS>(args)...);
     }
 
     /// @param args the arguments for the vector initializer
@@ -1477,7 +1465,7 @@
     /// `T`, constructed with the values `args`.
     template <typename T, typename... ARGS, typename _ = DisableIfSource<ARGS...>>
     const ast::CallExpression* vec2(ARGS&&... args) {
-        return Construct(ty.vec2<T>(), std::forward<ARGS>(args)...);
+        return Call(ty.vec2<T>(), std::forward<ARGS>(args)...);
     }
 
     /// @param source the vector source
@@ -1486,7 +1474,7 @@
     /// `T`, constructed with the values `args`.
     template <typename T, typename... ARGS>
     const ast::CallExpression* vec2(const Source& source, ARGS&&... args) {
-        return Construct(source, ty.vec2<T>(), std::forward<ARGS>(args)...);
+        return Call(source, ty.vec2<T>(), std::forward<ARGS>(args)...);
     }
 
     /// @param args the arguments for the vector initializer
@@ -1494,7 +1482,7 @@
     /// `T`, constructed with the values `args`.
     template <typename T, typename... ARGS, typename _ = DisableIfSource<ARGS...>>
     const ast::CallExpression* vec3(ARGS&&... args) {
-        return Construct(ty.vec3<T>(), std::forward<ARGS>(args)...);
+        return Call(ty.vec3<T>(), std::forward<ARGS>(args)...);
     }
 
     /// @param source the vector source
@@ -1503,7 +1491,7 @@
     /// `T`, constructed with the values `args`.
     template <typename T, typename... ARGS>
     const ast::CallExpression* vec3(const Source& source, ARGS&&... args) {
-        return Construct(source, ty.vec3<T>(), std::forward<ARGS>(args)...);
+        return Call(source, ty.vec3<T>(), std::forward<ARGS>(args)...);
     }
 
     /// @param args the arguments for the vector initializer
@@ -1511,7 +1499,7 @@
     /// `T`, constructed with the values `args`.
     template <typename T, typename... ARGS, typename _ = DisableIfSource<ARGS...>>
     const ast::CallExpression* vec4(ARGS&&... args) {
-        return Construct(ty.vec4<T>(), std::forward<ARGS>(args)...);
+        return Call(ty.vec4<T>(), std::forward<ARGS>(args)...);
     }
 
     /// @param source the vector source
@@ -1520,7 +1508,7 @@
     /// `T`, constructed with the values `args`.
     template <typename T, typename... ARGS>
     const ast::CallExpression* vec4(const Source& source, ARGS&&... args) {
-        return Construct(source, ty.vec4<T>(), std::forward<ARGS>(args)...);
+        return Call(source, ty.vec4<T>(), std::forward<ARGS>(args)...);
     }
 
     /// @param args the arguments for the matrix initializer
@@ -1528,7 +1516,7 @@
     /// `T`, constructed with the values `args`.
     template <typename T, typename... ARGS, typename _ = DisableIfSource<ARGS...>>
     const ast::CallExpression* mat2x2(ARGS&&... args) {
-        return Construct(ty.mat2x2<T>(), std::forward<ARGS>(args)...);
+        return Call(ty.mat2x2<T>(), std::forward<ARGS>(args)...);
     }
 
     /// @param source the matrix source
@@ -1537,7 +1525,7 @@
     /// `T`, constructed with the values `args`.
     template <typename T, typename... ARGS>
     const ast::CallExpression* mat2x2(const Source& source, ARGS&&... args) {
-        return Construct(source, ty.mat2x2<T>(), std::forward<ARGS>(args)...);
+        return Call(source, ty.mat2x2<T>(), std::forward<ARGS>(args)...);
     }
 
     /// @param args the arguments for the matrix initializer
@@ -1545,7 +1533,7 @@
     /// `T`, constructed with the values `args`.
     template <typename T, typename... ARGS, typename _ = DisableIfSource<ARGS...>>
     const ast::CallExpression* mat2x3(ARGS&&... args) {
-        return Construct(ty.mat2x3<T>(), std::forward<ARGS>(args)...);
+        return Call(ty.mat2x3<T>(), std::forward<ARGS>(args)...);
     }
 
     /// @param source the matrix source
@@ -1554,7 +1542,7 @@
     /// `T`, constructed with the values `args`.
     template <typename T, typename... ARGS>
     const ast::CallExpression* mat2x3(const Source& source, ARGS&&... args) {
-        return Construct(source, ty.mat2x3<T>(), std::forward<ARGS>(args)...);
+        return Call(source, ty.mat2x3<T>(), std::forward<ARGS>(args)...);
     }
 
     /// @param args the arguments for the matrix initializer
@@ -1562,7 +1550,7 @@
     /// `T`, constructed with the values `args`.
     template <typename T, typename... ARGS, typename _ = DisableIfSource<ARGS...>>
     const ast::CallExpression* mat2x4(ARGS&&... args) {
-        return Construct(ty.mat2x4<T>(), std::forward<ARGS>(args)...);
+        return Call(ty.mat2x4<T>(), std::forward<ARGS>(args)...);
     }
 
     /// @param source the matrix source
@@ -1571,7 +1559,7 @@
     /// `T`, constructed with the values `args`.
     template <typename T, typename... ARGS>
     const ast::CallExpression* mat2x4(const Source& source, ARGS&&... args) {
-        return Construct(source, ty.mat2x4<T>(), std::forward<ARGS>(args)...);
+        return Call(source, ty.mat2x4<T>(), std::forward<ARGS>(args)...);
     }
 
     /// @param args the arguments for the matrix initializer
@@ -1579,7 +1567,7 @@
     /// `T`, constructed with the values `args`.
     template <typename T, typename... ARGS, typename _ = DisableIfSource<ARGS...>>
     const ast::CallExpression* mat3x2(ARGS&&... args) {
-        return Construct(ty.mat3x2<T>(), std::forward<ARGS>(args)...);
+        return Call(ty.mat3x2<T>(), std::forward<ARGS>(args)...);
     }
 
     /// @param source the matrix source
@@ -1588,7 +1576,7 @@
     /// `T`, constructed with the values `args`.
     template <typename T, typename... ARGS>
     const ast::CallExpression* mat3x2(const Source& source, ARGS&&... args) {
-        return Construct(source, ty.mat3x2<T>(), std::forward<ARGS>(args)...);
+        return Call(source, ty.mat3x2<T>(), std::forward<ARGS>(args)...);
     }
 
     /// @param args the arguments for the matrix initializer
@@ -1596,7 +1584,7 @@
     /// `T`, constructed with the values `args`.
     template <typename T, typename... ARGS, typename _ = DisableIfSource<ARGS...>>
     const ast::CallExpression* mat3x3(ARGS&&... args) {
-        return Construct(ty.mat3x3<T>(), std::forward<ARGS>(args)...);
+        return Call(ty.mat3x3<T>(), std::forward<ARGS>(args)...);
     }
 
     /// @param source the matrix source
@@ -1605,7 +1593,7 @@
     /// `T`, constructed with the values `args`.
     template <typename T, typename... ARGS>
     const ast::CallExpression* mat3x3(const Source& source, ARGS&&... args) {
-        return Construct(source, ty.mat3x3<T>(), std::forward<ARGS>(args)...);
+        return Call(source, ty.mat3x3<T>(), std::forward<ARGS>(args)...);
     }
 
     /// @param args the arguments for the matrix initializer
@@ -1613,7 +1601,7 @@
     /// `T`, constructed with the values `args`.
     template <typename T, typename... ARGS, typename _ = DisableIfSource<ARGS...>>
     const ast::CallExpression* mat3x4(ARGS&&... args) {
-        return Construct(ty.mat3x4<T>(), std::forward<ARGS>(args)...);
+        return Call(ty.mat3x4<T>(), std::forward<ARGS>(args)...);
     }
 
     /// @param source the matrix source
@@ -1622,7 +1610,7 @@
     /// `T`, constructed with the values `args`.
     template <typename T, typename... ARGS>
     const ast::CallExpression* mat3x4(const Source& source, ARGS&&... args) {
-        return Construct(source, ty.mat3x4<T>(), std::forward<ARGS>(args)...);
+        return Call(source, ty.mat3x4<T>(), std::forward<ARGS>(args)...);
     }
 
     /// @param args the arguments for the matrix initializer
@@ -1630,7 +1618,7 @@
     /// `T`, constructed with the values `args`.
     template <typename T, typename... ARGS, typename _ = DisableIfSource<ARGS...>>
     const ast::CallExpression* mat4x2(ARGS&&... args) {
-        return Construct(ty.mat4x2<T>(), std::forward<ARGS>(args)...);
+        return Call(ty.mat4x2<T>(), std::forward<ARGS>(args)...);
     }
 
     /// @param source the matrix source
@@ -1639,7 +1627,7 @@
     /// `T`, constructed with the values `args`.
     template <typename T, typename... ARGS>
     const ast::CallExpression* mat4x2(const Source& source, ARGS&&... args) {
-        return Construct(source, ty.mat4x2<T>(), std::forward<ARGS>(args)...);
+        return Call(source, ty.mat4x2<T>(), std::forward<ARGS>(args)...);
     }
 
     /// @param args the arguments for the matrix initializer
@@ -1647,7 +1635,7 @@
     /// `T`, constructed with the values `args`.
     template <typename T, typename... ARGS, typename _ = DisableIfSource<ARGS...>>
     const ast::CallExpression* mat4x3(ARGS&&... args) {
-        return Construct(ty.mat4x3<T>(), std::forward<ARGS>(args)...);
+        return Call(ty.mat4x3<T>(), std::forward<ARGS>(args)...);
     }
 
     /// @param source the matrix source
@@ -1656,7 +1644,7 @@
     /// `T`, constructed with the values `args`.
     template <typename T, typename... ARGS>
     const ast::CallExpression* mat4x3(const Source& source, ARGS&&... args) {
-        return Construct(source, ty.mat4x3<T>(), std::forward<ARGS>(args)...);
+        return Call(source, ty.mat4x3<T>(), std::forward<ARGS>(args)...);
     }
 
     /// @param args the arguments for the matrix initializer
@@ -1664,7 +1652,7 @@
     /// `T`, constructed with the values `args`.
     template <typename T, typename... ARGS, typename _ = DisableIfSource<ARGS...>>
     const ast::CallExpression* mat4x4(ARGS&&... args) {
-        return Construct(ty.mat4x4<T>(), std::forward<ARGS>(args)...);
+        return Call(ty.mat4x4<T>(), std::forward<ARGS>(args)...);
     }
 
     /// @param source the matrix source
@@ -1673,7 +1661,7 @@
     /// `T`, constructed with the values `args`.
     template <typename T, typename... ARGS>
     const ast::CallExpression* mat4x4(const Source& source, ARGS&&... args) {
-        return Construct(source, ty.mat4x4<T>(), std::forward<ARGS>(args)...);
+        return Call(source, ty.mat4x4<T>(), std::forward<ARGS>(args)...);
     }
 
     /// @param args the arguments for the array initializer
@@ -1681,7 +1669,7 @@
     /// `T` and size `N`, constructed with the values `args`.
     template <typename T, int N, typename... ARGS>
     const ast::CallExpression* array(ARGS&&... args) {
-        return Construct(ty.array<T, N>(), std::forward<ARGS>(args)...);
+        return Call(ty.array<T, N>(), std::forward<ARGS>(args)...);
     }
 
     /// @param source the array source
@@ -1690,7 +1678,7 @@
     /// `T` and size `N`, constructed with the values `args`.
     template <typename T, int N, typename... ARGS>
     const ast::CallExpression* array(const Source& source, ARGS&&... args) {
-        return Construct(source, ty.array<T, N>(), std::forward<ARGS>(args)...);
+        return Call(source, ty.array<T, N>(), std::forward<ARGS>(args)...);
     }
 
     /// @param subtype the array element type
@@ -1700,7 +1688,7 @@
     /// `subtype`, constructed with the values `args`.
     template <typename EXPR, typename... ARGS>
     const ast::CallExpression* array(const ast::Type* subtype, EXPR&& n, ARGS&&... args) {
-        return Construct(ty.array(subtype, std::forward<EXPR>(n)), std::forward<ARGS>(args)...);
+        return Call(ty.array(subtype, std::forward<EXPR>(n)), std::forward<ARGS>(args)...);
     }
 
     /// @param source the array source
@@ -1714,8 +1702,7 @@
                                      const ast::Type* subtype,
                                      EXPR&& n,
                                      ARGS&&... args) {
-        return Construct(source, ty.array(subtype, std::forward<EXPR>(n)),
-                         std::forward<ARGS>(args)...);
+        return Call(source, ty.array(subtype, std::forward<EXPR>(n)), std::forward<ARGS>(args)...);
     }
 
     /// Adds the extension to the list of enable directives at the top of the module.
@@ -2073,24 +2060,41 @@
                                               Expr(std::forward<EXPR>(expr)));
     }
 
-    /// @param source the source information
-    /// @param func the function name
+    /// @param target the call target
     /// @param args the function call arguments
     /// @returns a `ast::CallExpression` to the function `func`, with the
     /// arguments of `args` converted to `ast::Expression`s using `Expr()`.
-    template <typename NAME, typename... ARGS>
-    const ast::CallExpression* Call(const Source& source, NAME&& func, ARGS&&... args) {
-        return create<ast::CallExpression>(source, Ident(func),
-                                           ExprList(std::forward<ARGS>(args)...));
+    template <typename TARGET,
+              typename... ARGS,
+              typename = DisableIfSource<TARGET>,
+              typename = DisableIfScalar<TARGET>>
+    const ast::CallExpression* Call(TARGET&& target, ARGS&&... args) {
+        return Call(source_, std::forward<TARGET>(target), std::forward<ARGS>(args)...);
     }
 
-    /// @param func the function name
+    /// @param source the source information
+    /// @param target the call target. Can be an ast::Type or ast::Identifier, or string-like.
     /// @param args the function call arguments
-    /// @returns a `ast::CallExpression` to the function `func`, with the
-    /// arguments of `args` converted to `ast::Expression`s using `Expr()`.
-    template <typename NAME, typename... ARGS, typename = DisableIfSource<NAME>>
-    const ast::CallExpression* Call(NAME&& func, ARGS&&... args) {
-        return create<ast::CallExpression>(Ident(func), ExprList(std::forward<ARGS>(args)...));
+    /// @returns a `ast::CallExpression` to the target @p target, with the arguments of @p args
+    /// converted to `ast::Expression`s using Expr().
+    template <typename TARGET, typename... ARGS, typename = DisableIfScalar<TARGET>>
+    const ast::CallExpression* Call(const Source& source, TARGET&& target, ARGS&&... args) {
+        if constexpr (traits::IsTypeOrDerived<traits::PtrElTy<TARGET>, ast::Type>) {
+            return create<ast::CallExpression>(source, target,
+                                               ExprList(std::forward<ARGS>(args)...));
+
+        } else {
+            return create<ast::CallExpression>(source, Ident(target),
+                                               ExprList(std::forward<ARGS>(args)...));
+        }
+    }
+
+    /// @param args the arguments for the type constructor
+    /// @return an `ast::CallExpression` of type `ty`, with the values
+    /// of `args` converted to `ast::Expression`s using `Expr()`
+    template <typename T, typename... ARGS, typename = DisableIfSource<ARGS...>>
+    const ast::CallExpression* Call(ARGS&&... args) {
+        return Call(ty.Of<T>(), std::forward<ARGS>(args)...);
     }
 
     /// @param source the source information
diff --git a/src/tint/reader/spirv/function.cc b/src/tint/reader/spirv/function.cc
index 141687c..1606b84 100644
--- a/src/tint/reader/spirv/function.cc
+++ b/src/tint/reader/spirv/function.cc
@@ -1393,7 +1393,7 @@
 
             // Add the return-value statement.
             stmts.Push(create<ast::ReturnStatement>(
-                source, builder_.Construct(source, return_type, std::move(return_exprs))));
+                source, builder_.Call(source, return_type, std::move(return_exprs))));
         }
     }
 
@@ -3912,8 +3912,7 @@
             }
             operands.Push(operand.expr);
         }
-        return {ast_type,
-                builder_.Construct(Source{}, ast_type->Build(builder_), std::move(operands))};
+        return {ast_type, builder_.Call(Source{}, ast_type->Build(builder_), std::move(operands))};
     }
 
     if (op == spv::Op::OpCompositeExtract) {
@@ -4731,8 +4730,7 @@
             return {};
         }
     }
-    return {result_type,
-            builder_.Construct(source, result_type->Build(builder_), std::move(values))};
+    return {result_type, builder_.Call(source, result_type->Build(builder_), std::move(values))};
 }
 
 bool FunctionEmitter::RegisterSpecialBuiltInVariables() {
@@ -5164,9 +5162,8 @@
 
     ExpressionList params;
     params.Push(arg_expr.expr);
-    TypedExpression result{
-        expr_type,
-        builder_.Construct(GetSourceForInst(inst), expr_type->Build(builder_), std::move(params))};
+    TypedExpression result{expr_type, builder_.Call(GetSourceForInst(inst),
+                                                    expr_type->Build(builder_), std::move(params))};
 
     if (requested_type == expr_type) {
         return result;
@@ -5640,14 +5637,14 @@
         // first component.
         if (texture_type->IsAnyOf<DepthTexture, DepthMultisampledTexture>()) {
             if (is_non_dref_sample || (op == spv::Op::OpImageFetch)) {
-                value = builder_.Construct(Source{},
-                                           result_type->Build(builder_),  // a vec4
-                                           utils::Vector{
-                                               value,
-                                               parser_impl_.MakeNullValue(result_component_type),
-                                               parser_impl_.MakeNullValue(result_component_type),
-                                               parser_impl_.MakeNullValue(result_component_type),
-                                           });
+                value = builder_.Call(Source{},
+                                      result_type->Build(builder_),  // a vec4
+                                      utils::Vector{
+                                          value,
+                                          parser_impl_.MakeNullValue(result_component_type),
+                                          parser_impl_.MakeNullValue(result_component_type),
+                                          parser_impl_.MakeNullValue(result_component_type),
+                                      });
             }
         }
 
@@ -5731,7 +5728,7 @@
                 // vector initializer - otherwise, just emit the single expression to omit an
                 // unnecessary cast.
                 (exprs.Length() > 1)
-                    ? builder_.Construct(Source{}, unsigned_type->Build(builder_), std::move(exprs))
+                    ? builder_.Call(Source{}, unsigned_type->Build(builder_), std::move(exprs))
                     : exprs[0],
             };
 
@@ -5753,8 +5750,8 @@
             // The WGSL bulitin returns u32.
             // If they aren't the same then convert the result.
             if (!result_type->Is<U32>()) {
-                ast_expr = builder_.Construct(Source{}, result_type->Build(builder_),
-                                              utils::Vector{ast_expr});
+                ast_expr =
+                    builder_.Call(Source{}, result_type->Build(builder_), utils::Vector{ast_expr});
             }
             TypedExpression expr{result_type, ast_expr};
             return EmitConstDefOrWriteToHoistedVar(inst, expr);
@@ -6066,7 +6063,7 @@
         for (auto i = src_count; i < dest_count; i++) {
             exprs.Push(parser_impl_.MakeNullExpression(component_type).expr);
         }
-        texel.expr = builder_.Construct(Source{}, src_type->Build(builder_), std::move(exprs));
+        texel.expr = builder_.Call(Source{}, src_type->Build(builder_), std::move(exprs));
     }
 
     return texel.expr;
@@ -6076,7 +6073,7 @@
     if (!value || value.type->Is<I32>()) {
         return value;
     }
-    return {ty_.I32(), builder_.Construct(Source{}, builder_.ty.i32(), utils::Vector{value.expr})};
+    return {ty_.I32(), builder_.Call(Source{}, builder_.ty.i32(), utils::Vector{value.expr})};
 }
 
 TypedExpression FunctionEmitter::ToSignedIfUnsigned(TypedExpression value) {
@@ -6085,7 +6082,7 @@
     }
     if (auto* vec_type = value.type->As<Vector>()) {
         auto* new_type = ty_.Vector(ty_.I32(), vec_type->size);
-        return {new_type, builder_.Construct(new_type->Build(builder_), utils::Vector{value.expr})};
+        return {new_type, builder_.Call(new_type->Build(builder_), utils::Vector{value.expr})};
     }
     return ToI32(value);
 }
@@ -6157,10 +6154,10 @@
             result_row.Push(elem);
         }
         result_columns.Push(
-            builder_.Construct(Source{}, col_ty->Build(builder_), std::move(result_row)));
+            builder_.Call(Source{}, col_ty->Build(builder_), std::move(result_row)));
     }
     return {result_ty,
-            builder_.Construct(Source{}, result_ty->Build(builder_), std::move(result_columns))};
+            builder_.Call(Source{}, result_ty->Build(builder_), std::move(result_columns))};
 }
 
 bool FunctionEmitter::MakeVectorInsertDynamic(const spvtools::opt::Instruction& inst) {
diff --git a/src/tint/reader/spirv/parser_impl.cc b/src/tint/reader/spirv/parser_impl.cc
index 15af5b5..4f75a63 100644
--- a/src/tint/reader/spirv/parser_impl.cc
+++ b/src/tint/reader/spirv/parser_impl.cc
@@ -1860,8 +1860,8 @@
         auto y = MakeConstantExpression(workgroup_size_builtin_.y_id);
         auto z = MakeConstantExpression(workgroup_size_builtin_.z_id);
         auto* ast_type = ty_.Vector(x.type, 3);
-        return {ast_type, builder_.Construct(Source{}, ast_type->Build(builder_),
-                                             utils::Vector{x.expr, y.expr, z.expr})};
+        return {ast_type, builder_.Call(Source{}, ast_type->Build(builder_),
+                                        utils::Vector{x.expr, y.expr, z.expr})};
     } else if (id == workgroup_size_builtin_.x_id) {
         return MakeConstantExpressionForScalarSpirvConstant(
             Source{}, ConvertType(workgroup_size_builtin_.component_type_id),
@@ -1930,9 +1930,8 @@
                 // We've already emitted a diagnostic.
                 return {};
             }
-            return {original_ast_type,
-                    builder_.Construct(source, original_ast_type->Build(builder_),
-                                       std::move(ast_components))};
+            return {original_ast_type, builder_.Call(source, original_ast_type->Build(builder_),
+                                                     std::move(ast_components))};
         }
         default:
             break;
@@ -1957,11 +1956,10 @@
             const auto value = spirv_const->GetS32();
             if (value == std::numeric_limits<int32_t>::min()) {
                 // Avoid overflowing i-suffixed literal.
-                return {ty_.I32(),
-                        builder_.Construct(
-                            source, builder_.ty.i32(),
-                            create<ast::IntLiteralExpression>(
-                                source, value, ast::IntLiteralExpression::Suffix::kNone))};
+                return {ty_.I32(), builder_.Call(source, builder_.ty.i32(),
+                                                 create<ast::IntLiteralExpression>(
+                                                     source, value,
+                                                     ast::IntLiteralExpression::Suffix::kNone))};
             } else {
                 return {ty_.I32(),
                         create<ast::IntLiteralExpression>(source, static_cast<int64_t>(value),
@@ -2024,17 +2022,17 @@
             return create<ast::FloatLiteralExpression>(Source{}, 0,
                                                        ast::FloatLiteralExpression::Suffix::kF);
         },
-        [&](const Vector*) { return builder_.Construct(Source{}, type->Build(builder_)); },
-        [&](const Matrix*) { return builder_.Construct(Source{}, type->Build(builder_)); },
-        [&](const Array*) { return builder_.Construct(Source{}, type->Build(builder_)); },
+        [&](const Vector*) { return builder_.Call(Source{}, type->Build(builder_)); },
+        [&](const Matrix*) { return builder_.Call(Source{}, type->Build(builder_)); },
+        [&](const Array*) { return builder_.Call(Source{}, type->Build(builder_)); },
         [&](const Bool*) { return create<ast::BoolLiteralExpression>(Source{}, false); },
         [&](const Struct* struct_ty) {
             ExpressionList ast_components;
             for (auto* member : struct_ty->members) {
                 ast_components.Push(MakeNullValue(member));
             }
-            return builder_.Construct(Source{}, original_type->Build(builder_),
-                                      std::move(ast_components));
+            return builder_.Call(Source{}, original_type->Build(builder_),
+                                 std::move(ast_components));
         },
         [&](Default) {
             Fail() << "can't make null value for type: " << type->TypeInfo().name;
diff --git a/src/tint/reader/wgsl/parser_impl.cc b/src/tint/reader/wgsl/parser_impl.cc
index 470511d..458c56f 100644
--- a/src/tint/reader/wgsl/parser_impl.cc
+++ b/src/tint/reader/wgsl/parser_impl.cc
@@ -2622,7 +2622,7 @@
             return Failure::kErrored;
         }
 
-        return builder_.Construct(t.source(), call.value, std::move(params.value));
+        return builder_.Call(t.source(), call.value, std::move(params.value));
     }
 
     auto lit = const_literal();
diff --git a/src/tint/resolver/alias_analysis_test.cc b/src/tint/resolver/alias_analysis_test.cc
index 12cfc58..acac18d 100644
--- a/src/tint/resolver/alias_analysis_test.cc
+++ b/src/tint/resolver/alias_analysis_test.cc
@@ -570,7 +570,7 @@
 
 TEST_P(Use, Read_Convert) {
     // _ = f32(*p2);
-    Run(Assign(Phony(), Construct<f32>(Deref("p2"))),
+    Run(Assign(Phony(), Call<f32>(Deref("p2"))),
         R"(56:78 warning: invalid aliased pointer argument
 12:34 note: aliases with another argument passed here)");
 }
@@ -759,7 +759,7 @@
          ty.void_(),
          utils::Vector{
              Assign(Phony(), MemberAccessor(Deref("p2"), "a")),
-             Assign(Deref("p1"), Construct(ty("S"))),
+             Assign(Deref("p1"), Call(ty("S"))),
          });
     Func("f1", utils::Empty, ty.void_(),
          utils::Vector{
@@ -822,7 +822,7 @@
          ty.void_(),
          utils::Vector{
              Assign(Phony(), MemberAccessor(Deref("p2"), "zy")),
-             Assign(Deref("p1"), Construct(ty.vec4<f32>())),
+             Assign(Deref("p1"), Call(ty.vec4<f32>())),
          });
     Func("f1", utils::Empty, ty.void_(),
          utils::Vector{
diff --git a/src/tint/resolver/array_accessor_test.cc b/src/tint/resolver/array_accessor_test.cc
index 255d109..fc7bdeb 100644
--- a/src/tint/resolver/array_accessor_test.cc
+++ b/src/tint/resolver/array_accessor_test.cc
@@ -37,7 +37,7 @@
 
 TEST_F(ResolverIndexAccessorTest, Matrix_Dynamic_Ref) {
     GlobalVar("my_var", ty.mat2x3<f32>(), type::AddressSpace::kPrivate);
-    auto* idx = Var("idx", ty.i32(), Construct(ty.i32()));
+    auto* idx = Var("idx", ty.i32(), Call<i32>());
     auto* acc = IndexAccessor("my_var", idx);
     WrapInFunction(Decl(idx), acc);
 
@@ -65,8 +65,8 @@
 }
 
 TEST_F(ResolverIndexAccessorTest, Matrix_Dynamic) {
-    GlobalConst("my_const", ty.mat2x3<f32>(), Construct(ty.mat2x3<f32>()));
-    auto* idx = Var("idx", ty.i32(), Construct(ty.i32()));
+    GlobalConst("my_const", ty.mat2x3<f32>(), Call(ty.mat2x3<f32>()));
+    auto* idx = Var("idx", ty.i32(), Call<i32>());
     auto* acc = IndexAccessor("my_const", Expr(Source{{12, 34}}, idx));
     WrapInFunction(Decl(idx), acc);
 
@@ -80,7 +80,7 @@
 }
 
 TEST_F(ResolverIndexAccessorTest, Matrix_XDimension_Dynamic) {
-    GlobalConst("my_const", ty.mat4x4<f32>(), Construct(ty.mat4x4<f32>()));
+    GlobalConst("my_const", ty.mat4x4<f32>(), Call(ty.mat4x4<f32>()));
     auto* idx = Var("idx", ty.u32(), Expr(3_u));
     auto* acc = IndexAccessor("my_const", Expr(Source{{12, 34}}, idx));
     WrapInFunction(Decl(idx), acc);
@@ -90,7 +90,7 @@
 }
 
 TEST_F(ResolverIndexAccessorTest, Matrix_BothDimension_Dynamic) {
-    GlobalConst("my_const", ty.mat4x4<f32>(), Construct(ty.mat4x4<f32>()));
+    GlobalConst("my_const", ty.mat4x4<f32>(), Call(ty.mat4x4<f32>()));
     auto* idx = Var("idy", ty.u32(), Expr(2_u));
     auto* acc = IndexAccessor(IndexAccessor("my_const", Expr(Source{{12, 34}}, idx)), 1_i);
     WrapInFunction(Decl(idx), acc);
@@ -158,7 +158,7 @@
 }
 
 TEST_F(ResolverIndexAccessorTest, Vector_Dynamic) {
-    GlobalConst("my_const", ty.vec3<f32>(), Construct(ty.vec3<f32>()));
+    GlobalConst("my_const", ty.vec3<f32>(), Call(ty.vec3<f32>()));
     auto* idx = Var("idx", ty.i32(), Expr(2_i));
     auto* acc = IndexAccessor("my_const", Expr(Source{{12, 34}}, idx));
     WrapInFunction(Decl(idx), acc);
@@ -258,7 +258,7 @@
     // var idx : i32 = 0;
     // var f : f32 = a[idx];
     auto* a = Let("a", ty.array<f32, 3>(), array<f32, 3>());
-    auto* idx = Var("idx", ty.i32(), Construct(ty.i32()));
+    auto* idx = Var("idx", ty.i32(), Call<i32>());
     auto* acc = IndexAccessor("a", Expr(Source{{12, 34}}, idx));
     auto* f = Var("f", ty.f32(), acc);
     Func("my_func", utils::Empty, ty.void_(),
@@ -317,7 +317,7 @@
     //     return x;
     // }
     auto* p = Param("p", ty.pointer(ty.vec4<f32>(), type::AddressSpace::kFunction));
-    auto* idx = Let("idx", ty.u32(), Construct(ty.u32()));
+    auto* idx = Let("idx", ty.u32(), Call<u32>());
     auto* star_p = Deref(p);
     auto* acc = IndexAccessor(Source{{12, 34}}, star_p, idx);
     auto* x = Var("x", ty.f32(), acc);
@@ -338,7 +338,7 @@
     //     return x;
     // }
     auto* p = Param("p", ty.pointer(ty.vec4<f32>(), type::AddressSpace::kFunction));
-    auto* idx = Let("idx", ty.u32(), Construct(ty.u32()));
+    auto* idx = Let("idx", ty.u32(), Call<u32>());
     auto* accessor_expr = IndexAccessor(Source{{12, 34}}, p, idx);
     auto* star_p = Deref(accessor_expr);
     auto* x = Var("x", ty.f32(), star_p);
@@ -353,7 +353,7 @@
     // var param: vec4<f32>
     // let x: f32 = *(&param)[0];
     auto* param = Var("param", ty.vec4<f32>());
-    auto* idx = Var("idx", ty.u32(), Construct(ty.u32()));
+    auto* idx = Var("idx", ty.u32(), Call<u32>());
     auto* addressOf_expr = AddressOf(param);
     auto* accessor_expr = IndexAccessor(Source{{12, 34}}, addressOf_expr, idx);
     auto* star_p = Deref(accessor_expr);
diff --git a/src/tint/resolver/attribute_validation_test.cc b/src/tint/resolver/attribute_validation_test.cc
index d5c3e0e..43ccf0e 100644
--- a/src/tint/resolver/attribute_validation_test.cc
+++ b/src/tint/resolver/attribute_validation_test.cc
@@ -300,7 +300,7 @@
     auto* p = Param("a", ty.vec4<f32>(), attrs);
     Func("vertex_main", utils::Vector{p}, ty.vec4<f32>(),
          utils::Vector{
-             Return(Construct(ty.vec4<f32>())),
+             Return(Call(ty.vec4<f32>())),
          },
          utils::Vector{
              Stage(ast::PipelineStage::kVertex),
@@ -349,7 +349,7 @@
     auto& params = GetParam();
     Func("main", utils::Empty, ty.vec4<f32>(),
          utils::Vector{
-             Return(Construct(ty.vec4<f32>(), 1_f)),
+             Return(Call(ty.vec4<f32>(), 1_f)),
          },
          utils::Vector{
              Stage(ast::PipelineStage::kCompute),
@@ -400,8 +400,7 @@
     auto& params = GetParam();
     auto attrs = createAttributes(Source{{12, 34}}, *this, params.kind);
     attrs.Push(Location(Source{{34, 56}}, 2_a));
-    Func("frag_main", utils::Empty, ty.vec4<f32>(),
-         utils::Vector{Return(Construct(ty.vec4<f32>()))},
+    Func("frag_main", utils::Empty, ty.vec4<f32>(), utils::Vector{Return(Call(ty.vec4<f32>()))},
          utils::Vector{
              Stage(ast::PipelineStage::kFragment),
          },
@@ -458,7 +457,7 @@
     }
     Func("vertex_main", utils::Empty, ty.vec4<f32>(),
          utils::Vector{
-             Return(Construct(ty.vec4<f32>())),
+             Return(Call(ty.vec4<f32>())),
          },
          utils::Vector{
              Stage(ast::PipelineStage::kVertex),
@@ -1383,7 +1382,7 @@
                         });
     Func("main", utils::Vector{param}, ty.vec4<f32>(),
          utils::Vector{
-             Return(Construct(ty.vec4<f32>())),
+             Return(Call(ty.vec4<f32>())),
          },
          utils::Vector{
              Stage(ast::PipelineStage::kFragment),
@@ -1402,7 +1401,7 @@
                         });
     Func("main", utils::Vector{param}, ty.vec4<f32>(),
          utils::Vector{
-             Return(Construct(ty.vec4<f32>())),
+             Return(Call(ty.vec4<f32>())),
          },
          utils::Vector{
              Stage(ast::PipelineStage::kFragment),
@@ -1629,7 +1628,7 @@
         });
     Func("main", utils::Empty, ty.Of(s),
          utils::Vector{
-             Return(Construct(ty.Of(s))),
+             Return(Call(ty.Of(s))),
          },
          utils::Vector{
              Stage(ast::PipelineStage::kVertex),
@@ -1665,7 +1664,7 @@
 TEST_F(InterpolateTest, MissingLocationAttribute_ReturnType) {
     Func("main", utils::Empty, ty.vec4<f32>(),
          utils::Vector{
-             Return(Construct(ty.vec4<f32>())),
+             Return(Call(ty.vec4<f32>())),
          },
          utils::Vector{
              Stage(ast::PipelineStage::kVertex),
@@ -1725,7 +1724,7 @@
 
 TEST_F(GroupAndBindingTest, Binding_NonConstant) {
     GlobalVar("val", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()),
-              Binding(Construct(ty.u32(), Call(Source{{12, 34}}, "dpdx", 1_a))), Group(1_i));
+              Binding(Call<u32>(Call(Source{{12, 34}}, "dpdx", 1_a))), Group(1_i));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -1759,7 +1758,7 @@
 
 TEST_F(GroupAndBindingTest, Group_NonConstant) {
     GlobalVar("val", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()), Binding(2_u),
-              Group(Construct(ty.u32(), Call(Source{{12, 34}}, "dpdx", 1_a))));
+              Group(Call<u32>(Call(Source{{12, 34}}, "dpdx", 1_a))));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -1809,8 +1808,7 @@
 }
 
 TEST_F(IdTest, NonConstant) {
-    Override("val", ty.f32(),
-             utils::Vector{Id(Construct(ty.u32(), Call(Source{{12, 34}}, "dpdx", 1_a)))});
+    Override("val", ty.f32(), utils::Vector{Id(Call<u32>(Call(Source{{12, 34}}, "dpdx", 1_a)))});
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(
         r()->error(),
@@ -1896,7 +1894,7 @@
 }
 
 TEST_P(LocationTest, NonConstant) {
-    Build(Construct(ty.u32(), Call(Source{{12, 34}}, "dpdx", 1_a)));
+    Build(Call<u32>(Call(Source{{12, 34}}, "dpdx", 1_a)));
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(
         r()->error(),
diff --git a/src/tint/resolver/builtin_validation_test.cc b/src/tint/resolver/builtin_validation_test.cc
index c9037ba..4f5c94f 100644
--- a/src/tint/resolver/builtin_validation_test.cc
+++ b/src/tint/resolver/builtin_validation_test.cc
@@ -123,7 +123,7 @@
          utils::Vector{
              Return(1_i),
          });
-    WrapInFunction(Construct(ty(Source{{56, 78}}, "mix")));
+    WrapInFunction(Call(ty(Source{{56, 78}}, "mix")));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), R"(56:78 error: cannot use function 'mix' as type
@@ -152,7 +152,7 @@
 
 TEST_F(ResolverBuiltinValidationTest, BuiltinRedeclaredAsGlobalConstUsedAsType) {
     GlobalConst(Source{{12, 34}}, "mix", ty.i32(), Expr(1_i));
-    WrapInFunction(Construct(ty(Source{{56, 78}}, "mix")));
+    WrapInFunction(Call(ty(Source{{56, 78}}, "mix")));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), R"(56:78 error: cannot use variable 'mix' as type
@@ -182,7 +182,7 @@
 
 TEST_F(ResolverBuiltinValidationTest, BuiltinRedeclaredAsGlobalVarUsedAsType) {
     GlobalVar(Source{{12, 34}}, "mix", ty.i32(), Expr(1_i), type::AddressSpace::kPrivate);
-    WrapInFunction(Construct(ty(Source{{56, 78}}, "mix")));
+    WrapInFunction(Call(ty(Source{{56, 78}}, "mix")));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), R"(56:78 error: cannot use variable 'mix' as type
@@ -215,7 +215,7 @@
 
 TEST_F(ResolverBuiltinValidationTest, BuiltinRedeclaredAsAliasUsedAsType) {
     auto* mix = Alias(Source{{12, 34}}, "mix", ty.i32());
-    auto* use = Construct(ty("mix"));
+    auto* use = Call(ty("mix"));
     WrapInFunction(use);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -249,7 +249,7 @@
     auto* mix = Structure("mix", utils::Vector{
                                      Member("m", ty.i32()),
                                  });
-    auto* use = Construct(ty("mix"));
+    auto* use = Call(ty("mix"));
     WrapInFunction(use);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -308,20 +308,20 @@
             case Kind::kScalar:
                 return b.Expr(src, i32(values[0]));
             case Kind::kVec2:
-                return b.Construct(src, b.ty.vec2<i32>(), i32(values[0]), i32(values[1]));
+                return b.Call(src, b.ty.vec2<i32>(), i32(values[0]), i32(values[1]));
             case Kind::kVec3:
-                return b.Construct(src, b.ty.vec3<i32>(), i32(values[0]), i32(values[1]),
-                                   i32(values[2]));
+                return b.Call(src, b.ty.vec3<i32>(), i32(values[0]), i32(values[1]),
+                              i32(values[2]));
             case Kind::kVec3_Scalar_Vec2:
-                return b.Construct(src, b.ty.vec3<i32>(), i32(values[0]),
-                                   b.vec2<i32>(i32(values[1]), i32(values[2])));
+                return b.Call(src, b.ty.vec3<i32>(), i32(values[0]),
+                              b.vec2<i32>(i32(values[1]), i32(values[2])));
             case Kind::kVec3_Vec2_Scalar:
-                return b.Construct(src, b.ty.vec3<i32>(),
-                                   b.vec2<i32>(i32(values[0]), i32(values[1])), i32(values[2]));
+                return b.Call(src, b.ty.vec3<i32>(), b.vec2<i32>(i32(values[0]), i32(values[1])),
+                              i32(values[2]));
             case Kind::kEmptyVec2:
-                return b.Construct(src, b.ty.vec2<i32>());
+                return b.Call(src, b.ty.vec2<i32>());
             case Kind::kEmptyVec3:
-                return b.Construct(src, b.ty.vec3<i32>());
+                return b.Call(src, b.ty.vec3<i32>());
         }
         return nullptr;
     }
diff --git a/src/tint/resolver/builtins_validation_test.cc b/src/tint/resolver/builtins_validation_test.cc
index abdd1a9..69ab01b 100644
--- a/src/tint/resolver/builtins_validation_test.cc
+++ b/src/tint/resolver/builtins_validation_test.cc
@@ -1229,7 +1229,7 @@
 
     utils::Vector<const ast::Expression*, 8> params;
     for (uint32_t i = 0; i < num_params; ++i) {
-        params.Push(Construct<u32>(1_i));
+        params.Push(Call<u32>(1_i));
     }
     auto* builtin = Call(name, params);
     WrapInFunction(builtin);
@@ -1289,7 +1289,7 @@
 
     utils::Vector<const ast::Expression*, 8> params;
     for (uint32_t i = 0; i < num_params; ++i) {
-        params.Push(Construct<i32>(1_i));
+        params.Push(Call<i32>(1_i));
     }
     auto* builtin = Call(name, params);
     WrapInFunction(builtin);
diff --git a/src/tint/resolver/call_validation_test.cc b/src/tint/resolver/call_validation_test.cc
index 9e90cf8..e811377 100644
--- a/src/tint/resolver/call_validation_test.cc
+++ b/src/tint/resolver/call_validation_test.cc
@@ -193,7 +193,7 @@
     Func("foo", utils::Vector{param}, ty.void_(), utils::Empty);
     Func("main", utils::Empty, ty.void_(),
          utils::Vector{
-             Decl(Let("v", ty.Of(S), Construct(ty.Of(S)))),
+             Decl(Let("v", ty.Of(S), Call(ty.Of(S)))),
              CallStmt(Call("foo", AddressOf(MemberAccessor(Source{{12, 34}}, "v", "m")))),
          });
 
diff --git a/src/tint/resolver/const_eval_binary_op_test.cc b/src/tint/resolver/const_eval_binary_op_test.cc
index 10c047c..de3c407 100644
--- a/src/tint/resolver/const_eval_binary_op_test.cc
+++ b/src/tint/resolver/const_eval_binary_op_test.cc
@@ -1953,8 +1953,8 @@
     Structure("S", utils::Vector{Member("a", ty.i32()), Member("b", ty.f32())});
     GlobalConst("one", Expr(1_a));
     auto* lhs = Equal("one", 0_a);
-    auto* rhs = Equal(
-        MemberAccessor(Construct(ty("S"), Expr(1_a), Expr(Source{{12, 34}}, true)), "a"), 0_a);
+    auto* rhs =
+        Equal(MemberAccessor(Call(ty("S"), Expr(1_a), Expr(Source{{12, 34}}, true)), "a"), 0_a);
     GlobalConst("result", LogicalAnd(lhs, rhs));
 
     EXPECT_FALSE(r()->Resolve());
@@ -1973,8 +1973,8 @@
     Structure("S", utils::Vector{Member("a", ty.i32()), Member("b", ty.f32())});
     GlobalConst("one", Expr(1_a));
     auto* lhs = Equal("one", 1_a);
-    auto* rhs = Equal(
-        MemberAccessor(Construct(ty("S"), Expr(1_a), Expr(Source{{12, 34}}, true)), "a"), 0_a);
+    auto* rhs =
+        Equal(MemberAccessor(Call(ty("S"), Expr(1_a), Expr(Source{{12, 34}}, true)), "a"), 0_a);
     GlobalConst("result", LogicalOr(lhs, rhs));
 
     EXPECT_FALSE(r()->Resolve());
@@ -2146,7 +2146,7 @@
     // const one = 1;
     // const result = (one == 0) && (s.c == 0);
     Structure("S", utils::Vector{Member("a", ty.i32()), Member("b", ty.f32())});
-    GlobalConst("s", Construct(ty("S"), Expr(1_a), Expr(2.0_a)));
+    GlobalConst("s", Call(ty("S"), Expr(1_a), Expr(2.0_a)));
     GlobalConst("one", Expr(1_a));
     auto* lhs = Equal("one", 0_a);
     auto* rhs = Equal(MemberAccessor(Source{{12, 34}}, "s", "c"), 0_a);
@@ -2165,7 +2165,7 @@
     // const one = 1;
     // const result = (one == 1) || (s.c == 0);
     Structure("S", utils::Vector{Member("a", ty.i32()), Member("b", ty.f32())});
-    GlobalConst("s", Construct(ty("S"), Expr(1_a), Expr(2.0_a)));
+    GlobalConst("s", Call(ty("S"), Expr(1_a), Expr(2.0_a)));
     GlobalConst("one", Expr(1_a));
     auto* lhs = Equal("one", 1_a);
     auto* rhs = Equal(MemberAccessor(Source{{12, 34}}, "s", "c"), 0_a);
diff --git a/src/tint/resolver/const_eval_construction_test.cc b/src/tint/resolver/const_eval_construction_test.cc
index 96e37ca..80f0c11 100644
--- a/src/tint/resolver/const_eval_construction_test.cc
+++ b/src/tint/resolver/const_eval_construction_test.cc
@@ -149,7 +149,7 @@
     Enable(ast::Extension::kF16);
     auto& param = GetParam();
     auto* ty = param.type(*this);
-    auto* expr = Construct(ty);
+    auto* expr = Call(ty);
     auto* a = Const("a", expr);
     WrapInFunction(a);
 
@@ -1392,7 +1392,7 @@
 }
 
 TEST_F(ResolverConstEvalTest, Mat3x2_Construct_Scalars_af) {
-    auto* expr = Construct(ty.mat(nullptr, 3, 2), 1.0_a, 2.0_a, 3.0_a, 4.0_a, 5.0_a, 6.0_a);
+    auto* expr = Call(ty.mat(nullptr, 3, 2), 1.0_a, 2.0_a, 3.0_a, 4.0_a, 5.0_a, 6.0_a);
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1441,10 +1441,10 @@
 }
 
 TEST_F(ResolverConstEvalTest, Mat3x2_Construct_Columns_af) {
-    auto* expr = Construct(ty.mat(nullptr, 3, 2),           //
-                           vec(nullptr, 2u, 1.0_a, 2.0_a),  //
-                           vec(nullptr, 2u, 3.0_a, 4.0_a),  //
-                           vec(nullptr, 2u, 5.0_a, 6.0_a));
+    auto* expr = Call(ty.mat(nullptr, 3, 2),           //
+                      vec(nullptr, 2u, 1.0_a, 2.0_a),  //
+                      vec(nullptr, 2u, 3.0_a, 4.0_a),  //
+                      vec(nullptr, 2u, 5.0_a, 6.0_a));
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1493,7 +1493,7 @@
 }
 
 TEST_F(ResolverConstEvalTest, Array_i32_Zero) {
-    auto* expr = Construct(ty.array<i32, 4>());
+    auto* expr = Call(ty.array<i32, 4>());
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1530,7 +1530,7 @@
 }
 
 TEST_F(ResolverConstEvalTest, Array_f32_Zero) {
-    auto* expr = Construct(ty.array<f32, 4>());
+    auto* expr = Call(ty.array<f32, 4>());
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1567,7 +1567,7 @@
 }
 
 TEST_F(ResolverConstEvalTest, Array_vec3_f32_Zero) {
-    auto* expr = Construct(ty.array(ty.vec3<f32>(), 2_u));
+    auto* expr = Call(ty.array(ty.vec3<f32>(), 2_u));
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1618,7 +1618,7 @@
                        Member("m1", ty.f32()),
                        Member("m2", ty.f32()),
                    });
-    auto* expr = Construct(ty.array(ty("S"), 2_u));
+    auto* expr = Call(ty.array(ty("S"), 2_u));
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1655,7 +1655,7 @@
 }
 
 TEST_F(ResolverConstEvalTest, Array_i32_Elements) {
-    auto* expr = Construct(ty.array<i32, 4>(), 10_i, 20_i, 30_i, 40_i);
+    auto* expr = Call(ty.array<i32, 4>(), 10_i, 20_i, 30_i, 40_i);
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1748,10 +1748,10 @@
     auto inner_ty = [&] { return ty.array<f32, 2>(); };
     auto outer_ty = ty.array(inner_ty(), Expr(3_i));
 
-    auto* expr = Construct(outer_ty,                         //
-                           Construct(inner_ty(), 1_f, 2_f),  //
-                           Construct(inner_ty(), 3_f, 4_f),  //
-                           Construct(inner_ty(), 5_f, 6_f));
+    auto* expr = Call(outer_ty,                    //
+                      Call(inner_ty(), 1_f, 2_f),  //
+                      Call(inner_ty(), 3_f, 4_f),  //
+                      Call(inner_ty(), 5_f, 6_f));
 
     WrapInFunction(expr);
 
@@ -1788,7 +1788,7 @@
 }
 
 TEST_F(ResolverConstEvalTest, Array_f32_Elements) {
-    auto* expr = Construct(ty.array<f32, 4>(), 10_f, 20_f, 30_f, 40_f);
+    auto* expr = Call(ty.array<f32, 4>(), 10_f, 20_f, 30_f, 40_f);
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1825,8 +1825,8 @@
 }
 
 TEST_F(ResolverConstEvalTest, Array_vec3_f32_Elements) {
-    auto* expr = Construct(ty.array(ty.vec3<f32>(), 2_u),  //
-                           vec3<f32>(1_f, 2_f, 3_f), vec3<f32>(4_f, 5_f, 6_f));
+    auto* expr = Call(ty.array(ty.vec3<f32>(), 2_u),  //
+                      vec3<f32>(1_f, 2_f, 3_f), vec3<f32>(4_f, 5_f, 6_f));
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1853,9 +1853,9 @@
                        Member("m1", ty.f32()),
                        Member("m2", ty.f32()),
                    });
-    auto* expr = Construct(ty.array(ty("S"), 2_u),        //
-                           Construct(ty("S"), 1_f, 2_f),  //
-                           Construct(ty("S"), 3_f, 4_f));
+    auto* expr = Call(ty.array(ty("S"), 2_u),   //
+                      Call(ty("S"), 1_f, 2_f),  //
+                      Call(ty("S"), 3_f, 4_f));
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1901,7 +1901,7 @@
                                  Member("e", ty.bool_()),
                              });
 
-    auto* expr = Construct(ty.Of(s));
+    auto* expr = Call(ty.Of(s));
     auto* a = Const("a", expr);
     WrapInFunction(a);
 
@@ -1950,7 +1950,7 @@
                             Member("inner", ty.Of(inner)),
                         });
 
-    auto* expr = Construct(ty.Of(s));
+    auto* expr = Call(ty.Of(s));
     auto* a = Const("a", expr);
     WrapInFunction(a);
 
@@ -1992,7 +1992,7 @@
 TEST_F(ResolverConstEvalTest, Struct_I32s_ZeroInit) {
     Structure(
         "S", utils::Vector{Member("m1", ty.i32()), Member("m2", ty.i32()), Member("m3", ty.i32())});
-    auto* expr = Construct(ty("S"));
+    auto* expr = Call(ty("S"));
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -2037,7 +2037,7 @@
                        Member("m4", ty.f16()),
                        Member("m5", ty.bool_()),
                    });
-    auto* expr = Construct(ty("S"));
+    auto* expr = Call(ty("S"));
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -2090,7 +2090,7 @@
                        Member("m2", ty.vec3<f32>()),
                        Member("m3", ty.vec3<f32>()),
                    });
-    auto* expr = Construct(ty("S"));
+    auto* expr = Call(ty("S"));
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -2147,7 +2147,7 @@
                        Member("m4", ty.vec3<f16>()),
                        Member("m5", ty.vec2<bool>()),
                    });
-    auto* expr = Construct(ty("S"));
+    auto* expr = Call(ty("S"));
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -2224,7 +2224,7 @@
                            Member("m1", ty("Inner")),
                            Member("m2", ty("Inner")),
                        });
-    auto* expr = Construct(ty("Outer"));
+    auto* expr = Call(ty("Outer"));
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -2267,7 +2267,7 @@
                        Member("m4", ty.f16()),
                        Member("m5", ty.bool_()),
                    });
-    auto* expr = Construct(ty("S"), 1_i, 2_u, 3_f, 4_h, false);
+    auto* expr = Call(ty("S"), 1_i, 2_u, 3_f, 4_h, false);
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -2324,8 +2324,8 @@
                        Member("m4", ty.vec3<f16>()),
                        Member("m5", ty.vec2<bool>()),
                    });
-    auto* expr = Construct(ty("S"), vec2<i32>(1_i), vec3<u32>(2_u), vec4<f32>(3_f), vec3<f16>(4_h),
-                           vec2<bool>(false));
+    auto* expr = Call(ty("S"), vec2<i32>(1_i), vec3<u32>(2_u), vec4<f32>(3_f), vec3<f16>(4_h),
+                      vec2<bool>(false));
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -2402,9 +2402,8 @@
                            Member("m1", ty("Inner")),
                            Member("m2", ty("Inner")),
                        });
-    auto* expr =
-        Construct(ty("Outer"),  //
-                  Construct(ty("Inner"), 1_i, 2_u, 3_f), Construct(ty("Inner"), 4_i, 0_u, 6_f));
+    auto* expr = Call(ty("Outer"),  //
+                      Call(ty("Inner"), 1_i, 2_u, 3_f), Call(ty("Inner"), 4_i, 0_u, 6_f));
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -2442,9 +2441,8 @@
                        Member("m1", ty.array<i32, 2>()),
                        Member("m2", ty.array<f32, 3>()),
                    });
-    auto* expr = Construct(ty("S"),  //
-                           Construct(ty.array<i32, 2>(), 1_i, 2_i),
-                           Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
+    auto* expr = Call(ty("S"),  //
+                      Call(ty.array<i32, 2>(), 1_i, 2_i), Call(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
diff --git a/src/tint/resolver/const_eval_conversion_test.cc b/src/tint/resolver/const_eval_conversion_test.cc
index d4b562f..739294d 100644
--- a/src/tint/resolver/const_eval_conversion_test.cc
+++ b/src/tint/resolver/const_eval_conversion_test.cc
@@ -71,9 +71,9 @@
     const auto unrepresentable = std::get<1>(GetParam()).unrepresentable;
 
     auto* input_val = input.Expr(*this);
-    auto* expr = Construct(type.ast(*this), input_val);
+    auto* expr = Call(type.ast(*this), input_val);
     if (kind == Kind::kVector) {
-        expr = Construct(ty.vec(nullptr, 3), expr);
+        expr = Call(ty.vec(nullptr, 3), expr);
     }
     WrapInFunction(expr);
 
diff --git a/src/tint/resolver/const_eval_indexing_test.cc b/src/tint/resolver/const_eval_indexing_test.cc
index e7c9688..9776674 100644
--- a/src/tint/resolver/const_eval_indexing_test.cc
+++ b/src/tint/resolver/const_eval_indexing_test.cc
@@ -226,8 +226,8 @@
 }
 
 TEST_F(ResolverConstEvalTest, Array_vec3_f32_Index) {
-    auto* expr = IndexAccessor(Construct(ty.array(ty.vec3<f32>(), 2_u),  //
-                                         vec3<f32>(1_f, 2_f, 3_f), vec3<f32>(4_f, 5_f, 6_f)),
+    auto* expr = IndexAccessor(Call(ty.array(ty.vec3<f32>(), 2_u),  //
+                                    vec3<f32>(1_f, 2_f, 3_f), vec3<f32>(4_f, 5_f, 6_f)),
                                1_i);
     WrapInFunction(expr);
 
@@ -258,8 +258,8 @@
 }
 
 TEST_F(ResolverConstEvalTest, Array_vec3_f32_Index_OOB_High) {
-    auto* expr = IndexAccessor(Construct(ty.array(ty.vec3<f32>(), 2_u),  //
-                                         vec3<f32>(1_f, 2_f, 3_f), vec3<f32>(4_f, 5_f, 6_f)),
+    auto* expr = IndexAccessor(Call(ty.array(ty.vec3<f32>(), 2_u),  //
+                                    vec3<f32>(1_f, 2_f, 3_f), vec3<f32>(4_f, 5_f, 6_f)),
                                Expr(Source{{12, 34}}, 2_i));
     WrapInFunction(expr);
 
@@ -268,8 +268,8 @@
 }
 
 TEST_F(ResolverConstEvalTest, Array_vec3_f32_Index_OOB_Low) {
-    auto* expr = IndexAccessor(Construct(ty.array(ty.vec3<f32>(), 2_u),  //
-                                         vec3<f32>(1_f, 2_f, 3_f), vec3<f32>(4_f, 5_f, 6_f)),
+    auto* expr = IndexAccessor(Call(ty.array(ty.vec3<f32>(), 2_u),  //
+                                    vec3<f32>(1_f, 2_f, 3_f), vec3<f32>(4_f, 5_f, 6_f)),
                                Expr(Source{{12, 34}}, -2_i));
     WrapInFunction(expr);
 
@@ -288,11 +288,11 @@
 }
 
 TEST_F(ResolverConstEvalTest, ChainedIndex) {
-    auto* arr_expr = Construct(ty.array(ty.mat2x3<f32>(), 2_u),        // array<mat2x3<f32>, 2u>
-                               mat2x3<f32>(vec3<f32>(1_f, 2_f, 3_f),   //
-                                           vec3<f32>(4_f, 5_f, 6_f)),  //
-                               mat2x3<f32>(vec3<f32>(7_f, 0_f, 9_f),   //
-                                           vec3<f32>(10_f, 11_f, 12_f)));
+    auto* arr_expr = Call(ty.array(ty.mat2x3<f32>(), 2_u),        // array<mat2x3<f32>, 2u>
+                          mat2x3<f32>(vec3<f32>(1_f, 2_f, 3_f),   //
+                                      vec3<f32>(4_f, 5_f, 6_f)),  //
+                          mat2x3<f32>(vec3<f32>(7_f, 0_f, 9_f),   //
+                                      vec3<f32>(10_f, 11_f, 12_f)));
 
     auto* mat_expr = IndexAccessor(arr_expr, 1_i);  // arr[1]
     auto* vec_expr = IndexAccessor(mat_expr, 0_i);  // arr[1][0]
diff --git a/src/tint/resolver/const_eval_member_access_test.cc b/src/tint/resolver/const_eval_member_access_test.cc
index 04ed3f8..c1fcfa1 100644
--- a/src/tint/resolver/const_eval_member_access_test.cc
+++ b/src/tint/resolver/const_eval_member_access_test.cc
@@ -31,9 +31,8 @@
                            Member("o1", ty("Inner")),
                            Member("o2", ty("Inner")),
                        });
-    auto* outer_expr =
-        Construct(ty("Outer"),  //
-                  Construct(ty("Inner"), 1_i, 2_u, 3_f, true), Construct(ty("Inner")));
+    auto* outer_expr = Call(ty("Outer"),  //
+                            Call(ty("Inner"), 1_i, 2_u, 3_f, true), Call(ty("Inner")));
     auto* o1_expr = MemberAccessor(outer_expr, "o1");
     auto* i2_expr = MemberAccessor(o1_expr, "i2");
     WrapInFunction(i2_expr);
@@ -72,9 +71,9 @@
 }
 
 TEST_F(ResolverConstEvalTest, Matrix_AFloat_Construct_From_AInt_Vectors) {
-    auto* c = Const("a", Construct(ty.mat(nullptr, 2, 2),  //
-                                   Construct(ty.vec(nullptr, 2), Expr(1_a), Expr(2_a)),
-                                   Construct(ty.vec(nullptr, 2), Expr(3_a), Expr(4_a))));
+    auto* c = Const("a", Call(ty.mat(nullptr, 2, 2),  //
+                              Call(ty.vec(nullptr, 2), Expr(1_a), Expr(2_a)),
+                              Call(ty.vec(nullptr, 2), Expr(3_a), Expr(4_a))));
     WrapInFunction(c);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -98,10 +97,9 @@
 }
 
 TEST_F(ResolverConstEvalTest, MatrixMemberAccess_AFloat) {
-    auto* c =
-        Const("a", Construct(ty.mat(nullptr, 2, 3),  //
-                             Construct(ty.vec(nullptr, 3), Expr(1.0_a), Expr(2.0_a), Expr(3.0_a)),
-                             Construct(ty.vec(nullptr, 3), Expr(4.0_a), Expr(5.0_a), Expr(6.0_a))));
+    auto* c = Const("a", Call(ty.mat(nullptr, 2, 3),  //
+                              Call(ty.vec(nullptr, 3), Expr(1.0_a), Expr(2.0_a), Expr(3.0_a)),
+                              Call(ty.vec(nullptr, 3), Expr(4.0_a), Expr(5.0_a), Expr(6.0_a))));
 
     auto* col_0 = Const("col_0", IndexAccessor("a", Expr(0_i)));
     auto* col_1 = Const("col_1", IndexAccessor("a", Expr(1_i)));
@@ -176,10 +174,9 @@
 }
 
 TEST_F(ResolverConstEvalTest, MatrixMemberAccess_f32) {
-    auto* c =
-        Const("a", Construct(ty.mat(nullptr, 2, 3),  //
-                             Construct(ty.vec(nullptr, 3), Expr(1.0_f), Expr(2.0_f), Expr(3.0_f)),
-                             Construct(ty.vec(nullptr, 3), Expr(4.0_f), Expr(5.0_f), Expr(6.0_f))));
+    auto* c = Const("a", Call(ty.mat(nullptr, 2, 3),  //
+                              Call(ty.vec(nullptr, 3), Expr(1.0_f), Expr(2.0_f), Expr(3.0_f)),
+                              Call(ty.vec(nullptr, 3), Expr(4.0_f), Expr(5.0_f), Expr(6.0_f))));
 
     auto* col_0 = Const("col_0", IndexAccessor("a", Expr(0_i)));
     auto* col_1 = Const("col_1", IndexAccessor("a", Expr(1_i)));
diff --git a/src/tint/resolver/dependency_graph_test.cc b/src/tint/resolver/dependency_graph_test.cc
index 5a816fb..4dfc3a3 100644
--- a/src/tint/resolver/dependency_graph_test.cc
+++ b/src/tint/resolver/dependency_graph_test.cc
@@ -665,7 +665,7 @@
     // type T = i32;
 
     Func("F", utils::Empty, ty.void_(),
-         utils::Vector{Block(Ignore(Construct(ty(Source{{12, 34}}, "T"))))});
+         utils::Vector{Block(Ignore(Call(ty(Source{{12, 34}}, "T"))))});
     Alias(Source{{56, 78}}, "T", ty.i32());
 
     Build();
@@ -1333,7 +1333,7 @@
     Structure("B", utils::Vector{Member("b", ty.i32())});
     Func("f", utils::Vector{Param("a", ty("A"))}, ty("B"),
          utils::Vector{
-             Return(Construct(ty("B"))),
+             Return(Call(ty("B"))),
          });
     Build();
 }
diff --git a/src/tint/resolver/entry_point_validation_test.cc b/src/tint/resolver/entry_point_validation_test.cc
index 9a026c7..2ca3e93 100644
--- a/src/tint/resolver/entry_point_validation_test.cc
+++ b/src/tint/resolver/entry_point_validation_test.cc
@@ -68,7 +68,7 @@
     // fn main() -> @builtin(position) vec4<f32> { return vec4<f32>(); }
     Func(Source{{12, 34}}, "main", utils::Empty, ty.vec4<f32>(),
          utils::Vector{
-             Return(Construct(ty.vec4<f32>())),
+             Return(Call(ty.vec4<f32>())),
          },
          utils::Vector{
              Stage(ast::PipelineStage::kVertex),
@@ -87,7 +87,7 @@
     // }
     Func(Source{{12, 34}}, "main", utils::Empty, ty.vec4<f32>(),
          utils::Vector{
-             Return(Construct(ty.vec4<f32>())),
+             Return(Call(ty.vec4<f32>())),
          },
          utils::Vector{
              Stage(ast::PipelineStage::kVertex),
@@ -104,7 +104,7 @@
     // }
     Func(Source{{12, 34}}, "main", utils::Empty, ty.vec4<f32>(),
          utils::Vector{
-             Return(Construct(ty.vec4<f32>())),
+             Return(Call(ty.vec4<f32>())),
          },
          utils::Vector{
              Stage(ast::PipelineStage::kVertex),
@@ -135,7 +135,7 @@
                   });
     Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
          utils::Vector{
-             Return(Construct(ty.Of(output))),
+             Return(Call(ty.Of(output))),
          },
          utils::Vector{
              Stage(ast::PipelineStage::kFragment),
@@ -161,7 +161,7 @@
         });
     Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
          utils::Vector{
-             Return(Construct(ty.Of(output))),
+             Return(Call(ty.Of(output))),
          },
          utils::Vector{
              Stage(ast::PipelineStage::kFragment),
@@ -189,7 +189,7 @@
                   });
     Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
          utils::Vector{
-             Return(Construct(ty.Of(output))),
+             Return(Call(ty.Of(output))),
          },
          utils::Vector{
              Stage(ast::PipelineStage::kFragment),
@@ -217,7 +217,7 @@
                   });
     Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
          utils::Vector{
-             Return(Construct(ty.Of(output))),
+             Return(Call(ty.Of(output))),
          },
          utils::Vector{
              Stage(ast::PipelineStage::kFragment),
@@ -686,7 +686,7 @@
 
     Func(Source{{12, 34}}, "main", utils::Empty, params.create_ast_type(*this),
          utils::Vector{
-             Return(Construct(params.create_ast_type(*this))),
+             Return(Call(params.create_ast_type(*this))),
          },
          utils::Vector{
              Stage(ast::PipelineStage::kFragment),
@@ -720,7 +720,7 @@
                   });
     Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
          utils::Vector{
-             Return(Construct(ty.Of(output))),
+             Return(Call(ty.Of(output))),
          },
          utils::Vector{
              Stage(ast::PipelineStage::kFragment),
@@ -794,7 +794,7 @@
 
     Func(Source{{12, 34}}, "frag_main", utils::Empty, ty.array<f32, 2>(),
          utils::Vector{
-             Return(Construct(ty.array<f32, 2>())),
+             Return(Call(ty.array<f32, 2>())),
          },
          utils::Vector{
              Stage(ast::PipelineStage::kFragment),
@@ -942,7 +942,7 @@
 
     Func("frag_main", utils::Empty, ty.Of(s),
          utils::Vector{
-             Return(Construct(ty.Of(s))),
+             Return(Call(ty.Of(s))),
          },
          utils::Vector{
              Stage(ast::PipelineStage::kFragment),
@@ -990,7 +990,7 @@
                   });
     Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
          utils::Vector{
-             Return(Construct(ty.Of(output))),
+             Return(Call(ty.Of(output))),
          },
          utils::Vector{
              Stage(ast::PipelineStage::kFragment),
@@ -1012,7 +1012,7 @@
                                        });
     Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
          utils::Vector{
-             Return(Construct(ty.Of(output))),
+             Return(Call(ty.Of(output))),
          },
          utils::Vector{
              Stage(ast::PipelineStage::kVertex),
@@ -1047,7 +1047,7 @@
                                        });
     Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
          utils::Vector{
-             Return(Construct(ty.Of(output))),
+             Return(Call(ty.Of(output))),
          },
          utils::Vector{
              Stage(ast::PipelineStage::kFragment),
@@ -1073,7 +1073,7 @@
                                        });
     Func(Source{{12, 34}}, "main", utils::Empty, ty.Of(output),
          utils::Vector{
-             Return(Construct(ty.Of(output))),
+             Return(Call(ty.Of(output))),
          },
          utils::Vector{
              Stage(ast::PipelineStage::kFragment),
@@ -1127,7 +1127,7 @@
     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)))),
+             Return(Expr(Call(ty.Of(s)))),
          },
          utils::Vector{
              Stage(ast::PipelineStage::kCompute),
diff --git a/src/tint/resolver/evaluation_stage_test.cc b/src/tint/resolver/evaluation_stage_test.cc
index 2b16053..28c8a99 100644
--- a/src/tint/resolver/evaluation_stage_test.cc
+++ b/src/tint/resolver/evaluation_stage_test.cc
@@ -116,7 +116,7 @@
     // const f = 1.f;
     // array<f32, 2>(f, f);
     auto* f = Const("f", Expr(1_f));
-    auto* expr = Construct(ty.array<f32, 2>(), f, f);
+    auto* expr = Call(ty.array<f32, 2>(), f, f);
     WrapInFunction(f, expr);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -130,7 +130,7 @@
     // array<f32, 2>(f1, f2);
     auto* f1 = Const("f1", Expr(1_f));
     auto* f2 = Override("f2", Expr(2_f));
-    auto* expr = Construct(ty.array<f32, 2>(), f1, f2);
+    auto* expr = Call(ty.array<f32, 2>(), f1, f2);
     WrapInFunction(f1, expr);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -145,7 +145,7 @@
     // array<f32, 2>(f1, f2);
     auto* f1 = Override("f1", Expr(1_f));
     auto* f2 = Var("f2", Expr(2_f));
-    auto* expr = Construct(ty.array<f32, 2>(), f1, f2);
+    auto* expr = Call(ty.array<f32, 2>(), f1, f2);
     WrapInFunction(f2, expr);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -160,7 +160,7 @@
     // array<f32, 2>(f1, f2);
     auto* f1 = Const("f1", Expr(1_f));
     auto* f2 = Var("f2", Expr(2_f));
-    auto* expr = Construct(ty.array<f32, 2>(), f1, f2);
+    auto* expr = Call(ty.array<f32, 2>(), f1, f2);
     WrapInFunction(f1, f2, expr);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -173,7 +173,7 @@
     // var f = 1.f;
     // array<f32, 2>(f, f);
     auto* f = Var("f", Expr(1_f));
-    auto* expr = Construct(ty.array<f32, 2>(), f, f);
+    auto* expr = Call(ty.array<f32, 2>(), f, f);
     WrapInFunction(f, expr);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -270,7 +270,7 @@
     // const str = S();
     // str.m
     Structure("S", utils::Vector{Member("m", ty.i32())});
-    auto* str = Const("str", Construct(ty("S")));
+    auto* str = Const("str", Call(ty("S")));
     auto* expr = MemberAccessor(str, "m");
     WrapInFunction(str, expr);
 
@@ -284,7 +284,7 @@
     // var str = S();
     // str.m
     Structure("S", utils::Vector{Member("m", ty.i32())});
-    auto* str = Var("str", Construct(ty("S")));
+    auto* str = Var("str", Call(ty("S")));
     auto* expr = MemberAccessor(str, "m");
     WrapInFunction(str, expr);
 
diff --git a/src/tint/resolver/f16_extension_test.cc b/src/tint/resolver/f16_extension_test.cc
index 2aad98f..1d327e5 100644
--- a/src/tint/resolver/f16_extension_test.cc
+++ b/src/tint/resolver/f16_extension_test.cc
@@ -65,14 +65,14 @@
     // var<private> v = vec2<f16>();
     Enable(ast::Extension::kF16);
 
-    GlobalVar("v", Construct(ty.vec2<f16>()), type::AddressSpace::kPrivate);
+    GlobalVar("v", Call(ty.vec2<f16>()), type::AddressSpace::kPrivate);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverF16ExtensionTest, Vec2TypeInitUsedWithoutExtension) {
     // var<private> v = vec2<f16>();
-    GlobalVar("v", Construct(ty.vec2(ty.f16(Source{{12, 34}}))), type::AddressSpace::kPrivate);
+    GlobalVar("v", Call(ty.vec2(ty.f16(Source{{12, 34}}))), type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: f16 type used without 'f16' extension enabled");
@@ -83,15 +83,14 @@
     // var<private> v = vec2<f16>(vec2<f32>());
     Enable(ast::Extension::kF16);
 
-    GlobalVar("v", Construct(ty.vec2<f16>(), Construct(ty.vec2<f32>())),
-              type::AddressSpace::kPrivate);
+    GlobalVar("v", Call(ty.vec2<f16>(), Call(ty.vec2<f32>())), type::AddressSpace::kPrivate);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverF16ExtensionTest, Vec2TypeConvUsedWithoutExtension) {
     // var<private> v = vec2<f16>(vec2<f32>());
-    GlobalVar("v", Construct(ty.vec2(ty.f16(Source{{12, 34}})), Construct(ty.vec2<f32>())),
+    GlobalVar("v", Call(ty.vec2(ty.f16(Source{{12, 34}})), Call(ty.vec2<f32>())),
               type::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
diff --git a/src/tint/resolver/function_validation_test.cc b/src/tint/resolver/function_validation_test.cc
index 4117f99..65aff49 100644
--- a/src/tint/resolver/function_validation_test.cc
+++ b/src/tint/resolver/function_validation_test.cc
@@ -185,7 +185,7 @@
     Func(Source{{1, 2}}, "func", utils::Empty, ty.vec4<f32>(),
          utils::Vector{
              Discard(Source{{12, 34}}),
-             Return(Construct(ty.vec4<f32>())),
+             Return(Call(ty.vec4<f32>())),
          },
          utils::Vector{Stage(ast::PipelineStage::kVertex)},
          utils::Vector{Builtin(ast::BuiltinValue::kPosition)});
@@ -533,7 +533,7 @@
     auto* func = Func("main", utils::Empty, ty.void_(), utils::Empty,
                       utils::Vector{
                           Stage(ast::PipelineStage::kCompute),
-                          WorkgroupSize(Construct(Source{{12, 34}}, ty.i32(), 5_a)),
+                          WorkgroupSize(Call(Source{{12, 34}}, ty.i32(), 5_a)),
                       });
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -788,7 +788,7 @@
     // const x = i32(i32(i32()));
     // @compute @workgroup_size(x)
     // fn main() {}
-    GlobalConst("x", ty.i32(), Construct(ty.i32(), Construct(ty.i32(), Construct(ty.i32()))));
+    GlobalConst("x", ty.i32(), Call<i32>(Call<i32>(Call<i32>())));
     Func("main", utils::Empty, ty.void_(), utils::Empty,
          utils::Vector{
              Stage(ast::PipelineStage::kCompute),
@@ -894,7 +894,7 @@
     Func("main", utils::Empty, ty.void_(), utils::Empty,
          utils::Vector{
              Stage(ast::PipelineStage::kCompute),
-             WorkgroupSize(Construct(Source{{12, 34}}, ty.i32(), "x")),
+             WorkgroupSize(Call(Source{{12, 34}}, ty.i32(), "x")),
          });
 
     EXPECT_FALSE(r()->Resolve());
@@ -910,7 +910,7 @@
     Func("main", utils::Empty, ty.void_(), utils::Empty,
          utils::Vector{
              Stage(ast::PipelineStage::kCompute),
-             WorkgroupSize(Construct(Source{{12, 34}}, ty.i32(), "x")),
+             WorkgroupSize(Call(Source{{12, 34}}, ty.i32(), "x")),
          });
 
     EXPECT_FALSE(r()->Resolve());
@@ -926,7 +926,7 @@
     Func("main", utils::Empty, ty.void_(), utils::Empty,
          utils::Vector{
              Stage(ast::PipelineStage::kCompute),
-             WorkgroupSize(Construct(Source{{12, 34}}, ty.i32(), "x")),
+             WorkgroupSize(Call(Source{{12, 34}}, ty.i32(), "x")),
          });
 
     EXPECT_FALSE(r()->Resolve());
diff --git a/src/tint/resolver/inferred_type_test.cc b/src/tint/resolver/inferred_type_test.cc
index 0835275..f3a2a6d 100644
--- a/src/tint/resolver/inferred_type_test.cc
+++ b/src/tint/resolver/inferred_type_test.cc
@@ -138,7 +138,7 @@
     auto* expected_type = create<type::Array>(
         create<type::U32>(), create<type::ConstantArrayCount>(10u), 4u, 4u * 10u, 4u, 4u);
 
-    auto* ctor_expr = Construct(type);
+    auto* ctor_expr = Call(type);
     auto* var = Var("a", type::AddressSpace::kFunction, ctor_expr);
     WrapInFunction(var);
 
@@ -156,7 +156,7 @@
                                                 create<type::I32>(), 0u, 0u, 0u, 4u, std::nullopt)},
         0u, 4u, 4u);
 
-    auto* ctor_expr = Construct(ty.Of(str));
+    auto* ctor_expr = Call(ty.Of(str));
 
     auto* var = Var("a", type::AddressSpace::kFunction, ctor_expr);
     WrapInFunction(var);
diff --git a/src/tint/resolver/load_test.cc b/src/tint/resolver/load_test.cc
index d44b34f..7a74224 100644
--- a/src/tint/resolver/load_test.cc
+++ b/src/tint/resolver/load_test.cc
@@ -154,7 +154,7 @@
     // var ref = vec4(1);
     // var v = ref.xyz;
     auto* ident = Expr("ref");
-    WrapInFunction(Var("ref", Construct(ty.vec4<i32>(), 1_i)),  //
+    WrapInFunction(Var("ref", Call(ty.vec4<i32>(), 1_i)),  //
                    Var("v", MemberAccessor(ident, "xyz")));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -230,7 +230,7 @@
          },
          ty.vec4<f32>(),
          utils::Vector{
-             Return(Call("textureSampleLevel", "tp", "sp", Construct(ty.vec2<f32>()), 0_a)),
+             Return(Call("textureSampleLevel", "tp", "sp", Call(ty.vec2<f32>()), 0_a)),
          });
     auto* t_ident = Expr("t");
     auto* s_ident = Expr("s");
diff --git a/src/tint/resolver/materialize_test.cc b/src/tint/resolver/materialize_test.cc
index 4543f85..366fbc3 100644
--- a/src/tint/resolver/materialize_test.cc
+++ b/src/tint/resolver/materialize_test.cc
@@ -346,11 +346,11 @@
             Func("F", utils::Empty, target_ty(), utils::Vector{Return(abstract_expr)});
             break;
         case Method::kArray:
-            WrapInFunction(Construct(ty.array(target_ty(), 1_i), abstract_expr));
+            WrapInFunction(Call(ty.array(target_ty(), 1_i), abstract_expr));
             break;
         case Method::kStruct:
             Structure("S", utils::Vector{Member("v", target_ty())});
-            WrapInFunction(Construct(ty("S"), abstract_expr));
+            WrapInFunction(Call(ty("S"), abstract_expr));
             break;
         case Method::kBinaryOp: {
             // Add 0 to ensure no overflow with max float values
@@ -912,7 +912,7 @@
             break;
         }
         case Method::kArrayLength: {
-            WrapInFunction(Construct(ty.array(ty.i32(), abstract_expr())));
+            WrapInFunction(Call(ty.array(ty.i32(), abstract_expr())));
             break;
         }
         case Method::kSwitch: {
@@ -1262,7 +1262,7 @@
 
 TEST_F(MaterializeAbstractStructure, Modf_Vector_DefaultType) {
     // var v = modf(vec2(1));
-    auto* call = Call("modf", Construct(ty.vec2(nullptr), 1_a));
+    auto* call = Call("modf", Call(ty.vec2(nullptr), 1_a));
     WrapInFunction(Decl(Var("v", call)));
     ASSERT_TRUE(r()->Resolve()) << r()->error();
     auto* sem = Sem().Get(call);
@@ -1302,9 +1302,8 @@
     // var v = modf(vec2(1_h)); // v is __modf_result_vec2_f16
     // v = modf(vec2(1));       // __modf_result_vec2_f16 <- __modf_result_vec2_abstract
     Enable(ast::Extension::kF16);
-    auto* call = Call("modf", Construct(ty.vec2(nullptr), 1_a));
-    WrapInFunction(Decl(Var("v", Call("modf", Construct(ty.vec2(nullptr), 1_h)))),
-                   Assign("v", call));
+    auto* call = Call("modf", Call(ty.vec2(nullptr), 1_a));
+    WrapInFunction(Decl(Var("v", Call("modf", Call(ty.vec2(nullptr), 1_h)))), Assign("v", call));
     ASSERT_TRUE(r()->Resolve()) << r()->error();
     auto* sem = Sem().Get(call);
     ASSERT_TRUE(sem->Is<sem::Materialize>());
@@ -1340,7 +1339,7 @@
 
 TEST_F(MaterializeAbstractStructure, Frexp_Vector_DefaultType) {
     // var v = frexp(vec2(1));
-    auto* call = Call("frexp", Construct(ty.vec2(nullptr), 1_a));
+    auto* call = Call("frexp", Call(ty.vec2(nullptr), 1_a));
     WrapInFunction(Decl(Var("v", call)));
     ASSERT_TRUE(r()->Resolve()) << r()->error();
     auto* sem = Sem().Get(call);
@@ -1386,9 +1385,8 @@
     // var v = frexp(vec2(1_h)); // v is __frexp_result_vec2_f16
     // v = frexp(vec2(1));       // __frexp_result_vec2_f16 <- __frexp_result_vec2_abstract
     Enable(ast::Extension::kF16);
-    auto* call = Call("frexp", Construct(ty.vec2(nullptr), 1_a));
-    WrapInFunction(Decl(Var("v", Call("frexp", Construct(ty.vec2(nullptr), 1_h)))),
-                   Assign("v", call));
+    auto* call = Call("frexp", Call(ty.vec2(nullptr), 1_a));
+    WrapInFunction(Decl(Var("v", Call("frexp", Call(ty.vec2(nullptr), 1_h)))), Assign("v", call));
     ASSERT_TRUE(r()->Resolve()) << r()->error();
     auto* sem = Sem().Get(call);
     ASSERT_TRUE(sem->Is<sem::Materialize>());
diff --git a/src/tint/resolver/resolver_behavior_test.cc b/src/tint/resolver/resolver_behavior_test.cc
index 960144e..af69c3c 100644
--- a/src/tint/resolver/resolver_behavior_test.cc
+++ b/src/tint/resolver/resolver_behavior_test.cc
@@ -82,7 +82,7 @@
     Func("ArrayDiscardOrNext", utils::Empty, ty.array<i32, 4>(),
          utils::Vector{
              If(true, Block(Discard())),
-             Return(Construct(ty.array<i32, 4>())),
+             Return(Call(ty.array<i32, 4>())),
          });
 
     auto* stmt = Decl(Var("lhs", ty.i32(), IndexAccessor(Call("ArrayDiscardOrNext"), 1_i)));
diff --git a/src/tint/resolver/resolver_test.cc b/src/tint/resolver/resolver_test.cc
index a71bebc..3886b10 100644
--- a/src/tint/resolver/resolver_test.cc
+++ b/src/tint/resolver/resolver_test.cc
@@ -644,7 +644,7 @@
 TEST_F(ResolverTest, Expr_Cast) {
     GlobalVar("name", ty.f32(), type::AddressSpace::kPrivate);
 
-    auto* cast = Construct(ty.f32(), "name");
+    auto* cast = Call<f32>("name");
     WrapInFunction(cast);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -715,7 +715,7 @@
 }
 
 TEST_F(ResolverTest, Expr_Identifier_GlobalConst) {
-    auto* my_var = GlobalConst("my_var", ty.f32(), Construct(ty.f32()));
+    auto* my_var = GlobalConst("my_var", ty.f32(), Call<f32>());
 
     auto* ident = Expr("my_var");
     WrapInFunction(ident);
@@ -731,7 +731,7 @@
 
 TEST_F(ResolverTest, Expr_Identifier_FunctionVariable_Const) {
     auto* my_var_a = Expr("my_var");
-    auto* var = Let("my_var", ty.f32(), Construct(ty.f32()));
+    auto* var = Let("my_var", ty.f32(), Call<f32>());
     auto* decl = Decl(Var("b", ty.f32(), my_var_a));
 
     Func("my_func", utils::Empty, ty.void_(),
@@ -755,7 +755,7 @@
     // var idx : f32 = f32();
     // var f : f32 = a[idx];
     auto* a = Var("a", ty.array<bool, 10>(), array<bool, 10>());
-    auto* idx = Var("idx", ty.f32(), Construct(ty.f32()));
+    auto* idx = Var("idx", ty.f32(), Call<f32>());
     auto* f = Var("f", ty.f32(), IndexAccessor("a", Expr(Source{{12, 34}}, idx)));
     Func("my_func", utils::Empty, ty.void_(),
          utils::Vector{
@@ -1034,7 +1034,7 @@
 TEST_F(ResolverTest, Function_NotRegisterFunctionConstant) {
     auto* func = Func("my_func", utils::Empty, ty.void_(),
                       utils::Vector{
-                          Decl(Let("var", ty.f32(), Construct(ty.f32()))),
+                          Decl(Let("var", ty.f32(), Call<f32>())),
                       });
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1145,10 +1145,8 @@
     // const height = i32(i32(i32(4i)));
     // @compute @workgroup_size(width, height)
     // fn main() {}
-    GlobalConst("width", ty.i32(),
-                Construct(ty.i32(), Construct(ty.i32(), Construct(ty.i32(), 8_i))));
-    GlobalConst("height", ty.i32(),
-                Construct(ty.i32(), Construct(ty.i32(), Construct(ty.i32(), 4_i))));
+    GlobalConst("width", ty.i32(), Call<i32>(Call<i32>(Call<i32>(8_i))));
+    GlobalConst("height", ty.i32(), Call<i32>(Call<i32>(Call<i32>(4_i))));
     auto* func = Func("main", utils::Empty, ty.void_(), utils::Empty,
                       utils::Vector{
                           Stage(ast::PipelineStage::kCompute),
@@ -1896,7 +1894,7 @@
 }
 
 TEST_F(ResolverTest, AddressSpace_DoesNotSetOnConst) {
-    auto* var = Let("var", ty.i32(), Construct(ty.i32()));
+    auto* var = Let("var", ty.i32(), Call<i32>());
     auto* stmt = Decl(var);
     Func("func", utils::Empty, ty.void_(), utils::Vector{stmt});
 
diff --git a/src/tint/resolver/resolver_test_helper.h b/src/tint/resolver/resolver_test_helper.h
index 2c175b9..ee913f4 100644
--- a/src/tint/resolver/resolver_test_helper.h
+++ b/src/tint/resolver/resolver_test_helper.h
@@ -467,7 +467,7 @@
     /// @param args args of size 1 or N with values of type T to initialize with
     /// @return a new AST vector value expression
     static inline const ast::Expression* Expr(ProgramBuilder& b, utils::VectorRef<Scalar> args) {
-        return b.Construct(AST(b), ExprArgs(b, std::move(args)));
+        return b.Call(AST(b), ExprArgs(b, std::move(args)));
     }
     /// @param b the ProgramBuilder
     /// @param args args of size 1 or N with values of type T to initialize with
@@ -516,7 +516,7 @@
     /// @param args args of size 1 or N*M with values of type T to initialize with
     /// @return a new AST matrix value expression
     static inline const ast::Expression* Expr(ProgramBuilder& b, utils::VectorRef<Scalar> args) {
-        return b.Construct(AST(b), ExprArgs(b, std::move(args)));
+        return b.Call(AST(b), ExprArgs(b, std::move(args)));
     }
     /// @param b the ProgramBuilder
     /// @param args args of size 1 or N*M with values of type T to initialize with
@@ -582,7 +582,7 @@
         ProgramBuilder& b,
         utils::VectorRef<Scalar> args) {
         // Cast
-        return b.Construct(AST(b), DataType<T>::Expr(b, std::move(args)));
+        return b.Call(AST(b), DataType<T>::Expr(b, std::move(args)));
     }
 
     /// @param b the ProgramBuilder
@@ -593,7 +593,7 @@
         ProgramBuilder& b,
         utils::VectorRef<Scalar> args) {
         // Construct
-        return b.Construct(AST(b), DataType<T>::ExprArgs(b, std::move(args)));
+        return b.Call(AST(b), DataType<T>::ExprArgs(b, std::move(args)));
     }
 
     /// @param b the ProgramBuilder
@@ -689,7 +689,7 @@
     /// with
     /// @return a new AST array value expression
     static inline const ast::Expression* Expr(ProgramBuilder& b, utils::VectorRef<Scalar> args) {
-        return b.Construct(AST(b), ExprArgs(b, std::move(args)));
+        return b.Call(AST(b), ExprArgs(b, std::move(args)));
     }
     /// @param b the ProgramBuilder
     /// @param args args of size 1 or N with values of type T to initialize with
diff --git a/src/tint/resolver/side_effects_test.cc b/src/tint/resolver/side_effects_test.cc
index cca7741..b7d27c0 100644
--- a/src/tint/resolver/side_effects_test.cc
+++ b/src/tint/resolver/side_effects_test.cc
@@ -370,7 +370,7 @@
 
 TEST_F(SideEffectsTest, Call_TypeConversion_NoSE) {
     auto* var = Decl(Var("a", ty.i32()));
-    auto* expr = Construct(ty.f32(), "a");
+    auto* expr = Call<f32>("a");
     WrapInFunction(var, expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -382,7 +382,7 @@
 
 TEST_F(SideEffectsTest, Call_TypeConversion_SE) {
     MakeSideEffectFunc<i32>("se");
-    auto* expr = Construct(ty.f32(), Call("se"));
+    auto* expr = Call<f32>(Call("se"));
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -394,7 +394,7 @@
 
 TEST_F(SideEffectsTest, Call_TypeInitializer_NoSE) {
     auto* var = Decl(Var("a", ty.f32()));
-    auto* expr = Construct(ty.f32(), "a");
+    auto* expr = Call<f32>("a");
     WrapInFunction(var, expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -406,7 +406,7 @@
 
 TEST_F(SideEffectsTest, Call_TypeInitializer_SE) {
     MakeSideEffectFunc<f32>("se");
-    auto* expr = Construct(ty.f32(), Call("se"));
+    auto* expr = Call<f32>(Call("se"));
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
diff --git a/src/tint/resolver/struct_address_space_use_test.cc b/src/tint/resolver/struct_address_space_use_test.cc
index a0ff744..6500158 100644
--- a/src/tint/resolver/struct_address_space_use_test.cc
+++ b/src/tint/resolver/struct_address_space_use_test.cc
@@ -52,7 +52,7 @@
 TEST_F(ResolverAddressSpaceUseTest, StructReachableFromReturnType) {
     auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
 
-    Func("f", utils::Empty, ty.Of(s), utils::Vector{Return(Construct(ty.Of(s)))}, utils::Empty);
+    Func("f", utils::Empty, ty.Of(s), utils::Vector{Return(Call(ty.Of(s)))}, utils::Empty);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 
diff --git a/src/tint/resolver/struct_pipeline_stage_use_test.cc b/src/tint/resolver/struct_pipeline_stage_use_test.cc
index cd77c07..1ffc907 100644
--- a/src/tint/resolver/struct_pipeline_stage_use_test.cc
+++ b/src/tint/resolver/struct_pipeline_stage_use_test.cc
@@ -53,7 +53,7 @@
 TEST_F(ResolverPipelineStageUseTest, StructUsedAsNonEntryPointReturnType) {
     auto* s = Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{Location(0_a)})});
 
-    Func("foo", utils::Empty, ty.Of(s), utils::Vector{Return(Construct(ty.Of(s), Expr(0_f)))},
+    Func("foo", utils::Empty, ty.Of(s), utils::Vector{Return(Call(ty.Of(s), Expr(0_f)))},
          utils::Empty);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -67,7 +67,7 @@
     auto* s = Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{Location(0_a)})});
 
     Func("main", utils::Vector{Param("param", ty.Of(s))}, ty.vec4<f32>(),
-         utils::Vector{Return(Construct(ty.vec4<f32>()))},
+         utils::Vector{Return(Call(ty.vec4<f32>()))},
          utils::Vector{Stage(ast::PipelineStage::kVertex)},
          utils::Vector{Builtin(ast::BuiltinValue::kPosition)});
 
@@ -84,7 +84,7 @@
         Structure("S", utils::Vector{Member("a", ty.vec4<f32>(),
                                             utils::Vector{Builtin(ast::BuiltinValue::kPosition)})});
 
-    Func("main", utils::Empty, ty.Of(s), utils::Vector{Return(Construct(ty.Of(s)))},
+    Func("main", utils::Empty, ty.Of(s), utils::Vector{Return(Call(ty.Of(s)))},
          utils::Vector{Stage(ast::PipelineStage::kVertex)});
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -112,7 +112,7 @@
 TEST_F(ResolverPipelineStageUseTest, StructUsedAsFragmentShaderReturnType) {
     auto* s = Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{Location(0_a)})});
 
-    Func("main", utils::Empty, ty.Of(s), utils::Vector{Return(Construct(ty.Of(s), Expr(0_f)))},
+    Func("main", utils::Empty, ty.Of(s), utils::Vector{Return(Call(ty.Of(s), Expr(0_f)))},
          utils::Vector{Stage(ast::PipelineStage::kFragment)});
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -144,7 +144,7 @@
         Structure("S", utils::Vector{Member("a", ty.vec4<f32>(),
                                             utils::Vector{Builtin(ast::BuiltinValue::kPosition)})});
 
-    Func("vert_main", utils::Empty, ty.Of(s), utils::Vector{Return(Construct(ty.Of(s)))},
+    Func("vert_main", utils::Empty, ty.Of(s), utils::Vector{Return(Call(ty.Of(s)))},
          utils::Vector{Stage(ast::PipelineStage::kVertex)});
 
     Func("frag_main", utils::Vector{Param("param", ty.Of(s))}, ty.void_(), utils::Empty,
@@ -193,7 +193,7 @@
     auto* s_alias = Alias("S_alias", ty.Of(s));
 
     Func("main", utils::Empty, ty.Of(s_alias),
-         utils::Vector{Return(Construct(ty.Of(s_alias), Expr(0_f)))},
+         utils::Vector{Return(Call(ty.Of(s_alias), Expr(0_f)))},
          utils::Vector{Stage(ast::PipelineStage::kFragment)});
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -207,7 +207,7 @@
 TEST_F(ResolverPipelineStageUseTest, StructUsedAsShaderReturnTypeLocationSet) {
     auto* s = Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{Location(3_a)})});
 
-    Func("main", utils::Empty, ty.Of(s), utils::Vector{Return(Construct(ty.Of(s), Expr(0_f)))},
+    Func("main", utils::Empty, ty.Of(s), utils::Vector{Return(Call(ty.Of(s), Expr(0_f)))},
          utils::Vector{Stage(ast::PipelineStage::kFragment)});
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
diff --git a/src/tint/resolver/type_initializer_validation_test.cc b/src/tint/resolver/type_initializer_validation_test.cc
index c8c0a3c..41fec1d 100644
--- a/src/tint/resolver/type_initializer_validation_test.cc
+++ b/src/tint/resolver/type_initializer_validation_test.cc
@@ -189,7 +189,7 @@
     Enable(ast::Extension::kF16);
 
     Func("foo", utils::Empty, params.create_rhs_ast_type(*this),
-         utils::Vector{Return(Construct(params.create_rhs_ast_type(*this)))}, {});
+         utils::Vector{Return(Call(params.create_rhs_ast_type(*this)))}, {});
 
     auto* a = Var("a", Call("foo"));
     // Self-assign 'a' to force the expression to be resolved so we can test its
@@ -356,8 +356,8 @@
        << FriendlyName(rhs_type) << "(<rhs value expr>))";
     SCOPED_TRACE(ss.str());
 
-    auto* arg = Construct(rhs_type, rhs_value_expr);
-    auto* tc = Construct(lhs_type2, arg);
+    auto* arg = Call(rhs_type, rhs_value_expr);
+    auto* tc = Call(lhs_type2, arg);
     auto* a = Var("a", lhs_type1, tc);
 
     // Self-assign 'a' to force the expression to be resolved so we can test its
@@ -451,7 +451,7 @@
 
     Enable(ast::Extension::kF16);
 
-    auto* a = Var("a", lhs_type1, Construct(lhs_type2, Construct(rhs_type, rhs_value_expr)));
+    auto* a = Var("a", lhs_type1, Call(lhs_type2, Call(rhs_type, rhs_value_expr)));
 
     // Self-assign 'a' to force the expression to be resolved so we can test its
     // type below
@@ -466,7 +466,7 @@
                                           testing::ValuesIn(all_types)));
 
 TEST_F(ResolverTypeInitializerValidationTest, ConversionInitializerInvalid_TooManyInitializers) {
-    auto* a = Var("a", ty.f32(), Construct(Source{{12, 34}}, ty.f32(), Expr(1_f), Expr(2_f)));
+    auto* a = Var("a", ty.f32(), Call(Source{{12, 34}}, ty.f32(), Expr(1_f), Expr(2_f)));
     WrapInFunction(a);
 
     ASSERT_FALSE(r()->Resolve());
@@ -474,8 +474,7 @@
 }
 
 TEST_F(ResolverTypeInitializerValidationTest, ConversionInitializerInvalid_InvalidInitializer) {
-    auto* a =
-        Var("a", ty.f32(), Construct(Source{{12, 34}}, ty.f32(), Construct(ty.array<f32, 4>())));
+    auto* a = Var("a", ty.f32(), Call(Source{{12, 34}}, ty.f32(), Call(ty.array<f32, 4>())));
     WrapInFunction(a);
 
     ASSERT_FALSE(r()->Resolve());
@@ -619,9 +618,9 @@
 
 TEST_F(ResolverTypeInitializerValidationTest, InferredArrayU32_VecI32_VecAI) {
     // array(vec2(10i), vec2(20));
-    auto* tc = array(Source{{12, 34}}, nullptr, nullptr,   //
-                     Construct(ty.vec(nullptr, 2), 20_i),  //
-                     Construct(ty.vec(nullptr, 2), 20_a));
+    auto* tc = array(Source{{12, 34}}, nullptr, nullptr,  //
+                     Call(ty.vec(nullptr, 2), 20_i),      //
+                     Call(ty.vec(nullptr, 2), 20_a));
     WrapInFunction(tc);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -641,9 +640,9 @@
 
 TEST_F(ResolverTypeInitializerValidationTest, InferredArrayU32_VecAI_VecF32) {
     // array(vec2(20), vec2(10f));
-    auto* tc = array(Source{{12, 34}}, nullptr, nullptr,   //
-                     Construct(ty.vec(nullptr, 2), 20_a),  //
-                     Construct(ty.vec(nullptr, 2), 20_f));
+    auto* tc = array(Source{{12, 34}}, nullptr, nullptr,  //
+                     Call(ty.vec(nullptr, 2), 20_a),      //
+                     Call(ty.vec(nullptr, 2), 20_f));
     WrapInFunction(tc);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -768,8 +767,7 @@
 
 TEST_F(ResolverTypeInitializerValidationTest, InferredArrayArgumentTypeMismatch_Vec3i32_Vec3AF) {
     // array(vec3<i32>(), vec3(1.0));
-    auto* t =
-        array(Source{{12, 34}}, nullptr, nullptr, vec3<i32>(), Construct(ty.vec3(nullptr), 1._a));
+    auto* t = array(Source{{12, 34}}, nullptr, nullptr, vec3<i32>(), Call(ty.vec3(nullptr), 1._a));
     WrapInFunction(t);
 
     EXPECT_FALSE(r()->Resolve());
@@ -892,7 +890,7 @@
 namespace ScalarInitializer {
 
 TEST_F(ResolverTypeInitializerValidationTest, I32_Success) {
-    auto* expr = Construct<i32>(Expr(123_i));
+    auto* expr = Call<i32>(Expr(123_i));
     WrapInFunction(expr);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -910,7 +908,7 @@
 }
 
 TEST_F(ResolverTypeInitializerValidationTest, U32_Success) {
-    auto* expr = Construct<u32>(Expr(123_u));
+    auto* expr = Call<u32>(Expr(123_u));
     WrapInFunction(expr);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -928,7 +926,7 @@
 }
 
 TEST_F(ResolverTypeInitializerValidationTest, F32_Success) {
-    auto* expr = Construct<f32>(Expr(1.23_f));
+    auto* expr = Call<f32>(Expr(1.23_f));
     WrapInFunction(expr);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -948,7 +946,7 @@
 TEST_F(ResolverTypeInitializerValidationTest, F16_Success) {
     Enable(ast::Extension::kF16);
 
-    auto* expr = Construct<f16>(Expr(1.5_h));
+    auto* expr = Call<f16>(Expr(1.5_h));
     WrapInFunction(expr);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -966,7 +964,7 @@
 }
 
 TEST_F(ResolverTypeInitializerValidationTest, Convert_f32_to_i32_Success) {
-    auto* expr = Construct<i32>(1.23_f);
+    auto* expr = Call<i32>(1.23_f);
     WrapInFunction(expr);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -984,7 +982,7 @@
 }
 
 TEST_F(ResolverTypeInitializerValidationTest, Convert_i32_to_u32_Success) {
-    auto* expr = Construct<u32>(123_i);
+    auto* expr = Call<u32>(123_i);
     WrapInFunction(expr);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -1004,7 +1002,7 @@
 TEST_F(ResolverTypeInitializerValidationTest, Convert_u32_to_f16_Success) {
     Enable(ast::Extension::kF16);
 
-    auto* expr = Construct<f16>(123_u);
+    auto* expr = Call<f16>(123_u);
     WrapInFunction(expr);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -1024,7 +1022,7 @@
 TEST_F(ResolverTypeInitializerValidationTest, Convert_f16_to_f32_Success) {
     Enable(ast::Extension::kF16);
 
-    auto* expr = Construct<f32>(123_h);
+    auto* expr = Call<f32>(123_h);
     WrapInFunction(expr);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -1995,7 +1993,7 @@
 
     // vec2<Float32>(1.0f, 1u)
     auto* vec_type = ty.vec(ty.Of(f32_alias), 2);
-    WrapInFunction(Construct(Source{{12, 34}}, vec_type, 1_f, 1_u));
+    WrapInFunction(Call(Source{{12, 34}}, vec_type, 1_f, 1_u));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_THAT(r()->error(),
@@ -2007,7 +2005,7 @@
 
     // vec2<Float32>(1.0f, 1.0f)
     auto* vec_type = ty.vec(ty.Of(f32_alias), 2);
-    auto* tc = Construct(Source{{12, 34}}, vec_type, 1_f, 1_f);
+    auto* tc = Call(Source{{12, 34}}, vec_type, 1_f, 1_f);
     WrapInFunction(tc);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -2018,7 +2016,7 @@
 
     // vec3<u32>(vec<Float32>(), 1.0f)
     auto* vec_type = ty.vec(ty.Of(f32_alias), 2);
-    WrapInFunction(vec3<u32>(Source{{12, 34}}, Construct(vec_type), 1_f));
+    WrapInFunction(vec3<u32>(Source{{12, 34}}, Call(vec_type), 1_f));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_THAT(r()->error(),
@@ -2030,7 +2028,7 @@
 
     // vec3<f32>(vec<Float32>(), 1.0f)
     auto* vec_type = ty.vec(ty.Of(f32_alias), 2);
-    auto* tc = vec3<f32>(Construct(Source{{12, 34}}, vec_type), 1_f);
+    auto* tc = vec3<f32>(Call(Source{{12, 34}}, vec_type), 1_f);
     WrapInFunction(tc);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -2039,11 +2037,11 @@
 TEST_F(ResolverTypeInitializerValidationTest, InferVec2ElementTypeFromScalars) {
     Enable(ast::Extension::kF16);
 
-    auto* vec2_bool = Construct(create<ast::Vector>(nullptr, 2u), Expr(true), Expr(false));
-    auto* vec2_i32 = Construct(create<ast::Vector>(nullptr, 2u), Expr(1_i), Expr(2_i));
-    auto* vec2_u32 = Construct(create<ast::Vector>(nullptr, 2u), Expr(1_u), Expr(2_u));
-    auto* vec2_f32 = Construct(create<ast::Vector>(nullptr, 2u), Expr(1_f), Expr(2_f));
-    auto* vec2_f16 = Construct(create<ast::Vector>(nullptr, 2u), Expr(1_h), Expr(2_h));
+    auto* vec2_bool = Call(create<ast::Vector>(nullptr, 2u), Expr(true), Expr(false));
+    auto* vec2_i32 = Call(create<ast::Vector>(nullptr, 2u), Expr(1_i), Expr(2_i));
+    auto* vec2_u32 = Call(create<ast::Vector>(nullptr, 2u), Expr(1_u), Expr(2_u));
+    auto* vec2_f32 = Call(create<ast::Vector>(nullptr, 2u), Expr(1_f), Expr(2_f));
+    auto* vec2_f16 = Call(create<ast::Vector>(nullptr, 2u), Expr(1_h), Expr(2_h));
     WrapInFunction(vec2_bool, vec2_i32, vec2_u32, vec2_f32, vec2_f16);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -2073,11 +2071,11 @@
 TEST_F(ResolverTypeInitializerValidationTest, InferVec2ElementTypeFromVec2) {
     Enable(ast::Extension::kF16);
 
-    auto* vec2_bool = Construct(create<ast::Vector>(nullptr, 2u), vec2<bool>(true, false));
-    auto* vec2_i32 = Construct(create<ast::Vector>(nullptr, 2u), vec2<i32>(1_i, 2_i));
-    auto* vec2_u32 = Construct(create<ast::Vector>(nullptr, 2u), vec2<u32>(1_u, 2_u));
-    auto* vec2_f32 = Construct(create<ast::Vector>(nullptr, 2u), vec2<f32>(1_f, 2_f));
-    auto* vec2_f16 = Construct(create<ast::Vector>(nullptr, 2u), vec2<f16>(1_h, 2_h));
+    auto* vec2_bool = Call(create<ast::Vector>(nullptr, 2u), vec2<bool>(true, false));
+    auto* vec2_i32 = Call(create<ast::Vector>(nullptr, 2u), vec2<i32>(1_i, 2_i));
+    auto* vec2_u32 = Call(create<ast::Vector>(nullptr, 2u), vec2<u32>(1_u, 2_u));
+    auto* vec2_f32 = Call(create<ast::Vector>(nullptr, 2u), vec2<f32>(1_f, 2_f));
+    auto* vec2_f16 = Call(create<ast::Vector>(nullptr, 2u), vec2<f16>(1_h, 2_h));
     WrapInFunction(vec2_bool, vec2_i32, vec2_u32, vec2_f32, vec2_f16);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -2107,12 +2105,11 @@
 TEST_F(ResolverTypeInitializerValidationTest, InferVec3ElementTypeFromScalars) {
     Enable(ast::Extension::kF16);
 
-    auto* vec3_bool =
-        Construct(create<ast::Vector>(nullptr, 3u), Expr(true), Expr(false), Expr(true));
-    auto* vec3_i32 = Construct(create<ast::Vector>(nullptr, 3u), Expr(1_i), Expr(2_i), Expr(3_i));
-    auto* vec3_u32 = Construct(create<ast::Vector>(nullptr, 3u), Expr(1_u), Expr(2_u), Expr(3_u));
-    auto* vec3_f32 = Construct(create<ast::Vector>(nullptr, 3u), Expr(1_f), Expr(2_f), Expr(3_f));
-    auto* vec3_f16 = Construct(create<ast::Vector>(nullptr, 3u), Expr(1_h), Expr(2_h), Expr(3_h));
+    auto* vec3_bool = Call(create<ast::Vector>(nullptr, 3u), Expr(true), Expr(false), Expr(true));
+    auto* vec3_i32 = Call(create<ast::Vector>(nullptr, 3u), Expr(1_i), Expr(2_i), Expr(3_i));
+    auto* vec3_u32 = Call(create<ast::Vector>(nullptr, 3u), Expr(1_u), Expr(2_u), Expr(3_u));
+    auto* vec3_f32 = Call(create<ast::Vector>(nullptr, 3u), Expr(1_f), Expr(2_f), Expr(3_f));
+    auto* vec3_f16 = Call(create<ast::Vector>(nullptr, 3u), Expr(1_h), Expr(2_h), Expr(3_h));
     WrapInFunction(vec3_bool, vec3_i32, vec3_u32, vec3_f32, vec3_f16);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -2142,11 +2139,11 @@
 TEST_F(ResolverTypeInitializerValidationTest, InferVec3ElementTypeFromVec3) {
     Enable(ast::Extension::kF16);
 
-    auto* vec3_bool = Construct(create<ast::Vector>(nullptr, 3u), vec3<bool>(true, false, true));
-    auto* vec3_i32 = Construct(create<ast::Vector>(nullptr, 3u), vec3<i32>(1_i, 2_i, 3_i));
-    auto* vec3_u32 = Construct(create<ast::Vector>(nullptr, 3u), vec3<u32>(1_u, 2_u, 3_u));
-    auto* vec3_f32 = Construct(create<ast::Vector>(nullptr, 3u), vec3<f32>(1_f, 2_f, 3_f));
-    auto* vec3_f16 = Construct(create<ast::Vector>(nullptr, 3u), vec3<f16>(1_h, 2_h, 3_h));
+    auto* vec3_bool = Call(create<ast::Vector>(nullptr, 3u), vec3<bool>(true, false, true));
+    auto* vec3_i32 = Call(create<ast::Vector>(nullptr, 3u), vec3<i32>(1_i, 2_i, 3_i));
+    auto* vec3_u32 = Call(create<ast::Vector>(nullptr, 3u), vec3<u32>(1_u, 2_u, 3_u));
+    auto* vec3_f32 = Call(create<ast::Vector>(nullptr, 3u), vec3<f32>(1_f, 2_f, 3_f));
+    auto* vec3_f16 = Call(create<ast::Vector>(nullptr, 3u), vec3<f16>(1_h, 2_h, 3_h));
     WrapInFunction(vec3_bool, vec3_i32, vec3_u32, vec3_f32, vec3_f16);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -2176,12 +2173,11 @@
 TEST_F(ResolverTypeInitializerValidationTest, InferVec3ElementTypeFromScalarAndVec2) {
     Enable(ast::Extension::kF16);
 
-    auto* vec3_bool =
-        Construct(create<ast::Vector>(nullptr, 3u), Expr(true), vec2<bool>(false, true));
-    auto* vec3_i32 = Construct(create<ast::Vector>(nullptr, 3u), Expr(1_i), vec2<i32>(2_i, 3_i));
-    auto* vec3_u32 = Construct(create<ast::Vector>(nullptr, 3u), Expr(1_u), vec2<u32>(2_u, 3_u));
-    auto* vec3_f32 = Construct(create<ast::Vector>(nullptr, 3u), Expr(1_f), vec2<f32>(2_f, 3_f));
-    auto* vec3_f16 = Construct(create<ast::Vector>(nullptr, 3u), Expr(1_h), vec2<f16>(2_h, 3_h));
+    auto* vec3_bool = Call(create<ast::Vector>(nullptr, 3u), Expr(true), vec2<bool>(false, true));
+    auto* vec3_i32 = Call(create<ast::Vector>(nullptr, 3u), Expr(1_i), vec2<i32>(2_i, 3_i));
+    auto* vec3_u32 = Call(create<ast::Vector>(nullptr, 3u), Expr(1_u), vec2<u32>(2_u, 3_u));
+    auto* vec3_f32 = Call(create<ast::Vector>(nullptr, 3u), Expr(1_f), vec2<f32>(2_f, 3_f));
+    auto* vec3_f16 = Call(create<ast::Vector>(nullptr, 3u), Expr(1_h), vec2<f16>(2_h, 3_h));
     WrapInFunction(vec3_bool, vec3_i32, vec3_u32, vec3_f32, vec3_f16);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -2211,16 +2207,16 @@
 TEST_F(ResolverTypeInitializerValidationTest, InferVec4ElementTypeFromScalars) {
     Enable(ast::Extension::kF16);
 
-    auto* vec4_bool = Construct(create<ast::Vector>(nullptr, 4u), Expr(true), Expr(false),
-                                Expr(true), Expr(false));
+    auto* vec4_bool =
+        Call(create<ast::Vector>(nullptr, 4u), Expr(true), Expr(false), Expr(true), Expr(false));
     auto* vec4_i32 =
-        Construct(create<ast::Vector>(nullptr, 4u), Expr(1_i), Expr(2_i), Expr(3_i), Expr(4_i));
+        Call(create<ast::Vector>(nullptr, 4u), Expr(1_i), Expr(2_i), Expr(3_i), Expr(4_i));
     auto* vec4_u32 =
-        Construct(create<ast::Vector>(nullptr, 4u), Expr(1_u), Expr(2_u), Expr(3_u), Expr(4_u));
+        Call(create<ast::Vector>(nullptr, 4u), Expr(1_u), Expr(2_u), Expr(3_u), Expr(4_u));
     auto* vec4_f32 =
-        Construct(create<ast::Vector>(nullptr, 4u), Expr(1_f), Expr(2_f), Expr(3_f), Expr(4_f));
+        Call(create<ast::Vector>(nullptr, 4u), Expr(1_f), Expr(2_f), Expr(3_f), Expr(4_f));
     auto* vec4_f16 =
-        Construct(create<ast::Vector>(nullptr, 4u), Expr(1_h), Expr(2_h), Expr(3_h), Expr(4_h));
+        Call(create<ast::Vector>(nullptr, 4u), Expr(1_h), Expr(2_h), Expr(3_h), Expr(4_h));
     WrapInFunction(vec4_bool, vec4_i32, vec4_u32, vec4_f32, vec4_f16);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -2250,12 +2246,11 @@
 TEST_F(ResolverTypeInitializerValidationTest, InferVec4ElementTypeFromVec4) {
     Enable(ast::Extension::kF16);
 
-    auto* vec4_bool =
-        Construct(create<ast::Vector>(nullptr, 4u), vec4<bool>(true, false, true, false));
-    auto* vec4_i32 = Construct(create<ast::Vector>(nullptr, 4u), vec4<i32>(1_i, 2_i, 3_i, 4_i));
-    auto* vec4_u32 = Construct(create<ast::Vector>(nullptr, 4u), vec4<u32>(1_u, 2_u, 3_u, 4_u));
-    auto* vec4_f32 = Construct(create<ast::Vector>(nullptr, 4u), vec4<f32>(1_f, 2_f, 3_f, 4_f));
-    auto* vec4_f16 = Construct(create<ast::Vector>(nullptr, 4u), vec4<f16>(1_h, 2_h, 3_h, 4_h));
+    auto* vec4_bool = Call(create<ast::Vector>(nullptr, 4u), vec4<bool>(true, false, true, false));
+    auto* vec4_i32 = Call(create<ast::Vector>(nullptr, 4u), vec4<i32>(1_i, 2_i, 3_i, 4_i));
+    auto* vec4_u32 = Call(create<ast::Vector>(nullptr, 4u), vec4<u32>(1_u, 2_u, 3_u, 4_u));
+    auto* vec4_f32 = Call(create<ast::Vector>(nullptr, 4u), vec4<f32>(1_f, 2_f, 3_f, 4_f));
+    auto* vec4_f16 = Call(create<ast::Vector>(nullptr, 4u), vec4<f16>(1_h, 2_h, 3_h, 4_h));
     WrapInFunction(vec4_bool, vec4_i32, vec4_u32, vec4_f32, vec4_f16);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -2286,15 +2281,11 @@
     Enable(ast::Extension::kF16);
 
     auto* vec4_bool =
-        Construct(create<ast::Vector>(nullptr, 4u), Expr(true), vec3<bool>(false, true, false));
-    auto* vec4_i32 =
-        Construct(create<ast::Vector>(nullptr, 4u), Expr(1_i), vec3<i32>(2_i, 3_i, 4_i));
-    auto* vec4_u32 =
-        Construct(create<ast::Vector>(nullptr, 4u), Expr(1_u), vec3<u32>(2_u, 3_u, 4_u));
-    auto* vec4_f32 =
-        Construct(create<ast::Vector>(nullptr, 4u), Expr(1_f), vec3<f32>(2_f, 3_f, 4_f));
-    auto* vec4_f16 =
-        Construct(create<ast::Vector>(nullptr, 4u), Expr(1_h), vec3<f16>(2_h, 3_h, 4_h));
+        Call(create<ast::Vector>(nullptr, 4u), Expr(true), vec3<bool>(false, true, false));
+    auto* vec4_i32 = Call(create<ast::Vector>(nullptr, 4u), Expr(1_i), vec3<i32>(2_i, 3_i, 4_i));
+    auto* vec4_u32 = Call(create<ast::Vector>(nullptr, 4u), Expr(1_u), vec3<u32>(2_u, 3_u, 4_u));
+    auto* vec4_f32 = Call(create<ast::Vector>(nullptr, 4u), Expr(1_f), vec3<f32>(2_f, 3_f, 4_f));
+    auto* vec4_f16 = Call(create<ast::Vector>(nullptr, 4u), Expr(1_h), vec3<f16>(2_h, 3_h, 4_h));
     WrapInFunction(vec4_bool, vec4_i32, vec4_u32, vec4_f32, vec4_f16);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -2324,16 +2315,16 @@
 TEST_F(ResolverTypeInitializerValidationTest, InferVec4ElementTypeFromVec2AndVec2) {
     Enable(ast::Extension::kF16);
 
-    auto* vec4_bool = Construct(create<ast::Vector>(nullptr, 4u), vec2<bool>(true, false),
-                                vec2<bool>(true, false));
+    auto* vec4_bool =
+        Call(create<ast::Vector>(nullptr, 4u), vec2<bool>(true, false), vec2<bool>(true, false));
     auto* vec4_i32 =
-        Construct(create<ast::Vector>(nullptr, 4u), vec2<i32>(1_i, 2_i), vec2<i32>(3_i, 4_i));
+        Call(create<ast::Vector>(nullptr, 4u), vec2<i32>(1_i, 2_i), vec2<i32>(3_i, 4_i));
     auto* vec4_u32 =
-        Construct(create<ast::Vector>(nullptr, 4u), vec2<u32>(1_u, 2_u), vec2<u32>(3_u, 4_u));
+        Call(create<ast::Vector>(nullptr, 4u), vec2<u32>(1_u, 2_u), vec2<u32>(3_u, 4_u));
     auto* vec4_f32 =
-        Construct(create<ast::Vector>(nullptr, 4u), vec2<f32>(1_f, 2_f), vec2<f32>(3_f, 4_f));
+        Call(create<ast::Vector>(nullptr, 4u), vec2<f32>(1_f, 2_f), vec2<f32>(3_f, 4_f));
     auto* vec4_f16 =
-        Construct(create<ast::Vector>(nullptr, 4u), vec2<f16>(1_h, 2_h), vec2<f16>(3_h, 4_h));
+        Call(create<ast::Vector>(nullptr, 4u), vec2<f16>(1_h, 2_h), vec2<f16>(3_h, 4_h));
     WrapInFunction(vec4_bool, vec4_i32, vec4_u32, vec4_f32, vec4_f16);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -2361,26 +2352,26 @@
 }
 
 TEST_F(ResolverTypeInitializerValidationTest, CannotInferVectorElementTypeWithoutArgs) {
-    WrapInFunction(Construct(Source{{12, 34}}, create<ast::Vector>(nullptr, 3u)));
+    WrapInFunction(Call(Source{{12, 34}}, create<ast::Vector>(nullptr, 3u)));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_THAT(r()->error(), HasSubstr("12:34 error: no matching initializer for vec3()"));
 }
 
 TEST_F(ResolverTypeInitializerValidationTest, CannotInferVec2ElementTypeFromScalarsMismatch) {
-    WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 2u),
-                             Expr(Source{{1, 2}}, 1_i),  //
-                             Expr(Source{{1, 3}}, 2_u)));
+    WrapInFunction(Call(Source{{1, 1}}, create<ast::Vector>(nullptr, 2u),
+                        Expr(Source{{1, 2}}, 1_i),  //
+                        Expr(Source{{1, 3}}, 2_u)));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_THAT(r()->error(), HasSubstr("1:1 error: no matching initializer for vec2(i32, u32)"));
 }
 
 TEST_F(ResolverTypeInitializerValidationTest, CannotInferVec3ElementTypeFromScalarsMismatch) {
-    WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 3u),
-                             Expr(Source{{1, 2}}, 1_i),  //
-                             Expr(Source{{1, 3}}, 2_u),  //
-                             Expr(Source{{1, 4}}, 3_i)));
+    WrapInFunction(Call(Source{{1, 1}}, create<ast::Vector>(nullptr, 3u),
+                        Expr(Source{{1, 2}}, 1_i),  //
+                        Expr(Source{{1, 3}}, 2_u),  //
+                        Expr(Source{{1, 4}}, 3_i)));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_THAT(r()->error(),
@@ -2388,9 +2379,9 @@
 }
 
 TEST_F(ResolverTypeInitializerValidationTest, CannotInferVec3ElementTypeFromScalarAndVec2Mismatch) {
-    WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 3u),
-                             Expr(Source{{1, 2}}, 1_i),  //
-                             Construct(Source{{1, 3}}, ty.vec2<f32>(), 2_f, 3_f)));
+    WrapInFunction(Call(Source{{1, 1}}, create<ast::Vector>(nullptr, 3u),
+                        Expr(Source{{1, 2}}, 1_i),  //
+                        Call(Source{{1, 3}}, ty.vec2<f32>(), 2_f, 3_f)));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_THAT(r()->error(),
@@ -2398,11 +2389,11 @@
 }
 
 TEST_F(ResolverTypeInitializerValidationTest, CannotInferVec4ElementTypeFromScalarsMismatch) {
-    WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 4u),
-                             Expr(Source{{1, 2}}, 1_i),  //
-                             Expr(Source{{1, 3}}, 2_i),  //
-                             Expr(Source{{1, 4}}, 3_f),  //
-                             Expr(Source{{1, 5}}, 4_i)));
+    WrapInFunction(Call(Source{{1, 1}}, create<ast::Vector>(nullptr, 4u),
+                        Expr(Source{{1, 2}}, 1_i),  //
+                        Expr(Source{{1, 3}}, 2_i),  //
+                        Expr(Source{{1, 4}}, 3_f),  //
+                        Expr(Source{{1, 5}}, 4_i)));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_THAT(r()->error(),
@@ -2410,9 +2401,9 @@
 }
 
 TEST_F(ResolverTypeInitializerValidationTest, CannotInferVec4ElementTypeFromScalarAndVec3Mismatch) {
-    WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 4u),
-                             Expr(Source{{1, 2}}, 1_i),  //
-                             Construct(Source{{1, 3}}, ty.vec3<u32>(), 2_u, 3_u, 4_u)));
+    WrapInFunction(Call(Source{{1, 1}}, create<ast::Vector>(nullptr, 4u),
+                        Expr(Source{{1, 2}}, 1_i),  //
+                        Call(Source{{1, 3}}, ty.vec3<u32>(), 2_u, 3_u, 4_u)));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_THAT(r()->error(),
@@ -2420,9 +2411,9 @@
 }
 
 TEST_F(ResolverTypeInitializerValidationTest, CannotInferVec4ElementTypeFromVec2AndVec2Mismatch) {
-    WrapInFunction(Construct(Source{{1, 1}}, create<ast::Vector>(nullptr, 4u),
-                             Construct(Source{{1, 2}}, ty.vec2<i32>(), 3_i, 4_i),  //
-                             Construct(Source{{1, 3}}, ty.vec2<u32>(), 3_u, 4_u)));
+    WrapInFunction(Call(Source{{1, 1}}, create<ast::Vector>(nullptr, 4u),
+                        Call(Source{{1, 2}}, ty.vec2<i32>(), 3_i, 4_i),  //
+                        Call(Source{{1, 3}}, ty.vec2<u32>(), 3_u, 4_u)));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_THAT(r()->error(),
@@ -2478,7 +2469,7 @@
     utils::Vector<const ast::Expression*, 8> args;
     for (uint32_t i = 0; i < param.columns - 1; i++) {
         auto* vec_type = param.create_column_ast_type(*this);
-        args.Push(Construct(vec_type));
+        args.Push(Call(vec_type));
         if (i > 0) {
             args_tys << ", ";
         }
@@ -2486,7 +2477,7 @@
     }
 
     auto* matrix_type = param.create_mat_ast_type(*this);
-    auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
+    auto* tc = Call(Source{{12, 34}}, matrix_type, std::move(args));
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -2506,7 +2497,7 @@
     std::stringstream args_tys;
     utils::Vector<const ast::Expression*, 8> args;
     for (uint32_t i = 0; i < param.columns * param.rows - 1; i++) {
-        args.Push(Construct(param.create_element_ast_type(*this)));
+        args.Push(Call(param.create_element_ast_type(*this)));
         if (i > 0) {
             args_tys << ", ";
         }
@@ -2514,7 +2505,7 @@
     }
 
     auto* matrix_type = param.create_mat_ast_type(*this);
-    auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
+    auto* tc = Call(Source{{12, 34}}, matrix_type, std::move(args));
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -2535,7 +2526,7 @@
     utils::Vector<const ast::Expression*, 8> args;
     for (uint32_t i = 0; i < param.columns + 1; i++) {
         auto* vec_type = param.create_column_ast_type(*this);
-        args.Push(Construct(vec_type));
+        args.Push(Call(vec_type));
         if (i > 0) {
             args_tys << ", ";
         }
@@ -2543,7 +2534,7 @@
     }
 
     auto* matrix_type = param.create_mat_ast_type(*this);
-    auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
+    auto* tc = Call(Source{{12, 34}}, matrix_type, std::move(args));
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -2563,7 +2554,7 @@
     std::stringstream args_tys;
     utils::Vector<const ast::Expression*, 8> args;
     for (uint32_t i = 0; i < param.columns * param.rows + 1; i++) {
-        args.Push(Construct(param.create_element_ast_type(*this)));
+        args.Push(Call(param.create_element_ast_type(*this)));
         if (i > 0) {
             args_tys << ", ";
         }
@@ -2571,7 +2562,7 @@
     }
 
     auto* matrix_type = param.create_mat_ast_type(*this);
-    auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
+    auto* tc = Call(Source{{12, 34}}, matrix_type, std::move(args));
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -2591,7 +2582,7 @@
     utils::Vector<const ast::Expression*, 8> args;
     for (uint32_t i = 0; i < param.columns; i++) {
         auto* vec_type = ty.vec<u32>(param.rows);
-        args.Push(Construct(vec_type));
+        args.Push(Call(vec_type));
         if (i > 0) {
             args_tys << ", ";
         }
@@ -2599,7 +2590,7 @@
     }
 
     auto* matrix_type = param.create_mat_ast_type(*this);
-    auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
+    auto* tc = Call(Source{{12, 34}}, matrix_type, std::move(args));
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -2626,7 +2617,7 @@
     }
 
     auto* matrix_type = param.create_mat_ast_type(*this);
-    auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
+    auto* tc = Call(Source{{12, 34}}, matrix_type, std::move(args));
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -2652,7 +2643,7 @@
     utils::Vector<const ast::Expression*, 8> args;
     for (uint32_t i = 0; i < param.columns; i++) {
         auto* valid_vec_type = param.create_column_ast_type(*this);
-        args.Push(Construct(valid_vec_type));
+        args.Push(Call(valid_vec_type));
         if (i > 0) {
             args_tys << ", ";
         }
@@ -2660,11 +2651,11 @@
     }
     const size_t kInvalidLoc = 2 * (param.columns - 1);
     auto* invalid_vec_type = ty.vec(param.create_element_ast_type(*this), param.rows - 1);
-    args.Push(Construct(Source{{12, kInvalidLoc}}, invalid_vec_type));
+    args.Push(Call(Source{{12, kInvalidLoc}}, invalid_vec_type));
     args_tys << ", vec" << (param.rows - 1) << "<" + element_type_name + ">";
 
     auto* matrix_type = param.create_mat_ast_type(*this);
-    auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
+    auto* tc = Call(Source{{12, 34}}, matrix_type, std::move(args));
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -2690,18 +2681,18 @@
     utils::Vector<const ast::Expression*, 8> args;
     for (uint32_t i = 0; i < param.columns; i++) {
         auto* valid_vec_type = param.create_column_ast_type(*this);
-        args.Push(Construct(valid_vec_type));
+        args.Push(Call(valid_vec_type));
         if (i > 0) {
             args_tys << ", ";
         }
         args_tys << "vec" << param.rows << "<" + element_type_name + ">";
     }
     auto* invalid_vec_type = ty.vec(param.create_element_ast_type(*this), param.rows + 1);
-    args.Push(Construct(invalid_vec_type));
+    args.Push(Call(invalid_vec_type));
     args_tys << ", vec" << (param.rows + 1) << "<" + element_type_name + ">";
 
     auto* matrix_type = param.create_mat_ast_type(*this);
-    auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
+    auto* tc = Call(Source{{12, 34}}, matrix_type, std::move(args));
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -2718,7 +2709,7 @@
     Enable(ast::Extension::kF16);
 
     auto* matrix_type = param.create_mat_ast_type(*this);
-    auto* tc = Construct(Source{{12, 40}}, matrix_type);
+    auto* tc = Call(Source{{12, 40}}, matrix_type);
     WrapInFunction(tc);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -2735,11 +2726,11 @@
     utils::Vector<const ast::Expression*, 4> args;
     for (uint32_t i = 0; i < param.columns; i++) {
         auto* vec_type = param.create_column_ast_type(*this);
-        args.Push(Construct(vec_type));
+        args.Push(Call(vec_type));
     }
 
     auto* matrix_type = param.create_mat_ast_type(*this);
-    auto* tc = Construct(matrix_type, std::move(args));
+    auto* tc = Call(matrix_type, std::move(args));
     WrapInFunction(tc);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -2755,11 +2746,11 @@
 
     utils::Vector<const ast::Expression*, 16> args;
     for (uint32_t i = 0; i < param.columns * param.rows; i++) {
-        args.Push(Construct(param.create_element_ast_type(*this)));
+        args.Push(Call(param.create_element_ast_type(*this)));
     }
 
     auto* matrix_type = param.create_mat_ast_type(*this);
-    auto* tc = Construct(matrix_type, std::move(args));
+    auto* tc = Call(matrix_type, std::move(args));
     WrapInFunction(tc);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -2779,7 +2770,7 @@
     utils::Vector<const ast::Expression*, 4> args;
     for (uint32_t i = 0; i < param.columns; i++) {
         auto* vec_type = ty.vec(ty.u32(), param.rows);
-        args.Push(Construct(vec_type));
+        args.Push(Call(vec_type));
         if (i > 0) {
             args_tys << ", ";
         }
@@ -2787,7 +2778,7 @@
     }
 
     auto* matrix_type = ty.mat(ty.Of(elem_type_alias), param.columns, param.rows);
-    auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
+    auto* tc = Call(Source{{12, 34}}, matrix_type, std::move(args));
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -2808,11 +2799,11 @@
     utils::Vector<const ast::Expression*, 8> args;
     for (uint32_t i = 0; i < param.columns; i++) {
         auto* vec_type = param.create_column_ast_type(*this);
-        args.Push(Construct(vec_type));
+        args.Push(Call(vec_type));
     }
 
     auto* matrix_type = ty.mat(ty.Of(elem_type_alias), param.columns, param.rows);
-    auto* tc = Construct(Source{}, matrix_type, std::move(args));
+    auto* tc = Call(Source{}, matrix_type, std::move(args));
     WrapInFunction(tc);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -2820,7 +2811,7 @@
 
 TEST_F(ResolverTypeInitializerValidationTest, MatrixInitializer_ArgumentTypeAlias_Error) {
     auto* alias = Alias("VectorUnsigned2", ty.vec2<u32>());
-    auto* tc = Construct(Source{{12, 34}}, ty.mat2x2<f32>(), Construct(ty.Of(alias)), vec2<f32>());
+    auto* tc = Call(Source{{12, 34}}, ty.mat2x2<f32>(), Call(ty.Of(alias)), vec2<f32>());
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -2840,10 +2831,10 @@
 
     utils::Vector<const ast::Expression*, 4> args;
     for (uint32_t i = 0; i < param.columns; i++) {
-        args.Push(Construct(ty.Of(vec_alias)));
+        args.Push(Call(ty.Of(vec_alias)));
     }
 
-    auto* tc = Construct(Source{}, matrix_type, std::move(args));
+    auto* tc = Call(Source{}, matrix_type, std::move(args));
     WrapInFunction(tc);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -2861,14 +2852,14 @@
     utils::Vector<const ast::Expression*, 4> args;
     for (uint32_t i = 0; i < param.columns; i++) {
         auto* vec_type = ty.vec(ty.Of(u32_type_alias), param.rows);
-        args.Push(Construct(vec_type));
+        args.Push(Call(vec_type));
         if (i > 0) {
             args_tys << ", ";
         }
         args_tys << "vec" << param.rows << "<u32>";
     }
 
-    auto* tc = Construct(Source{{12, 34}}, matrix_type, std::move(args));
+    auto* tc = Call(Source{{12, 34}}, matrix_type, std::move(args));
     WrapInFunction(tc);
 
     EXPECT_FALSE(r()->Resolve());
@@ -2886,11 +2877,11 @@
     utils::Vector<const ast::Expression*, 4> args;
     for (uint32_t i = 0; i < param.columns; i++) {
         auto* vec_type = ty.vec(ty.Of(elem_type_alias), param.rows);
-        args.Push(Construct(vec_type));
+        args.Push(Call(vec_type));
     }
 
     auto* matrix_type = param.create_mat_ast_type(*this);
-    auto* tc = Construct(Source{}, matrix_type, std::move(args));
+    auto* tc = Call(Source{}, matrix_type, std::move(args));
     WrapInFunction(tc);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -2903,11 +2894,11 @@
 
     utils::Vector<const ast::Expression*, 8> args;
     for (uint32_t i = 0; i < param.columns; i++) {
-        args.Push(Construct(param.create_column_ast_type(*this)));
+        args.Push(Call(param.create_column_ast_type(*this)));
     }
 
     auto* matrix_type = create<ast::Matrix>(nullptr, param.rows, param.columns);
-    auto* tc = Construct(Source{}, matrix_type, std::move(args));
+    auto* tc = Call(Source{}, matrix_type, std::move(args));
     WrapInFunction(tc);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -2924,7 +2915,7 @@
     }
 
     auto* matrix_type = create<ast::Matrix>(nullptr, param.rows, param.columns);
-    WrapInFunction(Construct(Source{{12, 34}}, matrix_type, std::move(args)));
+    WrapInFunction(Call(Source{{12, 34}}, matrix_type, std::move(args)));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -2945,16 +2936,16 @@
         }
         if (i == 1) {
             // Odd one out
-            args.Push(Construct(ty.vec<i32>(param.rows)));
+            args.Push(Call(ty.vec<i32>(param.rows)));
             err << "vec" << param.rows << "<i32>";
         } else {
-            args.Push(Construct(param.create_column_ast_type(*this)));
+            args.Push(Call(param.create_column_ast_type(*this)));
             err << "vec" << param.rows << "<" + param.get_element_type_name() + ">";
         }
     }
 
     auto* matrix_type = create<ast::Matrix>(nullptr, param.rows, param.columns);
-    WrapInFunction(Construct(Source{{12, 34}}, matrix_type, std::move(args)));
+    WrapInFunction(Call(Source{{12, 34}}, matrix_type, std::move(args)));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_THAT(r()->error(), HasSubstr(err.str()));
@@ -2986,7 +2977,7 @@
     err << ")";
 
     auto* matrix_type = create<ast::Matrix>(nullptr, param.rows, param.columns);
-    WrapInFunction(Construct(Source{{12, 34}}, matrix_type, std::move(args)));
+    WrapInFunction(Call(Source{{12, 34}}, matrix_type, std::move(args)));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_THAT(r()->error(), HasSubstr(err.str()));
@@ -3066,7 +3057,7 @@
         }
     }
     auto* s = Structure("s", members);
-    auto* tc = Construct(Source{{12, 34}}, ty.Of(s), values);
+    auto* tc = Call(Source{{12, 34}}, ty.Of(s), values);
     WrapInFunction(tc);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: struct initializer has too few inputs: expected " +
@@ -3091,7 +3082,7 @@
         values.Push(ctor_value_expr);
     }
     auto* s = Structure("s", members);
-    auto* tc = Construct(Source{{12, 34}}, ty.Of(s), values);
+    auto* tc = Call(Source{{12, 34}}, ty.Of(s), values);
     WrapInFunction(tc);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: struct initializer has too many inputs: expected " +
@@ -3130,7 +3121,7 @@
         values.Push(ctor_value_expr);
     }
     auto* s = Structure("s", members);
-    auto* tc = Construct(ty.Of(s), values);
+    auto* tc = Call(ty.Of(s), values);
     WrapInFunction(tc);
 
     std::string found = FriendlyName(ctor_params.ast(*this));
@@ -3157,7 +3148,7 @@
     auto* m2 = Member("m2", ty.i32());
     auto* s = Structure("s", utils::Vector{m0, m1, m2});
 
-    auto* tc = Construct(Source{{12, 34}}, ty.Of(s), 1_i, 1_i, 1_i);
+    auto* tc = Call(Source{{12, 34}}, ty.Of(s), 1_i, 1_i, 1_i);
     WrapInFunction(tc);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -3168,7 +3159,7 @@
 TEST_F(ResolverTypeInitializerValidationTest, Struct) {
     auto* m = Member("m", ty.i32());
     auto* s = Structure("MyInputs", utils::Vector{m});
-    auto* tc = Construct(Source{{12, 34}}, ty.Of(s));
+    auto* tc = Call(Source{{12, 34}}, ty.Of(s));
     WrapInFunction(tc);
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -3180,21 +3171,20 @@
                                    Member("c", ty.vec3<i32>()),
                                });
 
-    WrapInFunction(Construct(ty.Of(str)));
+    WrapInFunction(Call(ty.Of(str)));
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 }  // namespace StructInitializer
 
 TEST_F(ResolverTypeInitializerValidationTest, NonConstructibleType_Atomic) {
-    WrapInFunction(Assign(Phony(), Construct(Source{{12, 34}}, ty.atomic(ty.i32()))));
+    WrapInFunction(Assign(Phony(), Call(Source{{12, 34}}, ty.atomic(ty.i32()))));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: type is not constructible");
 }
 
 TEST_F(ResolverTypeInitializerValidationTest, NonConstructibleType_AtomicArray) {
-    WrapInFunction(
-        Assign(Phony(), Construct(Source{{12, 34}}, ty.array(ty.atomic(ty.i32()), 4_i))));
+    WrapInFunction(Assign(Phony(), Call(Source{{12, 34}}, ty.array(ty.atomic(ty.i32()), 4_i))));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array initializer has non-constructible element type");
@@ -3202,7 +3192,7 @@
 
 TEST_F(ResolverTypeInitializerValidationTest, NonConstructibleType_AtomicStructMember) {
     auto* str = Structure("S", utils::Vector{Member("a", ty.atomic(ty.i32()))});
-    WrapInFunction(Assign(Phony(), Construct(Source{{12, 34}}, ty.Of(str))));
+    WrapInFunction(Assign(Phony(), Call(Source{{12, 34}}, ty.Of(str))));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: struct initializer has non-constructible type");
@@ -3210,7 +3200,7 @@
 
 TEST_F(ResolverTypeInitializerValidationTest, NonConstructibleType_Sampler) {
     WrapInFunction(
-        Assign(Phony(), Construct(Source{{12, 34}}, ty.sampler(type::SamplerKind::kSampler))));
+        Assign(Phony(), Call(Source{{12, 34}}, ty.sampler(type::SamplerKind::kSampler))));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: type is not constructible");
@@ -3224,7 +3214,7 @@
 }
 
 TEST_F(ResolverTypeInitializerValidationTest, TypeConversionAsStatement) {
-    WrapInFunction(CallStmt(Construct(Source{{12, 34}}, ty.f32(), 1_i)));
+    WrapInFunction(CallStmt(Call(Source{{12, 34}}, ty.f32(), 1_i)));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: type conversion evaluated but not used");
diff --git a/src/tint/resolver/type_validation_test.cc b/src/tint/resolver/type_validation_test.cc
index 1b2597c..d8c1630 100644
--- a/src/tint/resolver/type_validation_test.cc
+++ b/src/tint/resolver/type_validation_test.cc
@@ -102,7 +102,7 @@
 
 TEST_F(ResolverTypeValidationTest, GlobalConstNoAddressSpace_Pass) {
     // const global_const: f32 = f32();
-    GlobalConst(Source{{12, 34}}, "global_const", ty.f32(), Construct(ty.f32()));
+    GlobalConst(Source{{12, 34}}, "global_const", ty.f32(), Call<f32>());
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -297,7 +297,7 @@
 
 TEST_F(ResolverTypeValidationTest, ArraySize_IVecLiteral) {
     // var<private> a : array<f32, vec2<i32>(10, 10)>;
-    GlobalVar("a", ty.array(ty.f32(), Construct(Source{{12, 34}}, ty.vec2<i32>(), 10_i, 10_i)),
+    GlobalVar("a", ty.array(ty.f32(), Call(Source{{12, 34}}, ty.vec2<i32>(), 10_i, 10_i)),
               type::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -322,7 +322,7 @@
 TEST_F(ResolverTypeValidationTest, ArraySize_IVecConst) {
     // const size = vec2<i32>(100, 100);
     // var<private> a : array<f32, size>;
-    GlobalConst("size", Construct(ty.vec2<i32>(), 100_i, 100_i));
+    GlobalConst("size", Call(ty.vec2<i32>(), 100_i, 100_i));
     GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")),
               type::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
@@ -580,7 +580,7 @@
 
 TEST_F(ResolverTypeValidationTest, ArraySize_ComplexExpr) {
     // var a : array<f32, i32(4i)>;
-    auto* a = Var("a", ty.array(ty.f32(), Construct(Source{{12, 34}}, ty.i32(), 4_i)));
+    auto* a = Var("a", ty.array(ty.f32(), Call(Source{{12, 34}}, ty.i32(), 4_i)));
     WrapInFunction(a);
     EXPECT_TRUE(r()->Resolve());
 }
@@ -1437,7 +1437,7 @@
 
     Enable(ast::Extension::kF16);
 
-    WrapInFunction(Decl(Var("v", params.type(*this), Construct(ty(params.alias)))));
+    WrapInFunction(Decl(Var("v", params.type(*this), Call(ty(params.alias)))));
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 INSTANTIATE_TEST_SUITE_P(ResolverTypeValidationTest,
diff --git a/src/tint/resolver/validation_test.cc b/src/tint/resolver/validation_test.cc
index 96fdd4f..128feb5 100644
--- a/src/tint/resolver/validation_test.cc
+++ b/src/tint/resolver/validation_test.cc
@@ -1267,8 +1267,7 @@
 
 TEST_F(ResolverTest, Expr_Initializer_Cast_Pointer) {
     auto* vf = Var("vf", ty.f32());
-    auto* c =
-        Construct(Source{{12, 34}}, ty.pointer<i32>(type::AddressSpace::kFunction), ExprList(vf));
+    auto* c = Call(Source{{12, 34}}, ty.pointer<i32>(type::AddressSpace::kFunction), ExprList(vf));
     auto* ip = Let("ip", ty.pointer<i32>(type::AddressSpace::kFunction), c);
     WrapInFunction(Decl(vf), Decl(ip));
 
diff --git a/src/tint/resolver/variable_test.cc b/src/tint/resolver/variable_test.cc
index 8dcff0f..9d00a5a 100644
--- a/src/tint/resolver/variable_test.cc
+++ b/src/tint/resolver/variable_test.cc
@@ -116,8 +116,8 @@
     auto* f_c = Expr(1_f);
     auto* h_c = Expr(1_h);
     auto* b_c = Expr(true);
-    auto* s_c = Construct(ty.Of(S), Expr(1_i));
-    auto* a_c = Construct(ty.Of(A), Expr(1_i));
+    auto* s_c = Call(ty.Of(S), Expr(1_i));
+    auto* a_c = Call(ty.Of(A), Expr(1_i));
 
     auto* i = Var("i", ty.i32(), i_c);
     auto* u = Var("u", ty.u32(), u_c);
@@ -410,8 +410,8 @@
     auto* f_c = Expr(1_f);
     auto* h_c = Expr(1_h);
     auto* b_c = Expr(true);
-    auto* s_c = Construct(ty.Of(S), Expr(1_i));
-    auto* a_c = Construct(ty.Of(A), Expr(1_i));
+    auto* s_c = Call(ty.Of(S), Expr(1_i));
+    auto* a_c = Call(ty.Of(A), Expr(1_i));
     auto* p_c = AddressOf(v);
 
     auto* i = Let("i", ty.i32(), i_c);
@@ -902,7 +902,7 @@
     auto* c_vu32 = Const("e", ty.vec3<u32>(), vec3<u32>());
     auto* c_vf32 = Const("f", ty.vec3<f32>(), vec3<f32>());
     auto* c_mf32 = Const("g", ty.mat3x3<f32>(), mat3x3<f32>());
-    auto* c_s = Const("h", ty("S"), Construct(ty("S")));
+    auto* c_s = Const("h", ty("S"), Call(ty("S")));
 
     WrapInFunction(c_i32, c_u32, c_f32, c_vi32, c_vu32, c_vf32, c_mf32, c_s);
 
@@ -947,14 +947,14 @@
     auto* c_vi32 = Const("f", vec3<i32>());
     auto* c_vu32 = Const("g", vec3<u32>());
     auto* c_vf32 = Const("h", vec3<f32>());
-    auto* c_vai = Const("i", Construct(ty.vec(nullptr, 3), Expr(0_a)));
-    auto* c_vaf = Const("j", Construct(ty.vec(nullptr, 3), Expr(0._a)));
+    auto* c_vai = Const("i", Call(ty.vec(nullptr, 3), Expr(0_a)));
+    auto* c_vaf = Const("j", Call(ty.vec(nullptr, 3), Expr(0._a)));
     auto* c_mf32 = Const("k", mat3x3<f32>());
-    auto* c_maf32 = Const("l", Construct(ty.mat(nullptr, 3, 3),  //
-                                         Construct(ty.vec(nullptr, 3), Expr(0._a)),
-                                         Construct(ty.vec(nullptr, 3), Expr(0._a)),
-                                         Construct(ty.vec(nullptr, 3), Expr(0._a))));
-    auto* c_s = Const("m", Construct(ty("S")));
+    auto* c_maf32 =
+        Const("l", Call(ty.mat(nullptr, 3, 3),  //
+                        Call(ty.vec(nullptr, 3), Expr(0._a)), Call(ty.vec(nullptr, 3), Expr(0._a)),
+                        Call(ty.vec(nullptr, 3), Expr(0._a))));
+    auto* c_s = Const("m", Call(ty("S")));
 
     WrapInFunction(c_i32, c_u32, c_f32, c_ai, c_af, c_vi32, c_vu32, c_vf32, c_vai, c_vaf, c_mf32,
                    c_maf32, c_s);
@@ -1123,13 +1123,13 @@
     auto* c_vi32 = GlobalConst("f", vec3<i32>());
     auto* c_vu32 = GlobalConst("g", vec3<u32>());
     auto* c_vf32 = GlobalConst("h", vec3<f32>());
-    auto* c_vai = GlobalConst("i", Construct(ty.vec(nullptr, 3), Expr(0_a)));
-    auto* c_vaf = GlobalConst("j", Construct(ty.vec(nullptr, 3), Expr(0._a)));
+    auto* c_vai = GlobalConst("i", Call(ty.vec(nullptr, 3), Expr(0_a)));
+    auto* c_vaf = GlobalConst("j", Call(ty.vec(nullptr, 3), Expr(0._a)));
     auto* c_mf32 = GlobalConst("k", mat3x3<f32>());
-    auto* c_maf32 = GlobalConst("l", Construct(ty.mat(nullptr, 3, 3),  //
-                                               Construct(ty.vec(nullptr, 3), Expr(0._a)),
-                                               Construct(ty.vec(nullptr, 3), Expr(0._a)),
-                                               Construct(ty.vec(nullptr, 3), Expr(0._a))));
+    auto* c_maf32 = GlobalConst(
+        "l", Call(ty.mat(nullptr, 3, 3),  //
+                  Call(ty.vec(nullptr, 3), Expr(0._a)), Call(ty.vec(nullptr, 3), Expr(0._a)),
+                  Call(ty.vec(nullptr, 3), Expr(0._a))));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 
diff --git a/src/tint/transform/builtin_polyfill.cc b/src/tint/transform/builtin_polyfill.cc
index 3323b28..8c1166c 100644
--- a/src/tint/transform/builtin_polyfill.cc
+++ b/src/tint/transform/builtin_polyfill.cc
@@ -65,7 +65,7 @@
             if (width == 1) {
                 return expr;
             }
-            return b.Construct(T(ty), expr);
+            return b.Call(T(ty), expr);
         };
 
         utils::Vector<const ast::Statement*, 4> body;
@@ -119,7 +119,7 @@
             if (width == 1) {
                 return expr;
             }
-            return b.Construct(T(ty), expr);
+            return b.Call(T(ty), expr);
         };
 
         utils::Vector<const ast::Statement*, 1> body;
@@ -183,44 +183,44 @@
         auto V = [&](uint32_t value) -> const ast::Expression* {
             return ScalarOrVector(width, u32(value));
         };
-        b.Func(name,
-               utils::Vector{
-                   b.Param("v", T(ty)),
-               },
-               T(ty),
-               utils::Vector{
-                   // var x = U(v);
-                   b.Decl(b.Var("x", b.Construct(U(), b.Expr("v")))),
-                   // let b16 = select(0, 16, x <= 0x0000ffff);
-                   b.Decl(b.Let(
-                       "b16", b.Call("select", V(0), V(16), b.LessThanEqual("x", V(0x0000ffff))))),
-                   // x = x << b16;
-                   b.Assign("x", b.Shl("x", "b16")),
-                   // let b8  = select(0, 8,  x <= 0x00ffffff);
-                   b.Decl(b.Let("b8",
-                                b.Call("select", V(0), V(8), b.LessThanEqual("x", V(0x00ffffff))))),
-                   // x = x << b8;
-                   b.Assign("x", b.Shl("x", "b8")),
-                   // let b4  = select(0, 4,  x <= 0x0fffffff);
-                   b.Decl(b.Let("b4",
-                                b.Call("select", V(0), V(4), b.LessThanEqual("x", V(0x0fffffff))))),
-                   // x = x << b4;
-                   b.Assign("x", b.Shl("x", "b4")),
-                   // let b2  = select(0, 2,  x <= 0x3fffffff);
-                   b.Decl(b.Let("b2",
-                                b.Call("select", V(0), V(2), b.LessThanEqual("x", V(0x3fffffff))))),
-                   // x = x << b2;
-                   b.Assign("x", b.Shl("x", "b2")),
-                   // let b1  = select(0, 1,  x <= 0x7fffffff);
-                   b.Decl(b.Let("b1",
-                                b.Call("select", V(0), V(1), b.LessThanEqual("x", V(0x7fffffff))))),
-                   // let is_zero  = select(0, 1, x == 0);
-                   b.Decl(b.Let("is_zero", b.Call("select", V(0), V(1), b.Equal("x", V(0))))),
-                   // return R((b16 | b8 | b4 | b2 | b1) + zero);
-                   b.Return(b.Construct(
-                       T(ty),
-                       b.Add(b.Or(b.Or(b.Or(b.Or("b16", "b8"), "b4"), "b2"), "b1"), "is_zero"))),
-               });
+        b.Func(
+            name,
+            utils::Vector{
+                b.Param("v", T(ty)),
+            },
+            T(ty),
+            utils::Vector{
+                // var x = U(v);
+                b.Decl(b.Var("x", b.Call(U(), b.Expr("v")))),
+                // let b16 = select(0, 16, x <= 0x0000ffff);
+                b.Decl(b.Let("b16",
+                             b.Call("select", V(0), V(16), b.LessThanEqual("x", V(0x0000ffff))))),
+                // x = x << b16;
+                b.Assign("x", b.Shl("x", "b16")),
+                // let b8  = select(0, 8,  x <= 0x00ffffff);
+                b.Decl(
+                    b.Let("b8", b.Call("select", V(0), V(8), b.LessThanEqual("x", V(0x00ffffff))))),
+                // x = x << b8;
+                b.Assign("x", b.Shl("x", "b8")),
+                // let b4  = select(0, 4,  x <= 0x0fffffff);
+                b.Decl(
+                    b.Let("b4", b.Call("select", V(0), V(4), b.LessThanEqual("x", V(0x0fffffff))))),
+                // x = x << b4;
+                b.Assign("x", b.Shl("x", "b4")),
+                // let b2  = select(0, 2,  x <= 0x3fffffff);
+                b.Decl(
+                    b.Let("b2", b.Call("select", V(0), V(2), b.LessThanEqual("x", V(0x3fffffff))))),
+                // x = x << b2;
+                b.Assign("x", b.Shl("x", "b2")),
+                // let b1  = select(0, 1,  x <= 0x7fffffff);
+                b.Decl(
+                    b.Let("b1", b.Call("select", V(0), V(1), b.LessThanEqual("x", V(0x7fffffff))))),
+                // let is_zero  = select(0, 1, x == 0);
+                b.Decl(b.Let("is_zero", b.Call("select", V(0), V(1), b.Equal("x", V(0))))),
+                // return R((b16 | b8 | b4 | b2 | b1) + zero);
+                b.Return(b.Call(T(ty), b.Add(b.Or(b.Or(b.Or(b.Or("b16", "b8"), "b4"), "b2"), "b1"),
+                                             "is_zero"))),
+            });
         return name;
     }
 
@@ -243,9 +243,9 @@
         };
         auto B = [&](const ast::Expression* value) -> const ast::Expression* {
             if (width == 1) {
-                return b.Construct<bool>(value);
+                return b.Call<bool>(value);
             }
-            return b.Construct(b.ty.vec<bool>(width), value);
+            return b.Call(b.ty.vec<bool>(width), value);
         };
         b.Func(
             name,
@@ -255,7 +255,7 @@
             T(ty),
             utils::Vector{
                 // var x = U(v);
-                b.Decl(b.Var("x", b.Construct(U(), b.Expr("v")))),
+                b.Decl(b.Var("x", b.Call(U(), b.Expr("v")))),
                 // let b16 = select(16, 0, bool(x & 0x0000ffff));
                 b.Decl(b.Let("b16", b.Call("select", V(16), V(0), B(b.And("x", V(0x0000ffff)))))),
                 // x = x >> b16;
@@ -277,9 +277,8 @@
                 // let is_zero  = select(0, 1, x == 0);
                 b.Decl(b.Let("is_zero", b.Call("select", V(0), V(1), b.Equal("x", V(0))))),
                 // return R((b16 | b8 | b4 | b2 | b1) + zero);
-                b.Return(b.Construct(
-                    T(ty),
-                    b.Add(b.Or(b.Or(b.Or(b.Or("b16", "b8"), "b4"), "b2"), "b1"), "is_zero"))),
+                b.Return(b.Call(T(ty), b.Add(b.Or(b.Or(b.Or(b.Or("b16", "b8"), "b4"), "b2"), "b1"),
+                                             "is_zero"))),
             });
         return name;
     }
@@ -297,7 +296,7 @@
             if (width == 1) {
                 return value;
             }
-            return b.Construct(b.ty.vec<u32>(width), value);
+            return b.Call(b.ty.vec<u32>(width), value);
         };
 
         utils::Vector<const ast::Statement*, 8> body{
@@ -312,7 +311,7 @@
                 // Here we don't want the shl and shr modulos the rhs, so handle the `rhs >= 32u`
                 // cases using `select`. In order to handle the signed shr `lhs >> rhs` corrently,
                 // use `(lhs >> 31u) >> 1u` if `rhs >= 32u`.
-                body.Push(b.Decl(b.Let("shl_result", b.Call("select", b.Construct(T(ty)),
+                body.Push(b.Decl(b.Let("shl_result", b.Call("select", b.Call(T(ty)),
                                                             b.Shl("v", vecN_u32(b.Expr("shl"))),
                                                             b.LessThan("shl", 32_u)))));
                 body.Push(b.Return(b.Call(
@@ -361,9 +360,9 @@
         };
         auto B = [&](const ast::Expression* value) -> const ast::Expression* {
             if (width == 1) {
-                return b.Construct<bool>(value);
+                return b.Call<bool>(value);
             }
-            return b.Construct(b.ty.vec<bool>(width), value);
+            return b.Call(b.ty.vec<bool>(width), value);
         };
 
         const ast::Expression* x = nullptr;
@@ -371,9 +370,9 @@
             x = b.Expr("v");
         } else {
             // If ty is signed, then the value is inverted if the sign is negative
-            x = b.Call("select",                             //
-                       b.Construct(U(), "v"),                //
-                       b.Construct(U(), b.Complement("v")),  //
+            x = b.Call("select",                        //
+                       b.Call(U(), "v"),                //
+                       b.Call(U(), b.Complement("v")),  //
                        b.LessThan("v", ScalarOrVector(width, 0_i)));
         }
 
@@ -408,7 +407,7 @@
                 // let is_zero  = select(0, 0xffffffff, x == 0);
                 b.Decl(b.Let("is_zero", b.Call("select", V(0), V(0xffffffff), b.Equal("x", V(0))))),
                 // return R(b16 | b8 | b4 | b2 | b1 | zero);
-                b.Return(b.Construct(
+                b.Return(b.Call(
                     T(ty), b.Or(b.Or(b.Or(b.Or(b.Or("b16", "b8"), "b4"), "b2"), "b1"), "is_zero"))),
             });
         return name;
@@ -433,9 +432,9 @@
         };
         auto B = [&](const ast::Expression* value) -> const ast::Expression* {
             if (width == 1) {
-                return b.Construct<bool>(value);
+                return b.Call<bool>(value);
             }
-            return b.Construct(b.ty.vec<bool>(width), value);
+            return b.Call(b.ty.vec<bool>(width), value);
         };
         b.Func(
             name,
@@ -445,7 +444,7 @@
             T(ty),
             utils::Vector{
                 // var x = U(v);
-                b.Decl(b.Var("x", b.Construct(U(), b.Expr("v")))),
+                b.Decl(b.Var("x", b.Call(U(), b.Expr("v")))),
                 // let b16 = select(16, 0, bool(x & 0x0000ffff));
                 b.Decl(b.Let("b16", b.Call("select", V(16), V(0), B(b.And("x", V(0x0000ffff)))))),
                 // x = x >> b16;
@@ -467,7 +466,7 @@
                 // let is_zero  = select(0, 0xffffffff, x == 0);
                 b.Decl(b.Let("is_zero", b.Call("select", V(0), V(0xffffffff), b.Equal("x", V(0))))),
                 // return R(b16 | b8 | b4 | b2 | b1 | is_zero);
-                b.Return(b.Construct(
+                b.Return(b.Call(
                     T(ty), b.Or(b.Or(b.Or(b.Or(b.Or("b16", "b8"), "b4"), "b2"), "b1"), "is_zero"))),
             });
         return name;
@@ -493,10 +492,10 @@
         auto V = [&](auto value) -> const ast::Expression* {
             const ast::Expression* expr = b.Expr(value);
             if (!ty->is_unsigned_integer_scalar_or_vector()) {
-                expr = b.Construct<i32>(expr);
+                expr = b.Call<i32>(expr);
             }
             if (ty->Is<type::Vector>()) {
-                expr = b.Construct(T(ty), expr);
+                expr = b.Call(T(ty), expr);
             }
             return expr;
         };
@@ -552,8 +551,8 @@
 
                 // return ((select(T(), n << offset, offset < 32u) & mask) | (v & ~(mask)));
                 body.Push(
-                    b.Return(b.Or(b.And(b.Call("select", b.Construct(T(ty)),
-                                               b.Shl("n", U("offset")), b.LessThan("offset", 32_u)),
+                    b.Return(b.Or(b.And(b.Call("select", b.Call(T(ty)), b.Shl("n", U("offset")),
+                                               b.LessThan("offset", 32_u)),
                                         V("mask")),
                                   b.And("v", V(b.Complement("mask"))))));
 
@@ -587,7 +586,7 @@
     Symbol saturate(const type::Type* ty) {
         auto name = b.Symbols().New("tint_saturate");
         auto body = utils::Vector{
-            b.Return(b.Call("clamp", "v", b.Construct(T(ty), 0_a), b.Construct(T(ty), 1_a))),
+            b.Return(b.Call("clamp", "v", b.Call(T(ty), 0_a), b.Call(T(ty), 1_a))),
         };
         b.Func(name,
                utils::Vector{
@@ -630,8 +629,7 @@
     Symbol textureSampleBaseClampToEdge_2d_f32() {
         auto name = b.Symbols().New("tint_textureSampleBaseClampToEdge");
         auto body = utils::Vector{
-            b.Decl(b.Let("dims",
-                         b.Construct(b.ty.vec2<f32>(), b.Call("textureDimensions", "t", 0_a)))),
+            b.Decl(b.Let("dims", b.Call(b.ty.vec2<f32>(), b.Call("textureDimensions", "t", 0_a)))),
             b.Decl(b.Let("half_texel", b.Div(b.vec2<f32>(0.5_a), "dims"))),
             b.Decl(
                 b.Let("clamped", b.Call("clamp", "coord", "half_texel", b.Sub(1_a, "half_texel")))),
@@ -663,7 +661,7 @@
                },
                T(vec),
                utils::Vector{
-                   b.Return(b.Construct(T(vec), std::move(args))),
+                   b.Return(b.Call(T(vec), std::move(args))),
                });
         return name;
     }
@@ -705,7 +703,7 @@
         auto* lhs_el_ty = type::Type::DeepestElementOf(lhs_ty);
         const ast::Expression* mask = b.Expr(AInt(lhs_el_ty->Size() * 8 - 1));
         if (rhs_ty->Is<type::Vector>()) {
-            mask = b.Construct(CreateASTTypeFor(ctx, rhs_ty), mask);
+            mask = b.Call(CreateASTTypeFor(ctx, rhs_ty), mask);
         }
         auto* lhs = ctx.Clone(bin_op->lhs);
         auto* rhs = b.And(ctx.Clone(bin_op->rhs), mask);
@@ -808,7 +806,7 @@
         if (width == 1) {
             return b.Expr(value);
         }
-        return b.Construct(b.ty.vec<T>(width), value);
+        return b.Call(b.ty.vec<T>(width), value);
     }
 };
 
diff --git a/src/tint/transform/canonicalize_entry_point_io.cc b/src/tint/transform/canonicalize_entry_point_io.cc
index 61bb6ae..4a223f6 100644
--- a/src/tint/transform/canonicalize_entry_point_io.cc
+++ b/src/tint/transform/canonicalize_entry_point_io.cc
@@ -370,7 +370,7 @@
 
         // Construct the original structure using the new shader input objects.
         inner_call_parameters.Push(
-            ctx.dst->Construct(ctx.Clone(param->Declaration()->type), inner_struct_values));
+            ctx.dst->Call(ctx.Clone(param->Declaration()->type), inner_struct_values));
     }
 
     /// Process the entry point return type.
diff --git a/src/tint/transform/clamp_frag_depth.cc b/src/tint/transform/clamp_frag_depth.cc
index b8ba511..20710bb 100644
--- a/src/tint/transform/clamp_frag_depth.cc
+++ b/src/tint/transform/clamp_frag_depth.cc
@@ -178,7 +178,7 @@
                 }
                 utils::Vector params{b.Param("s", ctx.Clone(return_ty))};
                 utils::Vector body{
-                    b.Return(b.Construct(ctx.Clone(return_ty), std::move(initializer_args))),
+                    b.Return(b.Call(ctx.Clone(return_ty), std::move(initializer_args))),
                 };
                 b.Func(fn_sym, params, ctx.Clone(return_ty), body);
                 return fn_sym;
diff --git a/src/tint/transform/decompose_memory_access.cc b/src/tint/transform/decompose_memory_access.cc
index c3c8245..ef0ce52 100644
--- a/src/tint/transform/decompose_memory_access.cc
+++ b/src/tint/transform/decompose_memory_access.cc
@@ -77,7 +77,7 @@
         auto* type = ctx.src->Sem().GetVal(expr)->Type()->UnwrapRef();
         auto* res = ctx.Clone(expr);
         if (!type->Is<type::U32>()) {
-            res = ctx.dst->Construct<u32>(res);
+            res = ctx.dst->Call<u32>(res);
         }
         return res;
     }
@@ -545,7 +545,7 @@
                     }
                     b.Func(name, params, CreateASTTypeFor(ctx, el_ty),
                            utils::Vector{
-                               b.Return(b.Construct(CreateASTTypeFor(ctx, el_ty), values)),
+                               b.Return(b.Call(CreateASTTypeFor(ctx, el_ty), values)),
                            });
                 }
                 return name;
diff --git a/src/tint/transform/decompose_strided_array.cc b/src/tint/transform/decompose_strided_array.cc
index c441df8..8602f14 100644
--- a/src/tint/transform/decompose_strided_array.cc
+++ b/src/tint/transform/decompose_strided_array.cc
@@ -150,7 +150,7 @@
                             args = ctx.Clone(expr->args);
                         }
 
-                        return target.type ? b.Construct(target.type, std::move(args))
+                        return target.type ? b.Call(target.type, std::move(args))
                                            : b.Call(target.name, std::move(args));
                     }
                 }
diff --git a/src/tint/transform/decompose_strided_array_test.cc b/src/tint/transform/decompose_strided_array_test.cc
index 0f1e21c..042acd7 100644
--- a/src/tint/transform/decompose_strided_array_test.cc
+++ b/src/tint/transform/decompose_strided_array_test.cc
@@ -348,9 +348,9 @@
                 b.Group(0_a), b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
-               b.Assign(b.MemberAccessor("s", "a"), b.Construct(b.ty.array<f32, 4u>(32))),
+               b.Assign(b.MemberAccessor("s", "a"), b.Call(b.ty.array<f32, 4u>(32))),
                b.Assign(b.MemberAccessor("s", "a"),
-                        b.Construct(b.ty.array<f32, 4u>(32), 1_f, 2_f, 3_f, 4_f)),
+                        b.Call(b.ty.array<f32, 4u>(32), 1_f, 2_f, 3_f, 4_f)),
                b.Assign(b.IndexAccessor(b.MemberAccessor("s", "a"), 1_i), 5_f),
            },
            utils::Vector{
@@ -402,9 +402,9 @@
                 b.Group(0_a), b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
-               b.Assign(b.MemberAccessor("s", "a"), b.Construct(b.ty.array<f32, 4u>(4))),
+               b.Assign(b.MemberAccessor("s", "a"), b.Call(b.ty.array<f32, 4u>(4))),
                b.Assign(b.MemberAccessor("s", "a"),
-                        b.Construct(b.ty.array<f32, 4u>(4), 1_f, 2_f, 3_f, 4_f)),
+                        b.Call(b.ty.array<f32, 4u>(4), 1_f, 2_f, 3_f, 4_f)),
                b.Assign(b.IndexAccessor(b.MemberAccessor("s", "a"), 1_i), 5_f),
            },
            utils::Vector{
@@ -458,7 +458,7 @@
                b.Decl(b.Let("b", b.AddressOf(b.Deref(b.AddressOf(b.Deref("a")))))),
                b.Decl(b.Let("c", b.Deref("b"))),
                b.Decl(b.Let("d", b.IndexAccessor(b.Deref("b"), 1_i))),
-               b.Assign(b.Deref("b"), b.Construct(b.ty.array<f32, 4u>(32), 1_f, 2_f, 3_f, 4_f)),
+               b.Assign(b.Deref("b"), b.Call(b.ty.array<f32, 4u>(32), 1_f, 2_f, 3_f, 4_f)),
                b.Assign(b.IndexAccessor(b.Deref("b"), 1_i), 5_f),
            },
            utils::Vector{
@@ -517,8 +517,8 @@
            utils::Vector{
                b.Decl(b.Let("a", b.ty("ARR"), b.MemberAccessor("s", "a"))),
                b.Decl(b.Let("b", b.ty.f32(), b.IndexAccessor(b.MemberAccessor("s", "a"), 1_i))),
-               b.Assign(b.MemberAccessor("s", "a"), b.Construct(b.ty("ARR"))),
-               b.Assign(b.MemberAccessor("s", "a"), b.Construct(b.ty("ARR"), 1_f, 2_f, 3_f, 4_f)),
+               b.Assign(b.MemberAccessor("s", "a"), b.Call(b.ty("ARR"))),
+               b.Assign(b.MemberAccessor("s", "a"), b.Call(b.ty("ARR"), 1_f, 2_f, 3_f, 4_f)),
                b.Assign(b.IndexAccessor(b.MemberAccessor("s", "a"), 1_i), 5_f),
            },
            utils::Vector{
@@ -603,7 +603,7 @@
                                         3_i),
                                     2_i),
                                 1_i))),
-               b.Assign(b.MemberAccessor("s", "a"), b.Construct(b.ty("ARR_B"))),
+               b.Assign(b.MemberAccessor("s", "a"), b.Call(b.ty("ARR_B"))),
                b.Assign(b.IndexAccessor(                         //
                             b.IndexAccessor(                     //
                                 b.IndexAccessor(                 //
diff --git a/src/tint/transform/decompose_strided_matrix.cc b/src/tint/transform/decompose_strided_matrix.cc
index 773cfdf..d5a4ea2 100644
--- a/src/tint/transform/decompose_strided_matrix.cc
+++ b/src/tint/transform/decompose_strided_matrix.cc
@@ -150,7 +150,7 @@
                            },
                            array(),
                            utils::Vector{
-                               b.Return(b.Construct(array(), columns)),
+                               b.Return(b.Call(array(), columns)),
                            });
                     return name;
                 });
@@ -189,7 +189,7 @@
                            },
                            matrix(),
                            utils::Vector{
-                               b.Return(b.Construct(matrix(), columns)),
+                               b.Return(b.Call(matrix(), columns)),
                            });
                     return name;
                 });
diff --git a/src/tint/transform/direct_variable_access.cc b/src/tint/transform/direct_variable_access.cc
index 92af018..84deea9 100644
--- a/src/tint/transform/direct_variable_access.cc
+++ b/src/tint/transform/direct_variable_access.cc
@@ -574,7 +574,7 @@
                      ->Type()
                      ->UnwrapRef()
                      ->IsAnyOf<type::U32, type::AbstractInt>()) {
-                expr = b.Construct(b.ty.u32(), expr);
+                expr = b.Call<u32>(expr);
             }
         }
 
@@ -937,7 +937,7 @@
                         dyn_idx_args.Push(BuildDynamicIndex(dyn_idx, /* cast_to_u32 */ true));
                     }
                     // Construct the dynamic index array, and push as an argument.
-                    new_args.Push(b.Construct(dyn_idx_arr_ty, std::move(dyn_idx_args)));
+                    new_args.Push(b.Call(dyn_idx_arr_ty, std::move(dyn_idx_args)));
                 }
             }
 
diff --git a/src/tint/transform/multiplanar_external_texture.cc b/src/tint/transform/multiplanar_external_texture.cc
index 6e68428..97d907c 100644
--- a/src/tint/transform/multiplanar_external_texture.cc
+++ b/src/tint/transform/multiplanar_external_texture.cc
@@ -320,17 +320,17 @@
                     "modifiedCoords", b.Mul(b.MemberAccessor("params", "coordTransformationMatrix"),
                                             b.vec3<f32>("coord", 1_a)))));
 
-                stmts.Push(b.Decl(b.Let(
-                    "plane0_dims",
-                    b.Construct(b.ty.vec2<f32>(), b.Call("textureDimensions", "plane0", 0_a)))));
+                stmts.Push(b.Decl(
+                    b.Let("plane0_dims",
+                          b.Call(b.ty.vec2<f32>(), b.Call("textureDimensions", "plane0", 0_a)))));
                 stmts.Push(
                     b.Decl(b.Let("plane0_half_texel", b.Div(b.vec2<f32>(0.5_a), "plane0_dims"))));
                 stmts.Push(b.Decl(
                     b.Let("plane0_clamped", b.Call("clamp", "modifiedCoords", "plane0_half_texel",
                                                    b.Sub(1_a, "plane0_half_texel")))));
-                stmts.Push(b.Decl(b.Let(
-                    "plane1_dims",
-                    b.Construct(b.ty.vec2<f32>(), b.Call("textureDimensions", "plane1", 0_a)))));
+                stmts.Push(b.Decl(
+                    b.Let("plane1_dims",
+                          b.Call(b.ty.vec2<f32>(), b.Call("textureDimensions", "plane1", 0_a)))));
                 stmts.Push(
                     b.Decl(b.Let("plane1_half_texel", b.Div(b.vec2<f32>(0.5_a), "plane1_dims"))));
                 stmts.Push(b.Decl(
diff --git a/src/tint/transform/packed_vec3.cc b/src/tint/transform/packed_vec3.cc
index c553a32..6337197 100644
--- a/src/tint/transform/packed_vec3.cc
+++ b/src/tint/transform/packed_vec3.cc
@@ -135,7 +135,7 @@
                 auto* expr = ref->Declaration();
                 ctx.Replace(expr, [this, vec_ty, expr] {  //
                     auto* packed = ctx.CloneWithoutTransform(expr);
-                    return b.Construct(CreateASTTypeFor(ctx, vec_ty), packed);
+                    return b.Call(CreateASTTypeFor(ctx, vec_ty), packed);
                 });
             }
         }
diff --git a/src/tint/transform/pad_structs.cc b/src/tint/transform/pad_structs.cc
index 449cde8..7d9e7cd 100644
--- a/src/tint/transform/pad_structs.cc
+++ b/src/tint/transform/pad_structs.cc
@@ -139,7 +139,7 @@
                 arg++;
             }
         }
-        return b.Construct(CreateASTTypeFor(ctx, str), new_args);
+        return b.Call(CreateASTTypeFor(ctx, str), new_args);
     });
 
     ctx.Clone();
diff --git a/src/tint/transform/robustness.cc b/src/tint/transform/robustness.cc
index 4680939..87403e8 100644
--- a/src/tint/transform/robustness.cc
+++ b/src/tint/transform/robustness.cc
@@ -79,7 +79,7 @@
         auto idx = [&]() -> const ast::Expression* {
             auto* i = ctx.Clone(expr->index);
             if (sem->Index()->Type()->is_signed_integer_scalar()) {
-                return b.Construct(b.ty.u32(), i);  // u32(idx)
+                return b.Call<u32>(i);  // u32(idx)
             }
             return i;
         };
@@ -191,15 +191,15 @@
         auto scalar_or_vec = [&](const ast::Expression* scalar,
                                  uint32_t width) -> const ast::Expression* {
             if (width > 1) {
-                return b.Construct(b.ty.vec(nullptr, width), scalar);
+                return b.Call(b.ty.vec(nullptr, width), scalar);
             }
             return scalar;
         };
         auto cast_to_signed = [&](const ast::Expression* val, uint32_t width) {
-            return b.Construct(scalar_or_vec_ty(b.ty.i32(), width), val);
+            return b.Call(scalar_or_vec_ty(b.ty.i32(), width), val);
         };
         auto cast_to_unsigned = [&](const ast::Expression* val, uint32_t width) {
-            return b.Construct(scalar_or_vec_ty(b.ty.u32(), width), val);
+            return b.Call(scalar_or_vec_ty(b.ty.u32(), width), val);
         };
 
         // If the level is provided, then we need to clamp this. As the level is
diff --git a/src/tint/transform/std140.cc b/src/tint/transform/std140.cc
index 46f71bc..334bef7 100644
--- a/src/tint/transform/std140.cc
+++ b/src/tint/transform/std140.cc
@@ -706,7 +706,7 @@
                                 utils::Transform(*col_members, [&](const ast::StructMember* m) {
                                     return b.MemberAccessor(param, m->symbol);
                                 });
-                            args.Push(b.Construct(mat_ty, std::move(mat_args)));
+                            args.Push(b.Call(mat_ty, std::move(mat_args)));
                         } else {
                             // Convert the member
                             args.Push(
@@ -714,7 +714,7 @@
                                         b.MemberAccessor(param, sym.NameFor(member->Name()))));
                         }
                     }
-                    stmts.Push(b.Return(b.Construct(CreateASTTypeFor(ctx, ty), std::move(args))));
+                    stmts.Push(b.Return(b.Call(CreateASTTypeFor(ctx, ty), std::move(args))));
                 },  //
                 [&](const type::Matrix* mat) {
                     // Reassemble a std140 matrix from the structure of column vector members.
@@ -726,7 +726,7 @@
                         auto mat_args = utils::Transform(std140_mat->columns, [&](Symbol name) {
                             return b.MemberAccessor(param, name);
                         });
-                        stmts.Push(b.Return(b.Construct(mat_ty, std::move(mat_args))));
+                        stmts.Push(b.Return(b.Call(mat_ty, std::move(mat_args))));
                     } else {
                         TINT_ICE(Transform, b.Diagnostics())
                             << "failed to find std140 matrix info for: " << src->FriendlyName(ty);
@@ -798,7 +798,7 @@
 
         // Build the arguments
         auto args = utils::Transform(access.dynamic_indices, [&](const sem::ValueExpression* e) {
-            return b.Construct(b.ty.u32(), ctx.Clone(e->Declaration()));
+            return b.Call<u32>(ctx.Clone(e->Declaration()));
         });
 
         // Call the helper
@@ -962,7 +962,7 @@
         // Build the default case (required in WGSL).
         // This just returns a zero value of the return type, as the index must be out of
         // bounds.
-        cases.Push(b.DefaultCase(b.Block(b.Return(b.Construct(CreateASTTypeFor(ctx, ret_ty))))));
+        cases.Push(b.DefaultCase(b.Block(b.Return(b.Call(CreateASTTypeFor(ctx, ret_ty))))));
 
         auto* column_selector = dynamic_index(column_param_idx);
         auto* stmt = b.Switch(column_selector, std::move(cases));
@@ -1035,7 +1035,7 @@
         }
 
         // Reconstruct the matrix from the columns
-        expr = b.Construct(CreateASTTypeFor(ctx, chain.std140_mat_ty), std::move(columns));
+        expr = b.Call(CreateASTTypeFor(ctx, chain.std140_mat_ty), std::move(columns));
 
         // Have the function return the constructed matrix
         stmts.Push(b.Return(expr));
diff --git a/src/tint/transform/truncate_interstage_variables.cc b/src/tint/transform/truncate_interstage_variables.cc
index d7d811f..cf15a38 100644
--- a/src/tint/transform/truncate_interstage_variables.cc
+++ b/src/tint/transform/truncate_interstage_variables.cc
@@ -139,11 +139,11 @@
 
                 // Create the mapping function to truncate the shader io.
                 auto mapping_fn_sym = b.Symbols().New("truncate_shader_output");
-                b.Func(
-                    mapping_fn_sym, utils::Vector{b.Param("io", ctx.Clone(func_ast->return_type))},
-                    b.ty(new_struct_sym),
-                    utils::Vector{
-                        b.Return(b.Construct(b.ty(new_struct_sym), std::move(initializer_exprs)))});
+                b.Func(mapping_fn_sym,
+                       utils::Vector{b.Param("io", ctx.Clone(func_ast->return_type))},
+                       b.ty(new_struct_sym),
+                       utils::Vector{
+                           b.Return(b.Call(b.ty(new_struct_sym), std::move(initializer_exprs)))});
                 return TruncatedStructAndConverter{new_struct_sym, mapping_fn_sym};
             });
 
diff --git a/src/tint/transform/vectorize_matrix_conversions.cc b/src/tint/transform/vectorize_matrix_conversions.cc
index 8aa3690..e920417 100644
--- a/src/tint/transform/vectorize_matrix_conversions.cc
+++ b/src/tint/transform/vectorize_matrix_conversions.cc
@@ -106,9 +106,9 @@
                 auto* src_matrix_expr = src_expression_builder();
                 auto* src_column_expr = b.IndexAccessor(src_matrix_expr, b.Expr(tint::AInt(c)));
                 columns.Push(
-                    b.Construct(CreateASTTypeFor(ctx, dst_type->ColumnType()), src_column_expr));
+                    b.Call(CreateASTTypeFor(ctx, dst_type->ColumnType()), src_column_expr));
             }
-            return b.Construct(CreateASTTypeFor(ctx, dst_type), columns);
+            return b.Call(CreateASTTypeFor(ctx, dst_type), columns);
         };
 
         // Replace the matrix conversion to column vector conversions and a matrix construction.
diff --git a/src/tint/transform/vectorize_scalar_matrix_initializers.cc b/src/tint/transform/vectorize_scalar_matrix_initializers.cc
index 60d4d13..5c58280 100644
--- a/src/tint/transform/vectorize_scalar_matrix_initializers.cc
+++ b/src/tint/transform/vectorize_scalar_matrix_initializers.cc
@@ -102,7 +102,7 @@
                 columns.Push(b.vec(CreateASTTypeFor(ctx, mat_type->type()), mat_type->rows(),
                                    std::move(row_values)));
             }
-            return b.Construct(CreateASTTypeFor(ctx, mat_type), columns);
+            return b.Call(CreateASTTypeFor(ctx, mat_type), columns);
         };
 
         if (args.Length() == 1) {
diff --git a/src/tint/transform/vertex_pulling.cc b/src/tint/transform/vertex_pulling.cc
index 60b02a6..c75b81c 100644
--- a/src/tint/transform/vertex_pulling.cc
+++ b/src/tint/transform/vertex_pulling.cc
@@ -402,7 +402,7 @@
                         loaded_data_target_type = b.ty.vec(b.ty.f16(), fmt_dt.width);
                     }
 
-                    fetch = b.Construct(loaded_data_target_type, fetch);
+                    fetch = b.Call(loaded_data_target_type, fetch);
                 }
 
                 // The attribute value may not be of the desired vector width. If it is not, we'll
@@ -444,7 +444,7 @@
                     }
 
                     const ast::Type* target_ty = CreateASTTypeFor(ctx, var.type);
-                    value = b.Construct(target_ty, values);
+                    value = b.Call(target_ty, values);
                 }
 
                 // Assign the value to the WGSL variable
@@ -745,7 +745,7 @@
             expr_list.Push(LoadPrimitive(array_base, primitive_offset, buffer, base_format));
         }
 
-        return b.Construct(b.create<ast::Vector>(base_type, count), std::move(expr_list));
+        return b.Call(b.create<ast::Vector>(base_type, count), std::move(expr_list));
     }
 
     /// Process a non-struct entry point parameter.
diff --git a/src/tint/transform/zero_init_workgroup_memory.cc b/src/tint/transform/zero_init_workgroup_memory.cc
index c7e1b8a..2f5ac1f 100644
--- a/src/tint/transform/zero_init_workgroup_memory.cc
+++ b/src/tint/transform/zero_init_workgroup_memory.cc
@@ -297,14 +297,14 @@
             if (!var) {
                 return false;
             }
-            auto* zero_init = b.Construct(CreateASTTypeFor(ctx, ty));
+            auto* zero_init = b.Call(CreateASTTypeFor(ctx, ty));
             statements.emplace_back(
                 Statement{b.Assign(var.expr, zero_init), var.num_iterations, var.array_indices});
             return true;
         }
 
         if (auto* atomic = ty->As<type::Atomic>()) {
-            auto* zero_init = b.Construct(CreateASTTypeFor(ctx, atomic->Type()));
+            auto* zero_init = b.Call(CreateASTTypeFor(ctx, atomic->Type()));
             auto expr = get_expr(1u);
             if (!expr) {
                 return false;
@@ -412,7 +412,7 @@
             workgroup_size_expr = [this, expr, size = workgroup_size_expr] {
                 auto* e = ctx.Clone(expr);
                 if (ctx.src->TypeOf(expr)->UnwrapRef()->Is<type::I32>()) {
-                    e = b.Construct<u32>(e);
+                    e = b.Call<u32>(e);
                 }
                 return size ? b.Mul(size(), e) : e;
             };
diff --git a/src/tint/writer/append_vector.cc b/src/tint/writer/append_vector.cc
index 40222c0..899e81a 100644
--- a/src/tint/writer/append_vector.cc
+++ b/src/tint/writer/append_vector.cc
@@ -135,7 +135,7 @@
 
     if (packed_el_sem_ty != scalar_sem->Type()->UnwrapRef()) {
         // Cast scalar to the vector element type
-        auto* scalar_cast_ast = b->Construct(packed_el_ast_ty, scalar_ast);
+        auto* scalar_cast_ast = b->Call(packed_el_ast_ty, scalar_ast);
         auto* scalar_cast_target = b->create<sem::TypeConversion>(
             packed_el_sem_ty,
             b->create<sem::Parameter>(nullptr, 0u, scalar_sem->Type()->UnwrapRef(),
@@ -152,9 +152,9 @@
     }
 
     auto* initializer_ast =
-        b->Construct(packed_ast_ty, utils::Transform(packed, [&](const sem::ValueExpression* expr) {
-                         return expr->Declaration();
-                     }));
+        b->Call(packed_ast_ty, utils::Transform(packed, [&](const sem::ValueExpression* expr) {
+                    return expr->Declaration();
+                }));
     auto* initializer_target = b->create<sem::TypeInitializer>(
         packed_sem_ty,
         utils::Transform(
diff --git a/src/tint/writer/glsl/generator_impl_cast_test.cc b/src/tint/writer/glsl/generator_impl_cast_test.cc
index c4f9c05..4954dee 100644
--- a/src/tint/writer/glsl/generator_impl_cast_test.cc
+++ b/src/tint/writer/glsl/generator_impl_cast_test.cc
@@ -22,7 +22,7 @@
 using GlslGeneratorImplTest_Cast = TestHelper;
 
 TEST_F(GlslGeneratorImplTest_Cast, EmitExpression_Cast_Scalar) {
-    auto* cast = Construct<f32>(1_i);
+    auto* cast = Call<f32>(1_i);
     WrapInFunction(cast);
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/glsl/generator_impl_function_test.cc b/src/tint/writer/glsl/generator_impl_function_test.cc
index 3c3dd53..db16749 100644
--- a/src/tint/writer/glsl/generator_impl_function_test.cc
+++ b/src/tint/writer/glsl/generator_impl_function_test.cc
@@ -223,8 +223,8 @@
         });
 
     Func("vert_main", utils::Empty, ty.Of(interface_struct),
-         utils::Vector{Return(Construct(ty.Of(interface_struct), Construct(ty.vec4<f32>()),
-                                        Expr(0.5_f), Expr(0.25_f)))},
+         utils::Vector{Return(
+             Call(ty.Of(interface_struct), Call(ty.vec4<f32>()), Expr(0.5_f), Expr(0.25_f)))},
          utils::Vector{Stage(ast::PipelineStage::kVertex)});
 
     Func("frag_main", utils::Vector{Param("inputs", ty.Of(interface_struct))}, ty.void_(),
@@ -300,17 +300,17 @@
       {Member("pos", ty.vec4<f32>(), {Builtin(ast::BuiltinValue::kPosition)})});
 
   Func("foo", utils::Vector{Param("x", ty.f32())}, ty.Of(vertex_output_struct),
-       {Return(Construct(ty.Of(vertex_output_struct),
-                         Construct(ty.vec4<f32>(), "x", "x", "x", Expr(1_f))))},
+       {Return(Call(ty.Of(vertex_output_struct),
+                         Call(ty.vec4<f32>(), "x", "x", "x", Expr(1_f))))},
        {});
 
   Func("vert_main1", utils::Empty, ty.Of(vertex_output_struct),
-       {Return(Construct(ty.Of(vertex_output_struct),
+       {Return(Call(ty.Of(vertex_output_struct),
                          Expr(Call("foo", Expr(0.5_f)))))},
        {Stage(ast::PipelineStage::kVertex)});
 
   Func("vert_main2", utils::Empty, ty.Of(vertex_output_struct),
-       {Return(Construct(ty.Of(vertex_output_struct),
+       {Return(Call(ty.Of(vertex_output_struct),
                          Expr(Call("foo", Expr(0.25_f)))))},
        {Stage(ast::PipelineStage::kVertex)});
 
@@ -782,9 +782,9 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_Compute_WithWorkgroup_Const) {
-    GlobalConst("width", ty.i32(), Construct(ty.i32(), 2_i));
-    GlobalConst("height", ty.i32(), Construct(ty.i32(), 3_i));
-    GlobalConst("depth", ty.i32(), Construct(ty.i32(), 4_i));
+    GlobalConst("width", ty.i32(), Call<i32>(2_i));
+    GlobalConst("height", ty.i32(), Call<i32>(3_i));
+    GlobalConst("depth", ty.i32(), Call<i32>(4_i));
     Func("main", utils::Empty, ty.void_(), {},
          utils::Vector{
              Stage(ast::PipelineStage::kCompute),
@@ -805,9 +805,9 @@
 
 TEST_F(GlslGeneratorImplTest_Function,
        Emit_Attribute_EntryPoint_Compute_WithWorkgroup_OverridableConst) {
-    Override("width", ty.i32(), Construct(ty.i32(), 2_i), Id(7_u));
-    Override("height", ty.i32(), Construct(ty.i32(), 3_i), Id(8_u));
-    Override("depth", ty.i32(), Construct(ty.i32(), 4_i), Id(9_u));
+    Override("width", ty.i32(), Call<i32>(2_i), Id(7_u));
+    Override("height", ty.i32(), Call<i32>(3_i), Id(8_u));
+    Override("depth", ty.i32(), Call<i32>(4_i), Id(9_u));
     Func("main", utils::Empty, ty.void_(), {},
          utils::Vector{
              Stage(ast::PipelineStage::kCompute),
@@ -843,7 +843,7 @@
 TEST_F(GlslGeneratorImplTest_Function, Emit_Function_WithArrayReturn) {
     Func("my_func", utils::Empty, ty.array<f32, 5>(),
          utils::Vector{
-             Return(Construct(ty.array<f32, 5>())),
+             Return(Call(ty.array<f32, 5>())),
          });
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/glsl/generator_impl_initializer_test.cc b/src/tint/writer/glsl/generator_impl_initializer_test.cc
index 69e58fc..e9c4dc9 100644
--- a/src/tint/writer/glsl/generator_impl_initializer_test.cc
+++ b/src/tint/writer/glsl/generator_impl_initializer_test.cc
@@ -74,7 +74,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Initializer, EmitInitializer_Type_Float) {
-    WrapInFunction(Construct<f32>(-1.2e-5_f));
+    WrapInFunction(Call<f32>(-1.2e-5_f));
 
     GeneratorImpl& gen = Build();
 
@@ -85,7 +85,7 @@
 TEST_F(GlslGeneratorImplTest_Initializer, EmitInitializer_Type_F16) {
     Enable(ast::Extension::kF16);
 
-    WrapInFunction(Construct<f16>(-1.2e-3_h));
+    WrapInFunction(Call<f16>(-1.2e-3_h));
 
     GeneratorImpl& gen = Build();
 
@@ -94,7 +94,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Initializer, EmitInitializer_Type_Bool) {
-    WrapInFunction(Construct<bool>(true));
+    WrapInFunction(Call<bool>(true));
 
     GeneratorImpl& gen = Build();
 
@@ -103,7 +103,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Initializer, EmitInitializer_Type_Int) {
-    WrapInFunction(Construct<i32>(-12345_i));
+    WrapInFunction(Call<i32>(-12345_i));
 
     GeneratorImpl& gen = Build();
 
@@ -112,7 +112,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Initializer, EmitInitializer_Type_Uint) {
-    WrapInFunction(Construct<u32>(12345_u));
+    WrapInFunction(Call<u32>(12345_u));
 
     GeneratorImpl& gen = Build();
 
@@ -375,8 +375,8 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Initializer, EmitInitializer_Type_Array) {
-    WrapInFunction(Construct(ty.array(ty.vec3<f32>(), 3_u), vec3<f32>(1_f, 2_f, 3_f),
-                             vec3<f32>(4_f, 5_f, 6_f), vec3<f32>(7_f, 8_f, 9_f)));
+    WrapInFunction(Call(ty.array(ty.vec3<f32>(), 3_u), vec3<f32>(1_f, 2_f, 3_f),
+                        vec3<f32>(4_f, 5_f, 6_f), vec3<f32>(7_f, 8_f, 9_f)));
 
     GeneratorImpl& gen = Build();
 
@@ -387,7 +387,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Initializer, EmitInitializer_Type_Array_Empty) {
-    WrapInFunction(Construct(ty.array(ty.vec3<f32>(), 3_u)));
+    WrapInFunction(Call(ty.array(ty.vec3<f32>(), 3_u)));
 
     GeneratorImpl& gen = Build();
 
@@ -402,7 +402,7 @@
                                    Member("c", ty.vec3<i32>()),
                                });
 
-    WrapInFunction(Construct(ty.Of(str), 1_i, 2_f, vec3<i32>(3_i, 4_i, 5_i)));
+    WrapInFunction(Call(ty.Of(str), 1_i, 2_f, vec3<i32>(3_i, 4_i, 5_i)));
 
     GeneratorImpl& gen = SanitizeAndBuild();
 
@@ -417,7 +417,7 @@
                                    Member("c", ty.vec3<i32>()),
                                });
 
-    WrapInFunction(Construct(ty.Of(str)));
+    WrapInFunction(Call(ty.Of(str)));
 
     GeneratorImpl& gen = SanitizeAndBuild();
 
diff --git a/src/tint/writer/glsl/generator_impl_member_accessor_test.cc b/src/tint/writer/glsl/generator_impl_member_accessor_test.cc
index e062630..358373b 100644
--- a/src/tint/writer/glsl/generator_impl_member_accessor_test.cc
+++ b/src/tint/writer/glsl/generator_impl_member_accessor_test.cc
@@ -219,7 +219,7 @@
     });
 
     SetupFunction(utils::Vector{
-        Decl(Var("value", p.member_type(ty), Construct(p.member_type(ty)))),
+        Decl(Var("value", p.member_type(ty), Call(p.member_type(ty)))),
         Assign(MemberAccessor("data", "b"), Expr("value")),
     });
 
@@ -267,7 +267,7 @@
     });
 
     SetupFunction(utils::Vector{
-        Assign(MemberAccessor("data", "b"), Construct(ty.mat2x3<f32>())),
+        Assign(MemberAccessor("data", "b"), Call(ty.mat2x3<f32>())),
     });
 
     GeneratorImpl& gen = SanitizeAndBuild();
diff --git a/src/tint/writer/glsl/generator_impl_module_constant_test.cc b/src/tint/writer/glsl/generator_impl_module_constant_test.cc
index b9da4d5..c5d594f 100644
--- a/src/tint/writer/glsl/generator_impl_module_constant_test.cc
+++ b/src/tint/writer/glsl/generator_impl_module_constant_test.cc
@@ -156,7 +156,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_vec3_AInt) {
-    auto* var = GlobalConst("G", Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
+    auto* var = GlobalConst("G", Call(ty.vec3(nullptr), 1_a, 2_a, 3_a));
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(Let("l", Expr(var))),
@@ -176,7 +176,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_vec3_AFloat) {
-    auto* var = GlobalConst("G", Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
+    auto* var = GlobalConst("G", Call(ty.vec3(nullptr), 1._a, 2._a, 3._a));
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(Let("l", Expr(var))),
@@ -239,8 +239,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_mat2x3_AFloat) {
-    auto* var =
-        GlobalConst("G", Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
+    auto* var = GlobalConst("G", Call(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(Let("l", Expr(var))),
@@ -303,7 +302,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_arr_f32) {
-    auto* var = GlobalConst("G", Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
+    auto* var = GlobalConst("G", Call(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(Let("l", Expr(var))),
@@ -323,10 +322,10 @@
 }
 
 TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_arr_vec2_bool) {
-    auto* var = GlobalConst("G", Construct(ty.array(ty.vec2<bool>(), 3_u),  //
-                                           vec2<bool>(true, false),         //
-                                           vec2<bool>(false, true),         //
-                                           vec2<bool>(true, true)));
+    auto* var = GlobalConst("G", Call(ty.array(ty.vec2<bool>(), 3_u),  //
+                                      vec2<bool>(true, false),         //
+                                      vec2<bool>(false, true),         //
+                                      vec2<bool>(true, true)));
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(Let("l", Expr(var))),
diff --git a/src/tint/writer/glsl/generator_impl_sanitizer_test.cc b/src/tint/writer/glsl/generator_impl_sanitizer_test.cc
index 3bb3e13..f232811 100644
--- a/src/tint/writer/glsl/generator_impl_sanitizer_test.cc
+++ b/src/tint/writer/glsl/generator_impl_sanitizer_test.cc
@@ -187,7 +187,7 @@
                                    Member("c", ty.i32()),
                                });
     auto* runtime_value = Var("runtime_value", Expr(3_f));
-    auto* struct_init = Construct(ty.Of(str), 1_i, vec3<f32>(2_f, runtime_value, 4_f), 4_i);
+    auto* struct_init = Call(ty.Of(str), 1_i, vec3<f32>(2_f, runtime_value, 4_f), 4_i);
     auto* struct_access = MemberAccessor(struct_init, "b");
     auto* pos = Var("pos", ty.vec3<f32>(), struct_access);
 
diff --git a/src/tint/writer/glsl/generator_impl_variable_decl_statement_test.cc b/src/tint/writer/glsl/generator_impl_variable_decl_statement_test.cc
index eced7dd..562dabe 100644
--- a/src/tint/writer/glsl/generator_impl_variable_decl_statement_test.cc
+++ b/src/tint/writer/glsl/generator_impl_variable_decl_statement_test.cc
@@ -39,7 +39,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Let) {
-    auto* var = Let("a", ty.f32(), Construct(ty.f32()));
+    auto* var = Let("a", ty.f32(), Call<f32>());
     auto* stmt = Decl(var);
     WrapInFunction(stmt);
 
@@ -52,7 +52,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const) {
-    auto* var = Const("a", ty.f32(), Construct(ty.f32()));
+    auto* var = Const("a", ty.f32(), Call<f32>());
     auto* stmt = Decl(var);
     WrapInFunction(stmt);
 
@@ -194,7 +194,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_vec3_AInt) {
-    auto* C = Const("C", Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
+    auto* C = Const("C", Call(ty.vec3(nullptr), 1_a, 2_a, 3_a));
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(C),
@@ -215,7 +215,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_vec3_AFloat) {
-    auto* C = Const("C", Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
+    auto* C = Const("C", Call(ty.vec3(nullptr), 1._a, 2._a, 3._a));
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(C),
@@ -281,7 +281,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_mat2x3_AFloat) {
-    auto* C = Const("C", Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
+    auto* C = Const("C", Call(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(C),
@@ -347,7 +347,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_arr_f32) {
-    auto* C = Const("C", Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
+    auto* C = Const("C", Call(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(C),
@@ -368,7 +368,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_arr_f32_zero) {
-    auto* C = Const("C", Construct(ty.array<f32, 2>()));
+    auto* C = Const("C", Call(ty.array<f32, 2>()));
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(C),
@@ -389,7 +389,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_arr_arr_f32_zero) {
-    auto* C = Const("C", Construct(ty.array(ty.array<f32, 2>(), 3_i)));
+    auto* C = Const("C", Call(ty.array(ty.array<f32, 2>(), 3_i)));
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(C),
@@ -411,7 +411,7 @@
 
 TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_arr_struct_zero) {
     Structure("S", utils::Vector{Member("a", ty.i32()), Member("b", ty.f32())});
-    auto* C = Const("C", Construct(ty.array(ty("S"), 2_i)));
+    auto* C = Const("C", Call(ty.array(ty("S"), 2_i)));
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(C),
@@ -437,10 +437,10 @@
 }
 
 TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_arr_vec2_bool) {
-    auto* C = Const("C", Construct(ty.array(ty.vec2<bool>(), 3_u),  //
-                                   vec2<bool>(true, false),         //
-                                   vec2<bool>(false, true),         //
-                                   vec2<bool>(true, true)));
+    auto* C = Const("C", Call(ty.array(ty.vec2<bool>(), 3_u),  //
+                              vec2<bool>(true, false),         //
+                              vec2<bool>(false, true),         //
+                              vec2<bool>(true, true)));
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(C),
diff --git a/src/tint/writer/hlsl/generator_impl_cast_test.cc b/src/tint/writer/hlsl/generator_impl_cast_test.cc
index 2c4690a..4c522a3 100644
--- a/src/tint/writer/hlsl/generator_impl_cast_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_cast_test.cc
@@ -22,7 +22,7 @@
 using HlslGeneratorImplTest_Cast = TestHelper;
 
 TEST_F(HlslGeneratorImplTest_Cast, EmitExpression_Cast_Scalar) {
-    auto* cast = Construct<f32>(1_i);
+    auto* cast = Call<f32>(1_i);
     WrapInFunction(cast);
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/hlsl/generator_impl_function_test.cc b/src/tint/writer/hlsl/generator_impl_function_test.cc
index 8e734ca..8b156ac 100644
--- a/src/tint/writer/hlsl/generator_impl_function_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_function_test.cc
@@ -216,8 +216,7 @@
 
     Func("vert_main", utils::Empty, ty.Of(interface_struct),
          utils::Vector{
-             Return(Construct(ty.Of(interface_struct), Construct(ty.vec4<f32>()), Expr(0.5_f),
-                              Expr(0.25_f))),
+             Return(Call(ty.Of(interface_struct), Call(ty.vec4<f32>()), Expr(0.5_f), Expr(0.25_f))),
          },
          utils::Vector{Stage(ast::PipelineStage::kVertex)});
 
@@ -297,8 +296,8 @@
 
     Func("foo", utils::Vector{Param("x", ty.f32())}, ty.Of(vertex_output_struct),
          utils::Vector{
-             Return(Construct(ty.Of(vertex_output_struct),
-                              Construct(ty.vec4<f32>(), "x", "x", "x", Expr(1_f)))),
+             Return(
+                 Call(ty.Of(vertex_output_struct), Call(ty.vec4<f32>(), "x", "x", "x", Expr(1_f)))),
          },
          utils::Empty);
 
@@ -693,9 +692,9 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_Compute_WithWorkgroup_Const) {
-    GlobalConst("width", ty.i32(), Construct(ty.i32(), 2_i));
-    GlobalConst("height", ty.i32(), Construct(ty.i32(), 3_i));
-    GlobalConst("depth", ty.i32(), Construct(ty.i32(), 4_i));
+    GlobalConst("width", ty.i32(), Call<i32>(2_i));
+    GlobalConst("height", ty.i32(), Call<i32>(3_i));
+    GlobalConst("depth", ty.i32(), Call<i32>(4_i));
     Func("main", utils::Empty, ty.void_(), utils::Empty,
          utils::Vector{
              Stage(ast::PipelineStage::kCompute),
@@ -714,9 +713,9 @@
 
 TEST_F(HlslGeneratorImplTest_Function,
        Emit_Attribute_EntryPoint_Compute_WithWorkgroup_OverridableConst) {
-    Override("width", ty.i32(), Construct(ty.i32(), 2_i), Id(7_u));
-    Override("height", ty.i32(), Construct(ty.i32(), 3_i), Id(8_u));
-    Override("depth", ty.i32(), Construct(ty.i32(), 4_i), Id(9_u));
+    Override("width", ty.i32(), Call<i32>(2_i), Id(7_u));
+    Override("height", ty.i32(), Call<i32>(3_i), Id(8_u));
+    Override("depth", ty.i32(), Call<i32>(4_i), Id(9_u));
     Func("main", utils::Empty, ty.void_(), utils::Empty,
          utils::Vector{
              Stage(ast::PipelineStage::kCompute),
@@ -753,7 +752,7 @@
 TEST_F(HlslGeneratorImplTest_Function, Emit_Function_WithArrayReturn) {
     Func("my_func", utils::Empty, ty.array<f32, 5>(),
          utils::Vector{
-             Return(Construct(ty.array<f32, 5>())),
+             Return(Call(ty.array<f32, 5>())),
          });
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/hlsl/generator_impl_initializer_test.cc b/src/tint/writer/hlsl/generator_impl_initializer_test.cc
index 7f05ef6..14f8c08 100644
--- a/src/tint/writer/hlsl/generator_impl_initializer_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_initializer_test.cc
@@ -74,7 +74,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Initializer, EmitInitializer_Type_Float) {
-    WrapInFunction(Construct<f32>(-1.2e-5_f));
+    WrapInFunction(Call<f32>(-1.2e-5_f));
 
     GeneratorImpl& gen = Build();
 
@@ -85,7 +85,7 @@
 TEST_F(HlslGeneratorImplTest_Initializer, EmitInitializer_Type_F16) {
     Enable(ast::Extension::kF16);
 
-    WrapInFunction(Construct<f16>(-1.2e-3_h));
+    WrapInFunction(Call<f16>(-1.2e-3_h));
 
     GeneratorImpl& gen = Build();
 
@@ -94,7 +94,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Initializer, EmitInitializer_Type_Bool) {
-    WrapInFunction(Construct<bool>(true));
+    WrapInFunction(Call<bool>(true));
 
     GeneratorImpl& gen = Build();
 
@@ -103,7 +103,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Initializer, EmitInitializer_Type_Int) {
-    WrapInFunction(Construct<i32>(-12345_i));
+    WrapInFunction(Call<i32>(-12345_i));
 
     GeneratorImpl& gen = Build();
 
@@ -112,7 +112,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Initializer, EmitInitializer_Type_Uint) {
-    WrapInFunction(Construct<u32>(12345_u));
+    WrapInFunction(Call<u32>(12345_u));
 
     GeneratorImpl& gen = Build();
 
@@ -396,8 +396,8 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Initializer, EmitInitializer_Type_Array) {
-    WrapInFunction(Construct(ty.array(ty.vec3<f32>(), 3_u), vec3<f32>(1_f, 2_f, 3_f),
-                             vec3<f32>(4_f, 5_f, 6_f), vec3<f32>(7_f, 8_f, 9_f)));
+    WrapInFunction(Call(ty.array(ty.vec3<f32>(), 3_u), vec3<f32>(1_f, 2_f, 3_f),
+                        vec3<f32>(4_f, 5_f, 6_f), vec3<f32>(7_f, 8_f, 9_f)));
 
     GeneratorImpl& gen = Build();
 
@@ -407,7 +407,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Initializer, EmitInitializer_Type_Array_Empty) {
-    WrapInFunction(Construct(ty.array(ty.vec3<f32>(), 3_u)));
+    WrapInFunction(Call(ty.array(ty.vec3<f32>(), 3_u)));
 
     GeneratorImpl& gen = Build();
 
@@ -422,7 +422,7 @@
                                    Member("c", ty.vec3<i32>()),
                                });
 
-    WrapInFunction(Construct(ty.Of(str), 1_i, 2_f, vec3<i32>(3_i, 4_i, 5_i)));
+    WrapInFunction(Call(ty.Of(str), 1_i, 2_f, vec3<i32>(3_i, 4_i, 5_i)));
 
     GeneratorImpl& gen = SanitizeAndBuild();
 
@@ -437,7 +437,7 @@
                                    Member("c", ty.vec3<i32>()),
                                });
 
-    WrapInFunction(Construct(ty.Of(str)));
+    WrapInFunction(Call(ty.Of(str)));
 
     GeneratorImpl& gen = SanitizeAndBuild();
 
diff --git a/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc b/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc
index bec778a..d4dc440 100644
--- a/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc
@@ -1000,7 +1000,7 @@
     });
 
     SetupFunction(utils::Vector{
-        Decl(Var("value", p.member_type(ty), Construct(p.member_type(ty)))),
+        Decl(Var("value", p.member_type(ty), Call(p.member_type(ty)))),
         Assign(MemberAccessor("data", "b"), Expr("value")),
     });
 
@@ -1134,7 +1134,7 @@
     });
 
     SetupFunction(utils::Vector{
-        Assign(MemberAccessor("data", "b"), Construct(ty.mat2x3<f32>())),
+        Assign(MemberAccessor("data", "b"), Call(ty.mat2x3<f32>())),
     });
 
     GeneratorImpl& gen = SanitizeAndBuild();
diff --git a/src/tint/writer/hlsl/generator_impl_module_constant_test.cc b/src/tint/writer/hlsl/generator_impl_module_constant_test.cc
index 57dc4b8..212a5d5 100644
--- a/src/tint/writer/hlsl/generator_impl_module_constant_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_module_constant_test.cc
@@ -109,7 +109,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_vec3_AInt) {
-    auto* var = GlobalConst("G", Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
+    auto* var = GlobalConst("G", Call(ty.vec3(nullptr), 1_a, 2_a, 3_a));
     Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", Expr(var)))});
 
     GeneratorImpl& gen = Build();
@@ -123,7 +123,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_vec3_AFloat) {
-    auto* var = GlobalConst("G", Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
+    auto* var = GlobalConst("G", Call(ty.vec3(nullptr), 1._a, 2._a, 3._a));
     Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", Expr(var)))});
 
     GeneratorImpl& gen = Build();
@@ -167,8 +167,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_mat2x3_AFloat) {
-    auto* var =
-        GlobalConst("G", Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
+    auto* var = GlobalConst("G", Call(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
     Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", Expr(var)))});
 
     GeneratorImpl& gen = Build();
@@ -212,7 +211,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_arr_f32) {
-    auto* var = GlobalConst("G", Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
+    auto* var = GlobalConst("G", Call(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
     Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", Expr(var)))});
 
     GeneratorImpl& gen = Build();
@@ -226,10 +225,10 @@
 }
 
 TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_arr_vec2_bool) {
-    auto* var = GlobalConst("G", Construct(ty.array(ty.vec2<bool>(), 3_u),  //
-                                           vec2<bool>(true, false),         //
-                                           vec2<bool>(false, true),         //
-                                           vec2<bool>(true, true)));
+    auto* var = GlobalConst("G", Call(ty.array(ty.vec2<bool>(), 3_u),  //
+                                      vec2<bool>(true, false),         //
+                                      vec2<bool>(false, true),         //
+                                      vec2<bool>(true, true)));
     Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", Expr(var)))});
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/hlsl/generator_impl_sanitizer_test.cc b/src/tint/writer/hlsl/generator_impl_sanitizer_test.cc
index 10c4147..cede53c 100644
--- a/src/tint/writer/hlsl/generator_impl_sanitizer_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_sanitizer_test.cc
@@ -203,7 +203,7 @@
                                    Member("b", ty.vec3<f32>()),
                                    Member("c", ty.i32()),
                                });
-    auto* struct_init = Construct(ty.Of(str), 1_i, vec3<f32>(2_f, runtime_value, 4_f), 4_i);
+    auto* struct_init = Call(ty.Of(str), 1_i, vec3<f32>(2_f, runtime_value, 4_f), 4_i);
     auto* struct_access = MemberAccessor(struct_init, "b");
     auto* pos = Var("pos", ty.vec3<f32>(), struct_access);
 
diff --git a/src/tint/writer/hlsl/generator_impl_variable_decl_statement_test.cc b/src/tint/writer/hlsl/generator_impl_variable_decl_statement_test.cc
index 11bf317..47a7db3 100644
--- a/src/tint/writer/hlsl/generator_impl_variable_decl_statement_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_variable_decl_statement_test.cc
@@ -39,7 +39,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Let) {
-    auto* var = Let("a", ty.f32(), Construct(ty.f32()));
+    auto* var = Let("a", ty.f32(), Call<f32>());
     auto* stmt = Decl(var);
     WrapInFunction(stmt);
 
@@ -52,7 +52,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const) {
-    auto* var = Const("a", ty.f32(), Construct(ty.f32()));
+    auto* var = Const("a", ty.f32(), Call<f32>());
     auto* stmt = Decl(var);
     WrapInFunction(stmt);
 
@@ -175,7 +175,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_vec3_AInt) {
-    auto* C = Const("C", Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
+    auto* C = Const("C", Call(ty.vec3(nullptr), 1_a, 2_a, 3_a));
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(C),
@@ -193,7 +193,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_vec3_AFloat) {
-    auto* C = Const("C", Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
+    auto* C = Const("C", Call(ty.vec3(nullptr), 1._a, 2._a, 3._a));
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(C),
@@ -249,7 +249,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_mat2x3_AFloat) {
-    auto* C = Const("C", Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
+    auto* C = Const("C", Call(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(C),
@@ -305,7 +305,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_arr_f32) {
-    auto* C = Const("C", Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
+    auto* C = Const("C", Call(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(C),
@@ -323,10 +323,10 @@
 }
 
 TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_arr_vec2_bool) {
-    auto* C = Const("C", Construct(ty.array(ty.vec2<bool>(), 3_u),  //
-                                   vec2<bool>(true, false),         //
-                                   vec2<bool>(false, true),         //
-                                   vec2<bool>(true, true)));
+    auto* C = Const("C", Call(ty.array(ty.vec2<bool>(), 3_u),  //
+                              vec2<bool>(true, false),         //
+                              vec2<bool>(false, true),         //
+                              vec2<bool>(true, true)));
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(C),
diff --git a/src/tint/writer/msl/generator_impl_cast_test.cc b/src/tint/writer/msl/generator_impl_cast_test.cc
index 74b3be6..ec1fe7c 100644
--- a/src/tint/writer/msl/generator_impl_cast_test.cc
+++ b/src/tint/writer/msl/generator_impl_cast_test.cc
@@ -22,7 +22,7 @@
 using MslGeneratorImplTest = TestHelper;
 
 TEST_F(MslGeneratorImplTest, EmitExpression_Cast_Scalar) {
-    auto* cast = Construct<f32>(1_i);
+    auto* cast = Call<f32>(1_i);
     WrapInFunction(cast);
 
     GeneratorImpl& gen = Build();
@@ -44,7 +44,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, EmitExpression_Cast_IntMin) {
-    auto* cast = Construct<u32>(i32(std::numeric_limits<int32_t>::min()));
+    auto* cast = Call<u32>(i32(std::numeric_limits<int32_t>::min()));
     WrapInFunction(cast);
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/msl/generator_impl_function_test.cc b/src/tint/writer/msl/generator_impl_function_test.cc
index 0b01e1c..a1e91fe 100644
--- a/src/tint/writer/msl/generator_impl_function_test.cc
+++ b/src/tint/writer/msl/generator_impl_function_test.cc
@@ -194,8 +194,8 @@
         });
 
     Func("vert_main", utils::Empty, ty.Of(interface_struct),
-         utils::Vector{Return(Construct(ty.Of(interface_struct), Expr(0.5_f), Expr(0.25_f),
-                                        Construct(ty.vec4<f32>())))},
+         utils::Vector{Return(
+             Call(ty.Of(interface_struct), Expr(0.5_f), Expr(0.25_f), Call(ty.vec4<f32>())))},
          utils::Vector{Stage(ast::PipelineStage::kVertex)});
 
     Func("frag_main", utils::Vector{Param("colors", ty.Of(interface_struct))}, ty.void_(),
@@ -277,8 +277,8 @@
 
     Func("foo", utils::Vector{Param("x", ty.f32())}, ty.Of(vertex_output_struct),
          utils::Vector{
-             Return(Construct(ty.Of(vertex_output_struct),
-                              Construct(ty.vec4<f32>(), "x", "x", "x", Expr(1_f)))),
+             Return(
+                 Call(ty.Of(vertex_output_struct), Call(ty.vec4<f32>(), "x", "x", "x", Expr(1_f)))),
          });
     Func("vert_main1", utils::Empty, ty.Of(vertex_output_struct),
          utils::Vector{Return(Expr(Call("foo", Expr(0.5_f))))},
@@ -606,7 +606,7 @@
 TEST_F(MslGeneratorImplTest, Emit_Function_WithArrayReturn) {
     Func("my_func", utils::Empty, ty.array<f32, 5>(),
          utils::Vector{
-             Return(Construct(ty.array<f32, 5>())),
+             Return(Call(ty.array<f32, 5>())),
          });
 
     GeneratorImpl& gen = SanitizeAndBuild();
diff --git a/src/tint/writer/msl/generator_impl_initializer_test.cc b/src/tint/writer/msl/generator_impl_initializer_test.cc
index 105e95f..bbcadfd 100644
--- a/src/tint/writer/msl/generator_impl_initializer_test.cc
+++ b/src/tint/writer/msl/generator_impl_initializer_test.cc
@@ -74,7 +74,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, EmitInitializer_Type_Float) {
-    WrapInFunction(Construct<f32>(-1.2e-5_f));
+    WrapInFunction(Call<f32>(-1.2e-5_f));
 
     GeneratorImpl& gen = Build();
 
@@ -85,7 +85,7 @@
 TEST_F(MslGeneratorImplTest, EmitInitializer_Type_F16) {
     Enable(ast::Extension::kF16);
 
-    WrapInFunction(Construct<f16>(-1.2e-3_h));
+    WrapInFunction(Call<f16>(-1.2e-3_h));
 
     GeneratorImpl& gen = Build();
 
@@ -94,7 +94,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, EmitInitializer_Type_Bool) {
-    WrapInFunction(Construct<bool>(true));
+    WrapInFunction(Call<bool>(true));
 
     GeneratorImpl& gen = Build();
 
@@ -103,7 +103,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, EmitInitializer_Type_Int) {
-    WrapInFunction(Construct<i32>(-12345_i));
+    WrapInFunction(Call<i32>(-12345_i));
 
     GeneratorImpl& gen = Build();
 
@@ -112,7 +112,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, EmitInitializer_Type_Uint) {
-    WrapInFunction(Construct<u32>(12345_u));
+    WrapInFunction(Call<u32>(12345_u));
 
     GeneratorImpl& gen = Build();
 
@@ -376,8 +376,8 @@
 }
 
 TEST_F(MslGeneratorImplTest, EmitInitializer_Type_Array) {
-    WrapInFunction(Construct(ty.array(ty.vec3<f32>(), 3_u), vec3<f32>(1_f, 2_f, 3_f),
-                             vec3<f32>(4_f, 5_f, 6_f), vec3<f32>(7_f, 8_f, 9_f)));
+    WrapInFunction(Call(ty.array(ty.vec3<f32>(), 3_u), vec3<f32>(1_f, 2_f, 3_f),
+                        vec3<f32>(4_f, 5_f, 6_f), vec3<f32>(7_f, 8_f, 9_f)));
 
     GeneratorImpl& gen = Build();
 
@@ -393,7 +393,7 @@
                                    Member("c", ty.vec3<i32>()),
                                });
 
-    WrapInFunction(Construct(ty.Of(str), 1_i, 2_f, vec3<i32>(3_i, 4_i, 5_i)));
+    WrapInFunction(Call(ty.Of(str), 1_i, 2_f, vec3<i32>(3_i, 4_i, 5_i)));
 
     GeneratorImpl& gen = Build();
 
@@ -408,7 +408,7 @@
                                    Member("c", ty.vec3<i32>()),
                                });
 
-    WrapInFunction(Construct(ty.Of(str)));
+    WrapInFunction(Call(ty.Of(str)));
 
     GeneratorImpl& gen = Build();
 
diff --git a/src/tint/writer/msl/generator_impl_module_constant_test.cc b/src/tint/writer/msl/generator_impl_module_constant_test.cc
index 0ff3290..6de50d7 100644
--- a/src/tint/writer/msl/generator_impl_module_constant_test.cc
+++ b/src/tint/writer/msl/generator_impl_module_constant_test.cc
@@ -133,7 +133,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_GlobalConst_vec3_AInt) {
-    auto* var = GlobalConst("G", Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
+    auto* var = GlobalConst("G", Call(ty.vec3(nullptr), 1_a, 2_a, 3_a));
     Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", Expr(var)))});
 
     GeneratorImpl& gen = Build();
@@ -151,7 +151,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_GlobalConst_vec3_AFloat) {
-    auto* var = GlobalConst("G", Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
+    auto* var = GlobalConst("G", Call(ty.vec3(nullptr), 1._a, 2._a, 3._a));
     Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", Expr(var)))});
 
     GeneratorImpl& gen = Build();
@@ -207,8 +207,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_GlobalConst_mat2x3_AFloat) {
-    auto* var =
-        GlobalConst("G", Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
+    auto* var = GlobalConst("G", Call(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
     Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", Expr(var)))});
 
     GeneratorImpl& gen = Build();
@@ -264,7 +263,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_GlobalConst_arr_f32) {
-    auto* var = GlobalConst("G", Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
+    auto* var = GlobalConst("G", Call(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
     Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", Expr(var)))});
 
     GeneratorImpl& gen = Build();
@@ -295,10 +294,10 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_GlobalConst_arr_vec2_bool) {
-    auto* var = GlobalConst("G", Construct(ty.array(ty.vec2<bool>(), 3_u),  //
-                                           vec2<bool>(true, false),         //
-                                           vec2<bool>(false, true),         //
-                                           vec2<bool>(true, true)));
+    auto* var = GlobalConst("G", Call(ty.array(ty.vec2<bool>(), 3_u),  //
+                                      vec2<bool>(true, false),         //
+                                      vec2<bool>(false, true),         //
+                                      vec2<bool>(true, true)));
     Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(Let("l", Expr(var)))});
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/msl/generator_impl_test.cc b/src/tint/writer/msl/generator_impl_test.cc
index 6a0a992..7f0e8f5 100644
--- a/src/tint/writer/msl/generator_impl_test.cc
+++ b/src/tint/writer/msl/generator_impl_test.cc
@@ -102,7 +102,7 @@
                                                 Invariant(),
                                             }),
                                  });
-    Func("vert_main", utils::Empty, ty.Of(out), utils::Vector{Return(Construct(ty.Of(out)))},
+    Func("vert_main", utils::Empty, ty.Of(out), utils::Vector{Return(Call(ty.Of(out)))},
          utils::Vector{
              Stage(ast::PipelineStage::kVertex),
          });
@@ -139,7 +139,7 @@
                                                 Builtin(ast::BuiltinValue::kPosition),
                                             }),
                                  });
-    Func("vert_main", utils::Empty, ty.Of(out), utils::Vector{Return(Construct(ty.Of(out)))},
+    Func("vert_main", utils::Empty, ty.Of(out), utils::Vector{Return(Call(ty.Of(out)))},
          utils::Vector{
              Stage(ast::PipelineStage::kVertex),
          });
diff --git a/src/tint/writer/msl/generator_impl_variable_decl_statement_test.cc b/src/tint/writer/msl/generator_impl_variable_decl_statement_test.cc
index 5ee1c33..5631b4d 100644
--- a/src/tint/writer/msl/generator_impl_variable_decl_statement_test.cc
+++ b/src/tint/writer/msl/generator_impl_variable_decl_statement_test.cc
@@ -39,7 +39,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Let) {
-    auto* var = Let("a", ty.f32(), Construct(ty.f32()));
+    auto* var = Let("a", ty.f32(), Call<f32>());
     auto* stmt = Decl(var);
     WrapInFunction(stmt);
 
@@ -52,7 +52,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const) {
-    auto* var = Const("a", ty.f32(), Construct(ty.f32()));
+    auto* var = Const("a", ty.f32(), Call<f32>());
     auto* stmt = Decl(var);
     WrapInFunction(stmt);
 
@@ -175,7 +175,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_vec3_AInt) {
-    auto* C = Const("C", Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
+    auto* C = Const("C", Call(ty.vec3(nullptr), 1_a, 2_a, 3_a));
     Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(C), Decl(Let("l", Expr(C)))});
 
     GeneratorImpl& gen = Build();
@@ -193,7 +193,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_vec3_AFloat) {
-    auto* C = Const("C", Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
+    auto* C = Const("C", Call(ty.vec3(nullptr), 1._a, 2._a, 3._a));
     Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(C), Decl(Let("l", Expr(C)))});
 
     GeneratorImpl& gen = Build();
@@ -249,7 +249,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_mat2x3_AFloat) {
-    auto* C = Const("C", Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
+    auto* C = Const("C", Call(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
     Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(C), Decl(Let("l", Expr(C)))});
 
     GeneratorImpl& gen = Build();
@@ -305,7 +305,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_arr_f32) {
-    auto* C = Const("C", Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
+    auto* C = Const("C", Call(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
     Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(C), Decl(Let("l", Expr(C)))});
 
     GeneratorImpl& gen = Build();
@@ -336,10 +336,10 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_arr_vec2_bool) {
-    auto* C = Const("C", Construct(ty.array(ty.vec2<bool>(), 3_u),  //
-                                   vec2<bool>(true, false),         //
-                                   vec2<bool>(false, true),         //
-                                   vec2<bool>(true, true)));
+    auto* C = Const("C", Call(ty.array(ty.vec2<bool>(), 3_u),  //
+                              vec2<bool>(true, false),         //
+                              vec2<bool>(false, true),         //
+                              vec2<bool>(true, true)));
     Func("f", utils::Empty, ty.void_(), utils::Vector{Decl(C), Decl(Let("l", Expr(C)))});
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/spirv/builder_accessor_expression_test.cc b/src/tint/writer/spirv/builder_accessor_expression_test.cc
index 925406a..ccbcad6 100644
--- a/src/tint/writer/spirv/builder_accessor_expression_test.cc
+++ b/src/tint/writer/spirv/builder_accessor_expression_test.cc
@@ -580,8 +580,8 @@
     // var x = pos[1u][0u];
 
     auto* pos = Let("pos", ty.array(ty.vec2<f32>(), 3_u),
-                    Construct(ty.array(ty.vec2<f32>(), 3_u), vec2<f32>(0_f, 0.5_f),
-                              vec2<f32>(-0.5_f, -0.5_f), vec2<f32>(0.5_f, -0.5_f)));
+                    Call(ty.array(ty.vec2<f32>(), 3_u), vec2<f32>(0_f, 0.5_f),
+                         vec2<f32>(-0.5_f, -0.5_f), vec2<f32>(0.5_f, -0.5_f)));
     auto* x = Var("x", IndexAccessor(IndexAccessor(pos, 1_u), 0_u));
     WrapInFunction(pos, x);
 
@@ -627,8 +627,8 @@
     // var x = pos[1u][0u];
 
     auto* pos = Const("pos", ty.array(ty.vec2<f32>(), 3_u),
-                      Construct(ty.array(ty.vec2<f32>(), 3_u), vec2<f32>(0_f, 0.5_f),
-                                vec2<f32>(-0.5_f, -0.5_f), vec2<f32>(0.5_f, -0.5_f)));
+                      Call(ty.array(ty.vec2<f32>(), 3_u), vec2<f32>(0_f, 0.5_f),
+                           vec2<f32>(-0.5_f, -0.5_f), vec2<f32>(0.5_f, -0.5_f)));
     auto* x = Var("x", IndexAccessor(IndexAccessor(pos, 1_u), 0_u));
     WrapInFunction(pos, x);
 
@@ -741,9 +741,9 @@
     // let a : mat2x2<f32>(vec2<f32>(1., 2.), vec2<f32>(3., 4.));
     // var x = a[1i]
 
-    auto* a = Let("a", ty.mat2x2<f32>(),
-                  Construct(ty.mat2x2<f32>(), Construct(ty.vec2<f32>(), 1_f, 2_f),
-                            Construct(ty.vec2<f32>(), 3_f, 4_f)));
+    auto* a =
+        Let("a", ty.mat2x2<f32>(),
+            Call(ty.mat2x2<f32>(), Call(ty.vec2<f32>(), 1_f, 2_f), Call(ty.vec2<f32>(), 3_f, 4_f)));
     auto* x = Var("x", IndexAccessor("a", 1_i));
     WrapInFunction(a, x);
 
@@ -783,9 +783,9 @@
     // const a : mat2x2<f32>(vec2<f32>(1., 2.), vec2<f32>(3., 4.));
     // var x = a[1i]
 
-    auto* a = Const("a", ty.mat2x2<f32>(),
-                    Construct(ty.mat2x2<f32>(), Construct(ty.vec2<f32>(), 1_f, 2_f),
-                              Construct(ty.vec2<f32>(), 3_f, 4_f)));
+    auto* a = Const(
+        "a", ty.mat2x2<f32>(),
+        Call(ty.mat2x2<f32>(), Call(ty.vec2<f32>(), 1_f, 2_f), Call(ty.vec2<f32>(), 3_f, 4_f)));
     auto* x = Var("x", IndexAccessor("a", 1_i));
     WrapInFunction(a, x);
 
@@ -994,7 +994,7 @@
                                          Member("b", ty.f32()),
                                      });
 
-    auto* var = Let("ident", ty.Of(s), Construct(ty.Of(s), 0_f, 0_f));
+    auto* var = Let("ident", ty.Of(s), Call(ty.Of(s), 0_f, 0_f));
 
     auto* expr = MemberAccessor("ident", "b");
     WrapInFunction(var, expr);
@@ -1035,8 +1035,8 @@
 
     auto* s_type = Structure("my_struct", utils::Vector{Member("inner", ty.Of(inner_struct))});
 
-    auto* var = Let("ident", ty.Of(s_type),
-                    Construct(ty.Of(s_type), Construct(ty.Of(inner_struct), 0_f, 0_f)));
+    auto* var =
+        Let("ident", ty.Of(s_type), Call(ty.Of(s_type), Call(ty.Of(inner_struct), 0_f, 0_f)));
     auto* expr = MemberAccessor(MemberAccessor("ident", "inner"), "b");
     WrapInFunction(var, expr);
 
diff --git a/src/tint/writer/spirv/builder_entry_point_test.cc b/src/tint/writer/spirv/builder_entry_point_test.cc
index f48c975..51995dd 100644
--- a/src/tint/writer/spirv/builder_entry_point_test.cc
+++ b/src/tint/writer/spirv/builder_entry_point_test.cc
@@ -215,7 +215,7 @@
             Member("pos", ty.vec4<f32>(), utils::Vector{Builtin(ast::BuiltinValue::kPosition)}),
         });
 
-    auto* vert_retval = Construct(ty.Of(interface), 42_f, Construct(ty.vec4<f32>()));
+    auto* vert_retval = Call(ty.Of(interface), 42_f, Call(ty.vec4<f32>()));
     Func("vert_main", utils::Empty, ty.Of(interface), utils::Vector{Return(vert_retval)},
          utils::Vector{
              Stage(ast::PipelineStage::kVertex),
diff --git a/src/tint/writer/spirv/builder_function_attribute_test.cc b/src/tint/writer/spirv/builder_function_attribute_test.cc
index b905d8c..9bba88f 100644
--- a/src/tint/writer/spirv/builder_function_attribute_test.cc
+++ b/src/tint/writer/spirv/builder_function_attribute_test.cc
@@ -57,7 +57,7 @@
     if (params.stage == ast::PipelineStage::kVertex) {
         ret_type = ty.vec4<f32>();
         ret_type_attrs.Push(Builtin(ast::BuiltinValue::kPosition));
-        body.Push(Return(Construct(ty.vec4<f32>())));
+        body.Push(Return(Call(ty.vec4<f32>())));
     } else {
         ret_type = ty.void_();
     }
@@ -132,9 +132,9 @@
 }
 
 TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_Const) {
-    GlobalConst("width", ty.i32(), Construct(ty.i32(), 2_i));
-    GlobalConst("height", ty.i32(), Construct(ty.i32(), 3_i));
-    GlobalConst("depth", ty.i32(), Construct(ty.i32(), 4_i));
+    GlobalConst("width", ty.i32(), Call<i32>(2_i));
+    GlobalConst("height", ty.i32(), Call<i32>(3_i));
+    GlobalConst("depth", ty.i32(), Call<i32>(4_i));
     auto* func = Func("main", utils::Empty, ty.void_(), utils::Empty,
                       utils::Vector{
                           WorkgroupSize("width", "height", "depth"),
@@ -150,9 +150,9 @@
 }
 
 TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_OverridableConst) {
-    Override("width", ty.i32(), Construct(ty.i32(), 2_i), Id(7_u));
-    Override("height", ty.i32(), Construct(ty.i32(), 3_i), Id(8_u));
-    Override("depth", ty.i32(), Construct(ty.i32(), 4_i), Id(9_u));
+    Override("width", ty.i32(), Call<i32>(2_i), Id(7_u));
+    Override("height", ty.i32(), Call<i32>(3_i), Id(8_u));
+    Override("depth", ty.i32(), Call<i32>(4_i), Id(9_u));
     auto* func = Func("main", utils::Empty, ty.void_(), utils::Empty,
                       utils::Vector{
                           WorkgroupSize("width", "height", "depth"),
@@ -168,8 +168,8 @@
 }
 
 TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_LiteralAndConst) {
-    Override("height", ty.i32(), Construct(ty.i32(), 2_i), Id(7_u));
-    GlobalConst("depth", ty.i32(), Construct(ty.i32(), 3_i));
+    Override("height", ty.i32(), Call<i32>(2_i), Id(7_u));
+    GlobalConst("depth", ty.i32(), Call<i32>(3_i));
     auto* func = Func("main", utils::Empty, ty.void_(), utils::Empty,
                       utils::Vector{
                           WorkgroupSize(4_i, "height", "depth"),
diff --git a/src/tint/writer/spirv/builder_global_variable_test.cc b/src/tint/writer/spirv/builder_global_variable_test.cc
index 1331471..c74def5 100644
--- a/src/tint/writer/spirv/builder_global_variable_test.cc
+++ b/src/tint/writer/spirv/builder_global_variable_test.cc
@@ -150,7 +150,7 @@
     // const c = vec3(1, 2, 3);
     // var v = c;
 
-    auto* c = GlobalConst("c", Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
+    auto* c = GlobalConst("c", Call(ty.vec3(nullptr), 1_a, 2_a, 3_a));
     GlobalVar("v", type::AddressSpace::kPrivate, Expr(c));
 
     spirv::Builder& b = SanitizeAndBuild();
@@ -179,7 +179,7 @@
     // const c = vec3(1.0, 2.0, 3.0);
     // var v = c;
 
-    auto* c = GlobalConst("c", Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
+    auto* c = GlobalConst("c", Call(ty.vec3(nullptr), 1._a, 2._a, 3._a));
     GlobalVar("v", type::AddressSpace::kPrivate, Expr(c));
 
     spirv::Builder& b = SanitizeAndBuild();
diff --git a/src/tint/writer/spirv/builder_initializer_expression_test.cc b/src/tint/writer/spirv/builder_initializer_expression_test.cc
index b8a1029..b78bd9d 100644
--- a/src/tint/writer/spirv/builder_initializer_expression_test.cc
+++ b/src/tint/writer/spirv/builder_initializer_expression_test.cc
@@ -54,7 +54,7 @@
 }
 
 TEST_F(SpvBuilderInitializerTest, Type_WithCasts) {
-    auto* t = vec2<f32>(Construct<f32>(1_i), Construct<f32>(1_i));
+    auto* t = vec2<f32>(Call<f32>(1_i), Call<f32>(1_i));
     WrapInFunction(t);
 
     spirv::Builder& b = Build();
@@ -77,7 +77,7 @@
     // cast<Int>(2.3f)
 
     auto* alias = Alias("Int", ty.i32());
-    auto* cast = Construct(ty.Of(alias), 2.3_f);
+    auto* cast = Call(ty.Of(alias), 2.3_f);
     WrapInFunction(cast);
 
     spirv::Builder& b = Build();
@@ -151,7 +151,7 @@
 }
 
 TEST_F(SpvBuilderInitializerTest, Type_Bool_With_Bool) {
-    auto* cast = Construct<bool>(true);
+    auto* cast = Call<bool>(true);
     WrapInFunction(cast);
 
     spirv::Builder& b = Build();
@@ -168,7 +168,7 @@
 }
 
 TEST_F(SpvBuilderInitializerTest, Type_I32_With_I32) {
-    auto* cast = Construct<i32>(2_i);
+    auto* cast = Call<i32>(2_i);
     WrapInFunction(cast);
 
     spirv::Builder& b = Build();
@@ -183,7 +183,7 @@
 }
 
 TEST_F(SpvBuilderInitializerTest, Type_U32_With_U32) {
-    auto* cast = Construct<u32>(2_u);
+    auto* cast = Call<u32>(2_u);
     WrapInFunction(cast);
 
     spirv::Builder& b = Build();
@@ -198,7 +198,7 @@
 }
 
 TEST_F(SpvBuilderInitializerTest, Type_F32_With_F32) {
-    auto* cast = Construct<f32>(2_f);
+    auto* cast = Call<f32>(2_f);
     WrapInFunction(cast);
 
     spirv::Builder& b = Build();
@@ -215,7 +215,7 @@
 TEST_F(SpvBuilderInitializerTest, Type_F16_With_F16) {
     Enable(ast::Extension::kF16);
 
-    auto* cast = Construct<f16>(2_h);
+    auto* cast = Call<f16>(2_h);
     WrapInFunction(cast);
 
     spirv::Builder& b = Build();
@@ -1890,7 +1890,7 @@
 }
 
 TEST_F(SpvBuilderInitializerTest, Type_GlobalConst_F32_With_F32) {
-    auto* ctor = Construct<f32>(2_f);
+    auto* ctor = Call<f32>(2_f);
     GlobalConst("g", ty.f32(), ctor);
     WrapInFunction(Decl(Var("l", Expr("g"))));
 
@@ -1913,7 +1913,7 @@
 TEST_F(SpvBuilderInitializerTest, Type_GlobalConst_F16_With_F16) {
     Enable(ast::Extension::kF16);
 
-    auto* ctor = Construct<f16>(2_h);
+    auto* ctor = Call<f16>(2_h);
     GlobalConst("g", ty.f16(), ctor);
     WrapInFunction(Decl(Var("l", Expr("g"))));
 
@@ -1934,7 +1934,7 @@
 }
 
 TEST_F(SpvBuilderInitializerTest, Type_GlobalVar_F32_With_F32) {
-    auto* ctor = Construct<f32>(2_f);
+    auto* ctor = Call<f32>(2_f);
     GlobalVar("g", ty.f32(), type::AddressSpace::kPrivate, ctor);
 
     spirv::Builder& b = SanitizeAndBuild();
@@ -1953,7 +1953,7 @@
 TEST_F(SpvBuilderInitializerTest, Type_GlobalVar_F16_With_F16) {
     Enable(ast::Extension::kF16);
 
-    auto* ctor = Construct<f16>(2_h);
+    auto* ctor = Call<f16>(2_h);
     GlobalVar("g", ty.f16(), type::AddressSpace::kPrivate, ctor);
 
     spirv::Builder& b = SanitizeAndBuild();
@@ -1970,7 +1970,7 @@
 }
 
 TEST_F(SpvBuilderInitializerTest, Type_GlobalConst_U32_With_F32) {
-    auto* ctor = Construct<u32>(1.5_f);
+    auto* ctor = Call<u32>(1.5_f);
     GlobalConst("g", ty.u32(), ctor);
     WrapInFunction(Decl(Var("l", Expr("g"))));
 
@@ -1993,7 +1993,7 @@
 TEST_F(SpvBuilderInitializerTest, Type_GlobalConst_U32_With_F16) {
     Enable(ast::Extension::kF16);
 
-    auto* ctor = Construct<u32>(1.5_h);
+    auto* ctor = Call<u32>(1.5_h);
     GlobalConst("g", ty.u32(), ctor);
     WrapInFunction(Decl(Var("l", Expr("g"))));
 
@@ -2014,7 +2014,7 @@
 }
 
 TEST_F(SpvBuilderInitializerTest, Type_GlobalVar_U32_With_F32) {
-    auto* ctor = Construct<u32>(1.5_f);
+    auto* ctor = Call<u32>(1.5_f);
     GlobalVar("g", ty.u32(), type::AddressSpace::kPrivate, ctor);
 
     spirv::Builder& b = SanitizeAndBuild();
@@ -2033,7 +2033,7 @@
 TEST_F(SpvBuilderInitializerTest, Type_GlobalVar_U32_With_F16) {
     Enable(ast::Extension::kF16);
 
-    auto* ctor = Construct<u32>(1.5_h);
+    auto* ctor = Call<u32>(1.5_h);
     GlobalVar("g", ty.u32(), type::AddressSpace::kPrivate, ctor);
 
     spirv::Builder& b = SanitizeAndBuild();
@@ -3589,7 +3589,7 @@
 TEST_F(SpvBuilderInitializerTest, Type_Array_2_Vec3_F32) {
     auto* first = vec3<f32>(1_f, 2_f, 3_f);
     auto* second = vec3<f32>(1_f, 2_f, 3_f);
-    auto* t = Construct(ty.array(ty.vec3<f32>(), 2_u), first, second);
+    auto* t = Call(ty.array(ty.vec3<f32>(), 2_u), first, second);
     WrapInFunction(t);
     spirv::Builder& b = Build();
 
@@ -3613,7 +3613,7 @@
 
     auto* first = vec3<f16>(1_h, 2_h, 3_h);
     auto* second = vec3<f16>(1_h, 2_h, 3_h);
-    auto* t = Construct(ty.array(ty.vec3<f16>(), 2_u), first, second);
+    auto* t = Call(ty.array(ty.vec3<f16>(), 2_u), first, second);
     WrapInFunction(t);
     spirv::Builder& b = Build();
 
@@ -3701,7 +3701,7 @@
                                          Member("b", ty.vec3<f32>()),
                                      });
 
-    auto* t = Construct(ty.Of(s), 2_f, vec3<f32>(2_f, 2_f, 2_f));
+    auto* t = Call(ty.Of(s), 2_f, vec3<f32>(2_f, 2_f, 2_f));
     WrapInFunction(t);
 
     spirv::Builder& b = Build();
@@ -3721,7 +3721,7 @@
 }
 
 TEST_F(SpvBuilderInitializerTest, Type_ZeroInit_F32) {
-    auto* t = Construct<f32>();
+    auto* t = Call<f32>();
 
     WrapInFunction(t);
 
@@ -3740,7 +3740,7 @@
 TEST_F(SpvBuilderInitializerTest, Type_ZeroInit_F16) {
     Enable(ast::Extension::kF16);
 
-    auto* t = Construct<f16>();
+    auto* t = Call<f16>();
 
     WrapInFunction(t);
 
@@ -3757,7 +3757,7 @@
 }
 
 TEST_F(SpvBuilderInitializerTest, Type_ZeroInit_I32) {
-    auto* t = Construct<i32>();
+    auto* t = Call<i32>();
 
     WrapInFunction(t);
 
@@ -3774,7 +3774,7 @@
 }
 
 TEST_F(SpvBuilderInitializerTest, Type_ZeroInit_U32) {
-    auto* t = Construct<u32>();
+    auto* t = Call<u32>();
 
     WrapInFunction(t);
 
@@ -3791,7 +3791,7 @@
 }
 
 TEST_F(SpvBuilderInitializerTest, Type_ZeroInit_Bool) {
-    auto* t = Construct<bool>();
+    auto* t = Call<bool>();
 
     WrapInFunction(t);
 
@@ -3887,7 +3887,7 @@
 
 TEST_F(SpvBuilderInitializerTest, Type_ZeroInit_Struct) {
     auto* s = Structure("my_struct", utils::Vector{Member("a", ty.f32())});
-    auto* t = Construct(ty.Of(s));
+    auto* t = Call(ty.Of(s));
     WrapInFunction(t);
 
     spirv::Builder& b = Build();
@@ -3905,7 +3905,7 @@
 
 TEST_F(SpvBuilderInitializerTest, Type_Convert_U32_To_I32) {
     auto* var = Decl(Var("x", ty.u32(), Expr(2_u)));
-    auto* cast = Construct<i32>("x");
+    auto* cast = Call<i32>("x");
     WrapInFunction(var, cast);
 
     spirv::Builder& b = Build();
@@ -3929,7 +3929,7 @@
 
 TEST_F(SpvBuilderInitializerTest, Type_Convert_F32_To_I32) {
     auto* var = Decl(Var("x", ty.f32(), Expr(2.4_f)));
-    auto* cast = Construct<i32>("x");
+    auto* cast = Call<i32>("x");
     WrapInFunction(var, cast);
 
     spirv::Builder& b = Build();
@@ -3955,7 +3955,7 @@
     Enable(ast::Extension::kF16);
 
     auto* var = Decl(Var("x", ty.f16(), Expr(2.4_h)));
-    auto* cast = Construct<i32>("x");
+    auto* cast = Call<i32>("x");
     WrapInFunction(var, cast);
 
     spirv::Builder& b = Build();
@@ -3979,7 +3979,7 @@
 
 TEST_F(SpvBuilderInitializerTest, Type_Convert_I32_To_U32) {
     auto* var = Decl(Var("x", ty.i32(), Expr(2_i)));
-    auto* cast = Construct<u32>("x");
+    auto* cast = Call<u32>("x");
     WrapInFunction(var, cast);
 
     spirv::Builder& b = Build();
@@ -4003,7 +4003,7 @@
 
 TEST_F(SpvBuilderInitializerTest, Type_Convert_F32_To_U32) {
     auto* var = Decl(Var("x", ty.f32(), Expr(2.4_f)));
-    auto* cast = Construct<u32>("x");
+    auto* cast = Call<u32>("x");
     WrapInFunction(var, cast);
 
     spirv::Builder& b = Build();
@@ -4029,7 +4029,7 @@
     Enable(ast::Extension::kF16);
 
     auto* var = Decl(Var("x", ty.f16(), Expr(2.4_h)));
-    auto* cast = Construct<u32>("x");
+    auto* cast = Call<u32>("x");
     WrapInFunction(var, cast);
 
     spirv::Builder& b = Build();
@@ -4053,7 +4053,7 @@
 
 TEST_F(SpvBuilderInitializerTest, Type_Convert_I32_To_F32) {
     auto* var = Decl(Var("x", ty.i32(), Expr(2_i)));
-    auto* cast = Construct<f32>("x");
+    auto* cast = Call<f32>("x");
     WrapInFunction(var, cast);
 
     spirv::Builder& b = Build();
@@ -4077,7 +4077,7 @@
 
 TEST_F(SpvBuilderInitializerTest, Type_Convert_U32_To_F32) {
     auto* var = Decl(Var("x", ty.u32(), Expr(2_u)));
-    auto* cast = Construct<f32>("x");
+    auto* cast = Call<f32>("x");
     WrapInFunction(var, cast);
 
     spirv::Builder& b = Build();
@@ -4103,7 +4103,7 @@
     Enable(ast::Extension::kF16);
 
     auto* var = Decl(Var("x", ty.f16(), Expr(2_h)));
-    auto* cast = Construct<f32>("x");
+    auto* cast = Call<f32>("x");
     WrapInFunction(var, cast);
 
     spirv::Builder& b = Build();
@@ -4129,7 +4129,7 @@
     Enable(ast::Extension::kF16);
 
     auto* var = Decl(Var("x", ty.i32(), Expr(2_i)));
-    auto* cast = Construct<f16>("x");
+    auto* cast = Call<f16>("x");
     WrapInFunction(var, cast);
 
     spirv::Builder& b = Build();
@@ -4155,7 +4155,7 @@
     Enable(ast::Extension::kF16);
 
     auto* var = Decl(Var("x", ty.u32(), Expr(2_u)));
-    auto* cast = Construct<f16>("x");
+    auto* cast = Call<f16>("x");
     WrapInFunction(var, cast);
 
     spirv::Builder& b = Build();
@@ -4181,7 +4181,7 @@
     Enable(ast::Extension::kF16);
 
     auto* var = Decl(Var("x", ty.f32(), Expr(2_f)));
-    auto* cast = Construct<f16>("x");
+    auto* cast = Call<f16>("x");
     WrapInFunction(var, cast);
 
     spirv::Builder& b = Build();
@@ -4541,8 +4541,8 @@
 TEST_F(SpvBuilderInitializerTest, IsInitializerConst_GlobalArrayWithAllConstInitializers) {
     // array<vec3<f32>, 2u>(vec3<f32>(1.0, 2.0, 3.0), vec3<f32>(1.0, 2.0, 3.0))
     //   -> true
-    auto* t = Construct(ty.array(ty.vec3<f32>(), 2_u), vec3<f32>(1_f, 2_f, 3_f),
-                        vec3<f32>(1_f, 2_f, 3_f));
+    auto* t =
+        Call(ty.array(ty.vec3<f32>(), 2_u), vec3<f32>(1_f, 2_f, 3_f), vec3<f32>(1_f, 2_f, 3_f));
     WrapInFunction(t);
 
     spirv::Builder& b = Build();
@@ -4554,7 +4554,7 @@
 TEST_F(SpvBuilderInitializerTest, IsInitializerConst_GlobalVectorWithMatchingTypeInitializers) {
     // vec2<f32>(f32(1.0), f32(2.0))  -> false
 
-    auto* t = vec2<f32>(Construct<f32>(1_f), Construct<f32>(2_f));
+    auto* t = vec2<f32>(Call<f32>(1_f), Call<f32>(2_f));
     WrapInFunction(t);
 
     spirv::Builder& b = Build();
@@ -4566,7 +4566,7 @@
 TEST_F(SpvBuilderInitializerTest, IsInitializerConst_GlobalWithTypeConversionInitializer) {
     // vec2<f32>(f32(1), f32(2)) -> false
 
-    auto* t = vec2<f32>(Construct<f32>(1_i), Construct<f32>(2_i));
+    auto* t = vec2<f32>(Call<f32>(1_i), Call<f32>(2_i));
     WrapInFunction(t);
 
     spirv::Builder& b = Build();
@@ -4610,7 +4610,7 @@
     auto* first = vec3<f32>(1_f, 2_f, 3_f);
     auto* second = vec3<f32>(1_f, 2_f, 3_f);
 
-    auto* t = Construct(ty.array(ty.vec3<f32>(), 2_u), first, second);
+    auto* t = Call(ty.array(ty.vec3<f32>(), 2_u), first, second);
     WrapInFunction(t);
 
     spirv::Builder& b = Build();
@@ -4622,7 +4622,7 @@
 TEST_F(SpvBuilderInitializerTest, IsInitializerConst_VectorWithTypeConversionConstInitializers) {
     // vec2<f32>(f32(1), f32(2))  -> false
 
-    auto* t = vec2<f32>(Construct<f32>(1_i), Construct<f32>(2_i));
+    auto* t = vec2<f32>(Call<f32>(1_i), Call<f32>(2_i));
     WrapInFunction(t);
 
     spirv::Builder& b = Build();
@@ -4632,7 +4632,7 @@
 }
 
 TEST_F(SpvBuilderInitializerTest, IsInitializerConst_BitCastScalars) {
-    auto* t = vec2<u32>(Construct<u32>(1_i), Construct<u32>(1_i));
+    auto* t = vec2<u32>(Call<u32>(1_i), Call<u32>(1_i));
     WrapInFunction(t);
 
     spirv::Builder& b = Build();
@@ -4647,7 +4647,7 @@
                                          Member("b", ty.vec3<f32>()),
                                      });
 
-    auto* t = Construct(ty.Of(s), 2_f, vec3<f32>(2_f, 2_f, 2_f));
+    auto* t = Call(ty.Of(s), 2_f, vec3<f32>(2_f, 2_f, 2_f));
     WrapInFunction(t);
 
     spirv::Builder& b = Build();
@@ -4665,7 +4665,7 @@
     GlobalVar("a", ty.f32(), type::AddressSpace::kPrivate);
     GlobalVar("b", ty.vec3<f32>(), type::AddressSpace::kPrivate);
 
-    auto* t = Construct(ty.Of(s), "a", "b");
+    auto* t = Call(ty.Of(s), "a", "b");
     WrapInFunction(t);
 
     spirv::Builder& b = Build();
diff --git a/src/tint/writer/wgsl/generator_impl_cast_test.cc b/src/tint/writer/wgsl/generator_impl_cast_test.cc
index 9b9379b..b10fd8f 100644
--- a/src/tint/writer/wgsl/generator_impl_cast_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_cast_test.cc
@@ -22,7 +22,7 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, EmitExpression_Cast_Scalar_F32_From_I32) {
-    auto* cast = Construct<f32>(1_i);
+    auto* cast = Call<f32>(1_i);
     WrapInFunction(cast);
 
     GeneratorImpl& gen = Build();
@@ -35,7 +35,7 @@
 TEST_F(WgslGeneratorImplTest, EmitExpression_Cast_Scalar_F16_From_I32) {
     Enable(ast::Extension::kF16);
 
-    auto* cast = Construct<f16>(1_i);
+    auto* cast = Call<f16>(1_i);
     WrapInFunction(cast);
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/wgsl/generator_impl_initializer_test.cc b/src/tint/writer/wgsl/generator_impl_initializer_test.cc
index 578da4d..9bc62c1 100644
--- a/src/tint/writer/wgsl/generator_impl_initializer_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_initializer_test.cc
@@ -74,7 +74,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitInitializer_Type_F32) {
-    WrapInFunction(Construct<f32>(Expr(-1.2e-5_f)));
+    WrapInFunction(Call<f32>(Expr(-1.2e-5_f)));
 
     GeneratorImpl& gen = Build();
 
@@ -85,7 +85,7 @@
 TEST_F(WgslGeneratorImplTest, EmitInitializer_Type_F16) {
     Enable(ast::Extension::kF16);
 
-    WrapInFunction(Construct<f16>(Expr(-1.2e-5_h)));
+    WrapInFunction(Call<f16>(Expr(-1.2e-5_h)));
 
     GeneratorImpl& gen = Build();
 
@@ -94,7 +94,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitInitializer_Type_Bool) {
-    WrapInFunction(Construct<bool>(true));
+    WrapInFunction(Call<bool>(true));
 
     GeneratorImpl& gen = Build();
 
@@ -103,7 +103,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitInitializer_Type_Int) {
-    WrapInFunction(Construct<i32>(-12345_i));
+    WrapInFunction(Call<i32>(-12345_i));
 
     GeneratorImpl& gen = Build();
 
@@ -112,7 +112,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitInitializer_Type_Uint) {
-    WrapInFunction(Construct<u32>(12345_u));
+    WrapInFunction(Call<u32>(12345_u));
 
     GeneratorImpl& gen = Build();
 
@@ -163,8 +163,8 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitInitializer_Type_Array) {
-    WrapInFunction(Construct(ty.array(ty.vec3<f32>(), 3_u), vec3<f32>(1_f, 2_f, 3_f),
-                             vec3<f32>(4_f, 5_f, 6_f), vec3<f32>(7_f, 8_f, 9_f)));
+    WrapInFunction(Call(ty.array(ty.vec3<f32>(), 3_u), vec3<f32>(1_f, 2_f, 3_f),
+                        vec3<f32>(4_f, 5_f, 6_f), vec3<f32>(7_f, 8_f, 9_f)));
 
     GeneratorImpl& gen = Build();
 
@@ -175,8 +175,8 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitInitializer_Type_ImplicitArray) {
-    WrapInFunction(Construct(ty.array(nullptr, nullptr), vec3<f32>(1_f, 2_f, 3_f),
-                             vec3<f32>(4_f, 5_f, 6_f), vec3<f32>(7_f, 8_f, 9_f)));
+    WrapInFunction(Call(ty.array(nullptr, nullptr), vec3<f32>(1_f, 2_f, 3_f),
+                        vec3<f32>(4_f, 5_f, 6_f), vec3<f32>(7_f, 8_f, 9_f)));
 
     GeneratorImpl& gen = Build();
 
diff --git a/src/tint/writer/wgsl/generator_impl_variable_decl_statement_test.cc b/src/tint/writer/wgsl/generator_impl_variable_decl_statement_test.cc
index 38c98e9..51b8683 100644
--- a/src/tint/writer/wgsl/generator_impl_variable_decl_statement_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_variable_decl_statement_test.cc
@@ -169,7 +169,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_vec3_AInt) {
-    auto* C = Const("C", Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
+    auto* C = Const("C", Call(ty.vec3(nullptr), 1_a, 2_a, 3_a));
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(C),
@@ -188,7 +188,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_vec3_AFloat) {
-    auto* C = Const("C", Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
+    auto* C = Const("C", Call(ty.vec3(nullptr), 1._a, 2._a, 3._a));
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(C),
@@ -249,7 +249,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_mat2x3_AFloat) {
-    auto* C = Const("C", Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
+    auto* C = Const("C", Call(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(C),
@@ -310,7 +310,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_arr_f32) {
-    auto* C = Const("C", Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
+    auto* C = Const("C", Call(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(C),
@@ -329,10 +329,10 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_arr_vec2_bool) {
-    auto* C = Const("C", Construct(ty.array(ty.vec2<bool>(), 3_u),  //
-                                   vec2<bool>(true, false),         //
-                                   vec2<bool>(false, true),         //
-                                   vec2<bool>(true, true)));
+    auto* C = Const("C", Call(ty.array(ty.vec2<bool>(), 3_u),  //
+                              vec2<bool>(true, false),         //
+                              vec2<bool>(false, true),         //
+                              vec2<bool>(true, true)));
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(C),