[tint][resolver] Rename builder_ to b and make a reference

This matches the naming convention used throughout Tint, and
substantially removes the number of wrapped lines in the file(s).

Change-Id: I3df7d807d6bb5e104e539c6e5450d7762e13339f
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/154504
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Kokoro: Ben Clayton <bclayton@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/lang/wgsl/resolver/resolver.cc b/src/tint/lang/wgsl/resolver/resolver.cc
index 41849b9..a1624f2 100644
--- a/src/tint/lang/wgsl/resolver/resolver.cc
+++ b/src/tint/lang/wgsl/resolver/resolver.cc
@@ -115,7 +115,7 @@
 }  // namespace
 
 Resolver::Resolver(ProgramBuilder* builder)
-    : builder_(builder),
+    : b(*builder),
       diagnostics_(builder->Diagnostics()),
       const_eval_(builder->constants, diagnostics_),
       intrinsic_table_{builder->Types(), builder->Symbols(), builder->Diagnostics()},
@@ -133,12 +133,12 @@
         return false;
     }
 
-    builder_->Sem().Reserve(builder_->LastAllocatedNodeID());
+    b.Sem().Reserve(b.LastAllocatedNodeID());
 
     // Pre-allocate the marked bitset with the total number of AST nodes.
-    marked_.Resize(builder_->ASTNodes().Count());
+    marked_.Resize(b.ASTNodes().Count());
 
-    if (!DependencyGraph::Build(builder_->AST(), diagnostics_, dependencies_)) {
+    if (!DependencyGraph::Build(b.AST(), diagnostics_, dependencies_)) {
         return false;
     }
 
@@ -150,15 +150,15 @@
     }
 
     // Create the semantic module. Don't be tempted to std::move() these, they're used below.
-    auto* mod = builder_->create<sem::Module>(dependencies_.ordered_globals, enabled_extensions_);
+    auto* mod = b.create<sem::Module>(dependencies_.ordered_globals, enabled_extensions_);
     ApplyDiagnosticSeverities(mod);
-    builder_->Sem().SetModule(mod);
+    b.Sem().SetModule(mod);
 
     const bool disable_uniformity_analysis =
         enabled_extensions_.Contains(wgsl::Extension::kChromiumDisableUniformityAnalysis);
     if (result && !disable_uniformity_analysis) {
         // Run the uniformity analysis, which requires a complete semantic module.
-        if (!AnalyzeUniformity(builder_, dependencies_)) {
+        if (!AnalyzeUniformity(b, dependencies_)) {
             return false;
         }
     }
@@ -167,7 +167,7 @@
 }
 
 bool Resolver::ResolveInternal() {
-    Mark(&builder_->AST());
+    Mark(&b.AST());
 
     // Process all module-scope declarations in dependency order.
     Vector<const ast::DiagnosticControl*, 4> diagnostic_controls;
@@ -211,7 +211,7 @@
     }
 
     bool result = true;
-    for (auto* node : builder_->ASTNodes().Objects()) {
+    for (auto* node : b.ASTNodes().Objects()) {
         if (TINT_UNLIKELY(!marked_[node->node_id.value])) {
             StringStream err;
             err << "AST node '" << node->TypeInfo().name << "' was not reached by the resolver\n"
@@ -294,19 +294,19 @@
 
     sem::Variable* sem = nullptr;
     if (is_global) {
-        sem = builder_->create<sem::GlobalVariable>(
-            v, ty, core::EvaluationStage::kRuntime, core::AddressSpace::kUndefined,
-            core::Access::kUndefined,
-            /* constant_value */ nullptr, std::nullopt, std::nullopt);
+        sem =
+            b.create<sem::GlobalVariable>(v, ty, core::EvaluationStage::kRuntime,
+                                          core::AddressSpace::kUndefined, core::Access::kUndefined,
+                                          /* constant_value */ nullptr, std::nullopt, std::nullopt);
     } else {
-        sem = builder_->create<sem::LocalVariable>(v, ty, core::EvaluationStage::kRuntime,
-                                                   core::AddressSpace::kUndefined,
-                                                   core::Access::kUndefined, current_statement_,
-                                                   /* constant_value */ nullptr);
+        sem = b.create<sem::LocalVariable>(v, ty, core::EvaluationStage::kRuntime,
+                                           core::AddressSpace::kUndefined, core::Access::kUndefined,
+                                           current_statement_,
+                                           /* constant_value */ nullptr);
     }
 
     sem->SetInitializer(rhs);
-    builder_->Sem().Add(v, sem);
+    b.Sem().Add(v, sem);
     return sem;
 }
 
@@ -355,10 +355,10 @@
         return nullptr;
     }
 
-    auto* sem = builder_->create<sem::GlobalVariable>(
-        v, ty, core::EvaluationStage::kOverride, core::AddressSpace::kUndefined,
-        core::Access::kUndefined,
-        /* constant_value */ nullptr, std::nullopt, std::nullopt);
+    auto* sem =
+        b.create<sem::GlobalVariable>(v, ty, core::EvaluationStage::kOverride,
+                                      core::AddressSpace::kUndefined, core::Access::kUndefined,
+                                      /* constant_value */ nullptr, std::nullopt, std::nullopt);
     sem->SetInitializer(rhs);
 
     for (auto* attribute : v->attributes) {
@@ -408,7 +408,7 @@
         }
     }
 
-    builder_->Sem().Add(v, sem);
+    b.Sem().Add(v, sem);
     return sem;
 }
 
@@ -476,15 +476,15 @@
 
     const auto value = rhs->ConstantValue();
     auto* sem = is_global
-                    ? static_cast<sem::Variable*>(builder_->create<sem::GlobalVariable>(
+                    ? static_cast<sem::Variable*>(b.create<sem::GlobalVariable>(
                           c, ty, core::EvaluationStage::kConstant, core::AddressSpace::kUndefined,
                           core::Access::kUndefined, value, std::nullopt, std::nullopt))
-                    : static_cast<sem::Variable*>(builder_->create<sem::LocalVariable>(
+                    : static_cast<sem::Variable*>(b.create<sem::LocalVariable>(
                           c, ty, core::EvaluationStage::kConstant, core::AddressSpace::kUndefined,
                           core::Access::kUndefined, current_statement_, value));
 
     sem->SetInitializer(rhs);
-    builder_->Sem().Add(c, sem);
+    b.Sem().Add(c, sem);
     return sem;
 }
 
@@ -566,7 +566,7 @@
         return nullptr;
     }
 
-    auto* var_ty = builder_->create<core::type::Reference>(address_space, storage_ty, access);
+    auto* var_ty = b.create<core::type::Reference>(address_space, storage_ty, access);
 
     if (!ApplyAddressSpaceUsageToType(address_space, var_ty,
                                       var->type ? var->type->source : var->source)) {
@@ -661,7 +661,7 @@
         if (group && binding) {
             binding_point = BindingPoint{group.value(), binding.value()};
         }
-        sem = builder_->create<sem::GlobalVariable>(
+        sem = b.create<sem::GlobalVariable>(
             var, var_ty, core::EvaluationStage::kRuntime, address_space, access,
             /* constant_value */ nullptr, binding_point, location, index);
 
@@ -679,13 +679,13 @@
                 return nullptr;
             }
         }
-        sem = builder_->create<sem::LocalVariable>(var, var_ty, core::EvaluationStage::kRuntime,
-                                                   address_space, access, current_statement_,
-                                                   /* constant_value */ nullptr);
+        sem = b.create<sem::LocalVariable>(var, var_ty, core::EvaluationStage::kRuntime,
+                                           address_space, access, current_statement_,
+                                           /* constant_value */ nullptr);
     }
 
     sem->SetInitializer(rhs);
-    builder_->Sem().Add(var, sem);
+    b.Sem().Add(var, sem);
     return sem;
 }
 
@@ -806,10 +806,10 @@
         binding_point = BindingPoint{group.value(), binding.value()};
     }
 
-    auto* sem = builder_->create<sem::Parameter>(
-        param, index, ty, core::AddressSpace::kUndefined, core::Access::kUndefined,
-        core::ParameterUsage::kNone, binding_point, location);
-    builder_->Sem().Add(param, sem);
+    auto* sem = b.create<sem::Parameter>(param, index, ty, core::AddressSpace::kUndefined,
+                                         core::Access::kUndefined, core::ParameterUsage::kNone,
+                                         binding_point, location);
+    b.Sem().Add(param, sem);
 
     if (!validator_.Parameter(sem)) {
         return nullptr;
@@ -849,7 +849,7 @@
     // deterministic.
     // TODO(crbug.com/tint/1192): If a transform changes the order or removes an
     // unused constant, the allocation may change on the next Resolver pass.
-    for (auto* decl : builder_->AST().GlobalDeclarations()) {
+    for (auto* decl : b.AST().GlobalDeclarations()) {
         auto* override = decl->As<ast::Override>();
         if (!override) {
             continue;
@@ -882,8 +882,8 @@
 
 void Resolver::SetShadows() {
     for (auto it : dependencies_.shadows) {
-        CastableBase* b = sem_.Get(it.value);
-        if (TINT_UNLIKELY(!b)) {
+        CastableBase* shadowed = sem_.Get(it.value);
+        if (TINT_UNLIKELY(!shadowed)) {
             StringStream err;
             err << "AST node '" << it.value->TypeInfo().name << "' had no semantic info\n"
                 << "Pointer: " << it.value;
@@ -892,8 +892,8 @@
 
         Switch(
             sem_.Get(it.key),  //
-            [&](sem::LocalVariable* local) { local->SetShadows(b); },
-            [&](sem::Parameter* param) { param->SetShadows(b); });
+            [&](sem::LocalVariable* local) { local->SetShadows(shadowed); },
+            [&](sem::Parameter* param) { param->SetShadows(shadowed); });
     }
 }
 
@@ -917,13 +917,13 @@
     // Track the pipeline-overridable constants that are transitively referenced by this
     // variable.
     for (auto* var : transitively_referenced_overrides) {
-        builder_->Sem().AddTransitivelyReferencedOverride(sem, var);
+        b.Sem().AddTransitivelyReferencedOverride(sem, var);
     }
     if (auto* arr = sem->Type()->UnwrapRef()->As<core::type::Array>()) {
-        auto* refs = builder_->Sem().TransitivelyReferencedOverrides(arr);
+        auto* refs = b.Sem().TransitivelyReferencedOverrides(arr);
         if (refs) {
             for (auto* var : *refs) {
-                builder_->Sem().AddTransitivelyReferencedOverride(sem, var);
+                b.Sem().AddTransitivelyReferencedOverride(sem, var);
             }
         }
     }
@@ -948,17 +948,16 @@
         AddError("const assertion failed", assertion->source);
         return nullptr;
     }
-    auto* sem =
-        builder_->create<sem::Statement>(assertion, current_compound_statement_, current_function_);
-    builder_->Sem().Add(assertion, sem);
+    auto* sem = b.create<sem::Statement>(assertion, current_compound_statement_, current_function_);
+    b.Sem().Add(assertion, sem);
     return sem;
 }
 
 sem::Function* Resolver::Function(const ast::Function* decl) {
     Mark(decl->name);
 
-    auto* func = builder_->create<sem::Function>(decl);
-    builder_->Sem().Add(decl, func);
+    auto* func = b.create<sem::Function>(decl);
+    b.Sem().Add(decl, func);
     TINT_SCOPED_ASSIGNMENT(current_function_, func);
 
     validator_.DiagnosticFilters().Push();
@@ -1040,7 +1039,7 @@
             return nullptr;
         }
     } else {
-        return_type = builder_->create<core::type::Void>();
+        return_type = b.create<core::type::Void>();
     }
     func->SetReturnType(return_type);
 
@@ -1158,7 +1157,7 @@
             AddICE(err.str(), decl->body->source);
             return nullptr;
         }
-        auto* body = StatementScope(decl->body, builder_->create<sem::FunctionBlockStatement>(func),
+        auto* body = StatementScope(decl->body, b.create<sem::FunctionBlockStatement>(func),
                                     [&] { return Statements(decl->body->statements); });
         if (!body) {
             return nullptr;
@@ -1227,25 +1226,25 @@
         stmt,
         // Compound statements. These create their own sem::CompoundStatement
         // bindings.
-        [&](const ast::BlockStatement* b) { return BlockStatement(b); },
-        [&](const ast::ForLoopStatement* l) { return ForLoopStatement(l); },
-        [&](const ast::LoopStatement* l) { return LoopStatement(l); },
-        [&](const ast::WhileStatement* w) { return WhileStatement(w); },
-        [&](const ast::IfStatement* i) { return IfStatement(i); },
+        [&](const ast::BlockStatement* s) { return BlockStatement(s); },
+        [&](const ast::ForLoopStatement* s) { return ForLoopStatement(s); },
+        [&](const ast::LoopStatement* s) { return LoopStatement(s); },
+        [&](const ast::WhileStatement* s) { return WhileStatement(s); },
+        [&](const ast::IfStatement* s) { return IfStatement(s); },
         [&](const ast::SwitchStatement* s) { return SwitchStatement(s); },
 
         // Non-Compound statements
-        [&](const ast::AssignmentStatement* a) { return AssignmentStatement(a); },
-        [&](const ast::BreakStatement* b) { return BreakStatement(b); },
-        [&](const ast::BreakIfStatement* b) { return BreakIfStatement(b); },
-        [&](const ast::CallStatement* c) { return CallStatement(c); },
-        [&](const ast::CompoundAssignmentStatement* c) { return CompoundAssignmentStatement(c); },
-        [&](const ast::ContinueStatement* c) { return ContinueStatement(c); },
-        [&](const ast::DiscardStatement* d) { return DiscardStatement(d); },
-        [&](const ast::IncrementDecrementStatement* i) { return IncrementDecrementStatement(i); },
-        [&](const ast::ReturnStatement* r) { return ReturnStatement(r); },
-        [&](const ast::VariableDeclStatement* v) { return VariableDeclStatement(v); },
-        [&](const ast::ConstAssert* sa) { return ConstAssert(sa); },
+        [&](const ast::AssignmentStatement* s) { return AssignmentStatement(s); },
+        [&](const ast::BreakStatement* s) { return BreakStatement(s); },
+        [&](const ast::BreakIfStatement* s) { return BreakIfStatement(s); },
+        [&](const ast::CallStatement* s) { return CallStatement(s); },
+        [&](const ast::CompoundAssignmentStatement* s) { return CompoundAssignmentStatement(s); },
+        [&](const ast::ContinueStatement* s) { return ContinueStatement(s); },
+        [&](const ast::DiscardStatement* s) { return DiscardStatement(s); },
+        [&](const ast::IncrementDecrementStatement* s) { return IncrementDecrementStatement(s); },
+        [&](const ast::ReturnStatement* s) { return ReturnStatement(s); },
+        [&](const ast::VariableDeclStatement* s) { return VariableDeclStatement(s); },
+        [&](const ast::ConstAssert* s) { return ConstAssert(s); },
 
         // Error cases
         [&](const ast::CaseStatement*) {
@@ -1260,8 +1259,7 @@
 
 sem::CaseStatement* Resolver::CaseStatement(const ast::CaseStatement* stmt,
                                             const core::type::Type* ty) {
-    auto* sem =
-        builder_->create<sem::CaseStatement>(stmt, current_compound_statement_, current_function_);
+    auto* sem = b.create<sem::CaseStatement>(stmt, current_compound_statement_, current_function_);
     return StatementScope(stmt, sem, [&] {
         sem->Selectors().reserve(stmt->selectors.Length());
         for (auto* sel : stmt->selectors) {
@@ -1289,7 +1287,7 @@
                 }
             }
 
-            sem->Selectors().emplace_back(builder_->create<sem::CaseSelector>(sel, const_value));
+            sem->Selectors().emplace_back(b.create<sem::CaseSelector>(sel, const_value));
         }
 
         Mark(stmt->body);
@@ -1304,8 +1302,7 @@
 }
 
 sem::IfStatement* Resolver::IfStatement(const ast::IfStatement* stmt) {
-    auto* sem =
-        builder_->create<sem::IfStatement>(stmt, current_compound_statement_, current_function_);
+    auto* sem = b.create<sem::IfStatement>(stmt, current_compound_statement_, current_function_);
     return StatementScope(stmt, sem, [&] {
         auto* cond = Load(ValueExpression(stmt->condition));
         if (!cond) {
@@ -1316,8 +1313,8 @@
         sem->Behaviors().Remove(sem::Behavior::kNext);
 
         Mark(stmt->body);
-        auto* body = builder_->create<sem::BlockStatement>(stmt->body, current_compound_statement_,
-                                                           current_function_);
+        auto* body = b.create<sem::BlockStatement>(stmt->body, current_compound_statement_,
+                                                   current_function_);
         if (!StatementScope(stmt->body, body, [&] { return Statements(stmt->body->statements); })) {
             return false;
         }
@@ -1342,19 +1339,18 @@
 }
 
 sem::BlockStatement* Resolver::BlockStatement(const ast::BlockStatement* stmt) {
-    auto* sem = builder_->create<sem::BlockStatement>(
-        stmt->As<ast::BlockStatement>(), current_compound_statement_, current_function_);
+    auto* sem = b.create<sem::BlockStatement>(stmt->As<ast::BlockStatement>(),
+                                              current_compound_statement_, current_function_);
     return StatementScope(stmt, sem, [&] { return Statements(stmt->statements); });
 }
 
 sem::LoopStatement* Resolver::LoopStatement(const ast::LoopStatement* stmt) {
-    auto* sem =
-        builder_->create<sem::LoopStatement>(stmt, current_compound_statement_, current_function_);
+    auto* sem = b.create<sem::LoopStatement>(stmt, current_compound_statement_, current_function_);
     return StatementScope(stmt, sem, [&] {
         Mark(stmt->body);
 
-        auto* body = builder_->create<sem::LoopBlockStatement>(
-            stmt->body, current_compound_statement_, current_function_);
+        auto* body = b.create<sem::LoopBlockStatement>(stmt->body, current_compound_statement_,
+                                                       current_function_);
         return StatementScope(stmt->body, body, [&] {
             if (!Statements(stmt->body->statements)) {
                 return false;
@@ -1366,7 +1362,7 @@
                 Mark(stmt->continuing);
                 auto* continuing = StatementScope(
                     stmt->continuing,
-                    builder_->create<sem::LoopContinuingBlockStatement>(
+                    b.create<sem::LoopContinuingBlockStatement>(
                         stmt->continuing, current_compound_statement_, current_function_),
                     [&] { return Statements(stmt->continuing->statements); });
                 if (!continuing) {
@@ -1388,8 +1384,8 @@
 }
 
 sem::ForLoopStatement* Resolver::ForLoopStatement(const ast::ForLoopStatement* stmt) {
-    auto* sem = builder_->create<sem::ForLoopStatement>(stmt, current_compound_statement_,
-                                                        current_function_);
+    auto* sem =
+        b.create<sem::ForLoopStatement>(stmt, current_compound_statement_, current_function_);
     return StatementScope(stmt, sem, [&] {
         auto& behaviors = sem->Behaviors();
         if (auto* initializer = stmt->initializer) {
@@ -1421,8 +1417,8 @@
 
         Mark(stmt->body);
 
-        auto* body = builder_->create<sem::LoopBlockStatement>(
-            stmt->body, current_compound_statement_, current_function_);
+        auto* body = b.create<sem::LoopBlockStatement>(stmt->body, current_compound_statement_,
+                                                       current_function_);
         if (!StatementScope(stmt->body, body, [&] { return Statements(stmt->body->statements); })) {
             return false;
         }
@@ -1440,8 +1436,7 @@
 }
 
 sem::WhileStatement* Resolver::WhileStatement(const ast::WhileStatement* stmt) {
-    auto* sem =
-        builder_->create<sem::WhileStatement>(stmt, current_compound_statement_, current_function_);
+    auto* sem = b.create<sem::WhileStatement>(stmt, current_compound_statement_, current_function_);
     return StatementScope(stmt, sem, [&] {
         auto& behaviors = sem->Behaviors();
 
@@ -1454,8 +1449,8 @@
 
         Mark(stmt->body);
 
-        auto* body = builder_->create<sem::LoopBlockStatement>(
-            stmt->body, current_compound_statement_, current_function_);
+        auto* body = b.create<sem::LoopBlockStatement>(stmt->body, current_compound_statement_,
+                                                       current_function_);
         if (!StatementScope(stmt->body, body, [&] { return Statements(stmt->body->statements); })) {
             return false;
         }
@@ -1517,11 +1512,11 @@
             [&](const ast::MemberAccessorExpression* member) { return MemberAccessor(member); },
             [&](const ast::UnaryOpExpression* unary) { return UnaryOp(unary); },
             [&](const ast::PhonyExpression*) {
-                return builder_->create<sem::ValueExpression>(
-                    expr, builder_->create<core::type::Void>(), core::EvaluationStage::kRuntime,
-                    current_statement_,
-                    /* constant_value */ nullptr,
-                    /* has_side_effects */ false);
+                return b.create<sem::ValueExpression>(expr, b.create<core::type::Void>(),
+                                                      core::EvaluationStage::kRuntime,
+                                                      current_statement_,
+                                                      /* constant_value */ nullptr,
+                                                      /* has_side_effects */ false);
             },
             [&](Default) {
                 StringStream err;
@@ -1544,7 +1539,7 @@
             }
         }
 
-        builder_->Sem().Add(expr, sem_expr);
+        b.Sem().Add(expr, sem_expr);
         if (expr == root) {
             return sem_expr;
         }
@@ -1768,12 +1763,12 @@
 const core::type::Type* Resolver::ConcreteType(const core::type::Type* ty,
                                                const core::type::Type* target_ty,
                                                const Source& source) {
-    auto i32 = [&] { return builder_->create<core::type::I32>(); };
-    auto f32 = [&] { return builder_->create<core::type::F32>(); };
-    auto i32v = [&](uint32_t width) { return builder_->create<core::type::Vector>(i32(), width); };
-    auto f32v = [&](uint32_t width) { return builder_->create<core::type::Vector>(f32(), width); };
+    auto i32 = [&] { return b.create<core::type::I32>(); };
+    auto f32 = [&] { return b.create<core::type::F32>(); };
+    auto i32v = [&](uint32_t width) { return b.create<core::type::Vector>(i32(), width); };
+    auto f32v = [&](uint32_t width) { return b.create<core::type::Vector>(f32(), width); };
     auto f32m = [&](uint32_t columns, uint32_t rows) {
-        return builder_->create<core::type::Matrix>(f32v(rows), columns);
+        return b.create<core::type::Matrix>(f32v(rows), columns);
     };
 
     return Switch(
@@ -1825,9 +1820,9 @@
         return expr;
     }
 
-    auto* load = builder_->create<sem::Load>(expr, current_statement_);
+    auto* load = b.create<sem::Load>(expr, current_statement_);
     load->Behaviors() = expr->Behaviors();
-    builder_->Sem().Replace(expr->Declaration(), load);
+    b.Sem().Replace(expr->Declaration(), load);
 
     // Track the load for the alias analysis.
     auto& alias_info = alias_analysis_infos_[current_function_];
@@ -1887,10 +1882,9 @@
         }
     }
 
-    auto* m =
-        builder_->create<sem::Materialize>(expr, current_statement_, concrete_ty, materialized_val);
+    auto* m = b.create<sem::Materialize>(expr, current_statement_, concrete_ty, materialized_val);
     m->Behaviors() = expr->Behaviors();
-    builder_->Sem().Replace(decl, m);
+    b.Sem().Replace(decl, m);
     return m;
 }
 
@@ -1969,7 +1963,7 @@
         [&](const core::type::Array* arr) { return arr->ElemType(); },
         [&](const core::type::Vector* vec) { return vec->type(); },
         [&](const core::type::Matrix* mat) {
-            return builder_->create<core::type::Vector>(mat->type(), mat->rows());
+            return b.create<core::type::Vector>(mat->type(), mat->rows());
         },
         [&](Default) {
             AddError("cannot index type '" + sem_.TypeNameOf(obj_ty) + "'", expr->source);
@@ -1988,7 +1982,7 @@
 
     // If we're extracting from a reference, we return a reference.
     if (auto* ref = obj_raw_ty->As<core::type::Reference>()) {
-        ty = builder_->create<core::type::Reference>(ref->AddressSpace(), ty, ref->Access());
+        ty = b.create<core::type::Reference>(ref->AddressSpace(), ty, ref->Access());
     }
 
     const core::constant::Value* val = nullptr;
@@ -2006,9 +2000,9 @@
         }
     }
     bool has_side_effects = idx->HasSideEffects() || obj->HasSideEffects();
-    auto* sem = builder_->create<sem::IndexAccessorExpression>(
-        expr, ty, stage, obj, idx, current_statement_, std::move(val), has_side_effects,
-        obj->RootIdentifier());
+    auto* sem = b.create<sem::IndexAccessorExpression>(expr, ty, stage, obj, idx,
+                                                       current_statement_, std::move(val),
+                                                       has_side_effects, obj->RootIdentifier());
     sem->Behaviors() = idx->Behaviors() + obj->Behaviors();
     return sem;
 }
@@ -2040,8 +2034,8 @@
         }
     }
 
-    auto* sem = builder_->create<sem::ValueExpression>(expr, ty, stage, current_statement_,
-                                                       std::move(value), inner->HasSideEffects());
+    auto* sem = b.create<sem::ValueExpression>(expr, ty, stage, current_statement_,
+                                               std::move(value), inner->HasSideEffects());
     sem->Behaviors() = inner->Behaviors();
     return sem;
 }
@@ -2097,22 +2091,21 @@
         if (match->info->flags.Contains(OverloadFlag::kIsConstructor)) {
             // Type constructor
             auto params = Transform(match->parameters, [&](auto& p, size_t i) {
-                return builder_->create<sem::Parameter>(nullptr, static_cast<uint32_t>(i), p.type,
-                                                        core::AddressSpace::kUndefined,
-                                                        core::Access::kUndefined, p.usage);
+                return b.create<sem::Parameter>(nullptr, static_cast<uint32_t>(i), p.type,
+                                                core::AddressSpace::kUndefined,
+                                                core::Access::kUndefined, p.usage);
             });
             target_sem = constructors_.GetOrCreate(match.Get(), [&] {
-                return builder_->create<sem::ValueConstructor>(match->return_type,
-                                                               std::move(params), overload_stage);
+                return b.create<sem::ValueConstructor>(match->return_type, std::move(params),
+                                                       overload_stage);
             });
         } else {
             // Type conversion
             target_sem = converters_.GetOrCreate(match.Get(), [&] {
-                auto param = builder_->create<sem::Parameter>(
+                auto param = b.create<sem::Parameter>(
                     nullptr, 0u, match->parameters[0].type, core::AddressSpace::kUndefined,
                     core::Access::kUndefined, match->parameters[0].usage);
-                return builder_->create<sem::ValueConversion>(match->return_type, param,
-                                                              overload_stage);
+                return b.create<sem::ValueConversion>(match->return_type, param, overload_stage);
             });
         }
 
@@ -2138,8 +2131,8 @@
                 return nullptr;
             }
         }
-        return builder_->create<sem::Call>(expr, target_sem, stage, std::move(args),
-                                           current_statement_, value, has_side_effects);
+        return b.create<sem::Call>(expr, target_sem, stage, std::move(args), current_statement_,
+                                   value, has_side_effects);
     };
 
     // arr_or_str_init is a helper for building a sem::ValueConstructor for an array or structure
@@ -2172,8 +2165,8 @@
             }
         }
 
-        return builder_->create<sem::Call>(expr, call_target, stage, std::move(args),
-                                           current_statement_, value, has_side_effects);
+        return b.create<sem::Call>(expr, call_target, stage, std::move(args), current_statement_,
+                                   value, has_side_effects);
     };
 
     auto ty_init_or_conv = [&](const core::type::Type* type) {
@@ -2206,15 +2199,14 @@
                     ArrayConstructorSig{{arr, args.Length(), args_stage}},
                     [&]() -> sem::ValueConstructor* {
                         auto params = tint::Transform(args, [&](auto, size_t i) {
-                            return builder_->create<sem::Parameter>(
+                            return b.create<sem::Parameter>(
                                 nullptr,                         // declaration
                                 static_cast<uint32_t>(i),        // index
                                 arr->ElemType(),                 // type
                                 core::AddressSpace::kUndefined,  // address_space
                                 core::Access::kUndefined);
                         });
-                        return builder_->create<sem::ValueConstructor>(arr, std::move(params),
-                                                                       args_stage);
+                        return b.create<sem::ValueConstructor>(arr, std::move(params), args_stage);
                     });
 
                 auto* call = arr_or_str_init(arr, call_target);
@@ -2235,15 +2227,14 @@
                         Vector<sem::Parameter*, 8> params;
                         params.Resize(std::min(args.Length(), str->Members().Length()));
                         for (size_t i = 0, n = params.Length(); i < n; i++) {
-                            params[i] = builder_->create<sem::Parameter>(
+                            params[i] = b.create<sem::Parameter>(
                                 nullptr,                         // declaration
                                 static_cast<uint32_t>(i),        // index
                                 str->Members()[i]->Type(),       // type
                                 core::AddressSpace::kUndefined,  // address_space
                                 core::Access::kUndefined);       // access
                         }
-                        return builder_->create<sem::ValueConstructor>(str, std::move(params),
-                                                                       args_stage);
+                        return b.create<sem::ValueConstructor>(str, std::move(params), args_stage);
                     });
 
                 auto* call = arr_or_str_init(str, call_target);
@@ -2265,7 +2256,7 @@
 
     auto inferred_array = [&]() -> tint::sem::Call* {
         auto el_count =
-            builder_->create<core::type::ConstantArrayCount>(static_cast<uint32_t>(args.Length()));
+            b.create<core::type::ConstantArrayCount>(static_cast<uint32_t>(args.Length()));
         auto arg_tys = tint::Transform(args, [](auto* arg) { return arg->Type()->UnwrapRef(); });
         auto el_ty = core::type::Type::Common(arg_tys);
         if (!el_ty) {
@@ -2331,11 +2322,11 @@
             return BuiltinCall(expr, f, args);
         }
 
-        if (auto b = resolved->BuiltinType(); b != core::BuiltinType::kUndefined) {
+        if (auto bt = resolved->BuiltinType(); bt != core::BuiltinType::kUndefined) {
             if (!ident->Is<ast::TemplatedIdentifier>()) {
                 // No template arguments provided.
                 // Check to see if this is an inferred-element-type call.
-                switch (b) {
+                switch (bt) {
                     case core::BuiltinType::kArray:
                         return inferred_array();
                     case core::BuiltinType::kVec2:
@@ -2366,7 +2357,7 @@
                         break;
                 }
             }
-            auto* ty = BuiltinType(b, ident);
+            auto* ty = BuiltinType(bt, ident);
             if (TINT_UNLIKELY(!ty)) {
                 return nullptr;
             }
@@ -2389,9 +2380,8 @@
     if (call->Target()->IsAnyOf<sem::ValueConstructor, sem::ValueConversion>()) {
         // The target of the call was a type.
         // Associate the target identifier expression with the resolved type.
-        auto* ty_expr =
-            builder_->create<sem::TypeExpression>(target, current_statement_, call->Type());
-        builder_->Sem().Add(target, ty_expr);
+        auto* ty_expr = b.create<sem::TypeExpression>(target, current_statement_, call->Type());
+        b.Sem().Add(target, ty_expr);
     }
 
     return validator_.Call(call, current_statement_) ? call : nullptr;
@@ -2415,9 +2405,9 @@
     // De-duplicate builtins that are identical.
     auto* target = builtins_.GetOrCreate(std::make_pair(overload.Get(), fn), [&] {
         auto params = Transform(overload->parameters, [&](auto& p, size_t i) {
-            return builder_->create<sem::Parameter>(nullptr, static_cast<uint32_t>(i), p.type,
-                                                    core::AddressSpace::kUndefined,
-                                                    core::Access::kUndefined, p.usage);
+            return b.create<sem::Parameter>(nullptr, static_cast<uint32_t>(i), p.type,
+                                            core::AddressSpace::kUndefined,
+                                            core::Access::kUndefined, p.usage);
         });
         sem::PipelineStageSet supported_stages;
         auto flags = overload->info->flags;
@@ -2432,7 +2422,7 @@
         }
         auto eval_stage = overload->const_eval_fn ? core::EvaluationStage::kConstant
                                                   : core::EvaluationStage::kRuntime;
-        return builder_->create<sem::BuiltinFn>(
+        return b.create<sem::BuiltinFn>(
             fn, overload->return_type, std::move(params), eval_stage, supported_stages,
             flags.Contains(OverloadFlag::kIsDeprecated), flags.Contains(OverloadFlag::kMustUse));
     });
@@ -2477,8 +2467,8 @@
     bool has_side_effects =
         target->HasSideEffects() ||
         std::any_of(args.begin(), args.end(), [](auto* e) { return e->HasSideEffects(); });
-    auto* call = builder_->create<sem::Call>(expr, target, stage, std::move(args),
-                                             current_statement_, value, has_side_effects);
+    auto* call = b.create<sem::Call>(expr, target, stage, std::move(args), current_statement_,
+                                     value, has_side_effects);
 
     if (current_function_) {
         current_function_->AddDirectlyCalledBuiltin(target);
@@ -2517,7 +2507,6 @@
 
 core::type::Type* Resolver::BuiltinType(core::BuiltinType builtin_ty,
                                         const ast::Identifier* ident) {
-    auto& b = *builder_;
     auto check_no_tmpl_args = [&](core::type::Type* ty) -> core::type::Type* {
         return TINT_LIKELY(CheckNotTemplated("type", ident)) ? ty : nullptr;
     };
@@ -2625,10 +2614,10 @@
             return Ptr(ident);
         case core::BuiltinType::kSampler:
             return check_no_tmpl_args(
-                builder_->create<core::type::Sampler>(core::type::SamplerKind::kSampler));
+                b.create<core::type::Sampler>(core::type::SamplerKind::kSampler));
         case core::BuiltinType::kSamplerComparison:
             return check_no_tmpl_args(
-                builder_->create<core::type::Sampler>(core::type::SamplerKind::kComparisonSampler));
+                b.create<core::type::Sampler>(core::type::SamplerKind::kComparisonSampler));
         case core::BuiltinType::kTexture1D:
             return SampledTexture(ident, core::type::TextureDimension::k1d);
         case core::BuiltinType::kTexture2D:
@@ -2643,21 +2632,21 @@
             return SampledTexture(ident, core::type::TextureDimension::kCubeArray);
         case core::BuiltinType::kTextureDepth2D:
             return check_no_tmpl_args(
-                builder_->create<core::type::DepthTexture>(core::type::TextureDimension::k2d));
+                b.create<core::type::DepthTexture>(core::type::TextureDimension::k2d));
         case core::BuiltinType::kTextureDepth2DArray:
             return check_no_tmpl_args(
-                builder_->create<core::type::DepthTexture>(core::type::TextureDimension::k2dArray));
+                b.create<core::type::DepthTexture>(core::type::TextureDimension::k2dArray));
         case core::BuiltinType::kTextureDepthCube:
             return check_no_tmpl_args(
-                builder_->create<core::type::DepthTexture>(core::type::TextureDimension::kCube));
+                b.create<core::type::DepthTexture>(core::type::TextureDimension::kCube));
         case core::BuiltinType::kTextureDepthCubeArray:
-            return check_no_tmpl_args(builder_->create<core::type::DepthTexture>(
-                core::type::TextureDimension::kCubeArray));
+            return check_no_tmpl_args(
+                b.create<core::type::DepthTexture>(core::type::TextureDimension::kCubeArray));
         case core::BuiltinType::kTextureDepthMultisampled2D:
-            return check_no_tmpl_args(builder_->create<core::type::DepthMultisampledTexture>(
-                core::type::TextureDimension::k2d));
+            return check_no_tmpl_args(
+                b.create<core::type::DepthMultisampledTexture>(core::type::TextureDimension::k2d));
         case core::BuiltinType::kTextureExternal:
-            return check_no_tmpl_args(builder_->create<core::type::ExternalTexture>());
+            return check_no_tmpl_args(b.create<core::type::ExternalTexture>());
         case core::BuiltinType::kTextureMultisampled2D:
             return MultisampledTexture(ident, core::type::TextureDimension::k2d);
         case core::BuiltinType::kTextureStorage1D:
@@ -2671,78 +2660,57 @@
         case core::BuiltinType::kPackedVec3:
             return PackedVec3T(ident);
         case core::BuiltinType::kAtomicCompareExchangeResultI32:
-            return core::type::CreateAtomicCompareExchangeResult(builder_->Types(),
-                                                                 builder_->Symbols(), I32());
+            return core::type::CreateAtomicCompareExchangeResult(b.Types(), b.Symbols(), I32());
         case core::BuiltinType::kAtomicCompareExchangeResultU32:
-            return core::type::CreateAtomicCompareExchangeResult(builder_->Types(),
-                                                                 builder_->Symbols(), U32());
+            return core::type::CreateAtomicCompareExchangeResult(b.Types(), b.Symbols(), U32());
         case core::BuiltinType::kFrexpResultAbstract:
-            return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(), AF());
+            return core::type::CreateFrexpResult(b.Types(), b.Symbols(), AF());
         case core::BuiltinType::kFrexpResultF16:
-            return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(),
-                                                 F16(ident));
+            return core::type::CreateFrexpResult(b.Types(), b.Symbols(), F16(ident));
         case core::BuiltinType::kFrexpResultF32:
-            return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(), F32());
+            return core::type::CreateFrexpResult(b.Types(), b.Symbols(), F32());
         case core::BuiltinType::kFrexpResultVec2Abstract:
-            return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(),
-                                                 Vec(ident, AF(), 2));
+            return core::type::CreateFrexpResult(b.Types(), b.Symbols(), Vec(ident, AF(), 2));
         case core::BuiltinType::kFrexpResultVec2F16:
-            return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(),
-                                                 Vec(ident, F16(ident), 2));
+            return core::type::CreateFrexpResult(b.Types(), b.Symbols(), Vec(ident, F16(ident), 2));
         case core::BuiltinType::kFrexpResultVec2F32:
-            return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(),
-                                                 Vec(ident, F32(), 2));
+            return core::type::CreateFrexpResult(b.Types(), b.Symbols(), Vec(ident, F32(), 2));
         case core::BuiltinType::kFrexpResultVec3Abstract:
-            return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(),
-                                                 Vec(ident, AF(), 3));
+            return core::type::CreateFrexpResult(b.Types(), b.Symbols(), Vec(ident, AF(), 3));
         case core::BuiltinType::kFrexpResultVec3F16:
-            return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(),
-                                                 Vec(ident, F16(ident), 3));
+            return core::type::CreateFrexpResult(b.Types(), b.Symbols(), Vec(ident, F16(ident), 3));
         case core::BuiltinType::kFrexpResultVec3F32:
-            return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(),
-                                                 Vec(ident, F32(), 3));
+            return core::type::CreateFrexpResult(b.Types(), b.Symbols(), Vec(ident, F32(), 3));
         case core::BuiltinType::kFrexpResultVec4Abstract:
-            return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(),
-                                                 Vec(ident, AF(), 4));
+            return core::type::CreateFrexpResult(b.Types(), b.Symbols(), Vec(ident, AF(), 4));
         case core::BuiltinType::kFrexpResultVec4F16:
-            return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(),
-                                                 Vec(ident, F16(ident), 4));
+            return core::type::CreateFrexpResult(b.Types(), b.Symbols(), Vec(ident, F16(ident), 4));
         case core::BuiltinType::kFrexpResultVec4F32:
-            return core::type::CreateFrexpResult(builder_->Types(), builder_->Symbols(),
-                                                 Vec(ident, F32(), 4));
+            return core::type::CreateFrexpResult(b.Types(), b.Symbols(), Vec(ident, F32(), 4));
         case core::BuiltinType::kModfResultAbstract:
-            return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(), AF());
+            return core::type::CreateModfResult(b.Types(), b.Symbols(), AF());
         case core::BuiltinType::kModfResultF16:
-            return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(), F16(ident));
+            return core::type::CreateModfResult(b.Types(), b.Symbols(), F16(ident));
         case core::BuiltinType::kModfResultF32:
-            return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(), F32());
+            return core::type::CreateModfResult(b.Types(), b.Symbols(), F32());
         case core::BuiltinType::kModfResultVec2Abstract:
-            return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(),
-                                                Vec(ident, AF(), 2));
+            return core::type::CreateModfResult(b.Types(), b.Symbols(), Vec(ident, AF(), 2));
         case core::BuiltinType::kModfResultVec2F16:
-            return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(),
-                                                Vec(ident, F16(ident), 2));
+            return core::type::CreateModfResult(b.Types(), b.Symbols(), Vec(ident, F16(ident), 2));
         case core::BuiltinType::kModfResultVec2F32:
-            return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(),
-                                                Vec(ident, F32(), 2));
+            return core::type::CreateModfResult(b.Types(), b.Symbols(), Vec(ident, F32(), 2));
         case core::BuiltinType::kModfResultVec3Abstract:
-            return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(),
-                                                Vec(ident, AF(), 3));
+            return core::type::CreateModfResult(b.Types(), b.Symbols(), Vec(ident, AF(), 3));
         case core::BuiltinType::kModfResultVec3F16:
-            return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(),
-                                                Vec(ident, F16(ident), 3));
+            return core::type::CreateModfResult(b.Types(), b.Symbols(), Vec(ident, F16(ident), 3));
         case core::BuiltinType::kModfResultVec3F32:
-            return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(),
-                                                Vec(ident, F32(), 3));
+            return core::type::CreateModfResult(b.Types(), b.Symbols(), Vec(ident, F32(), 3));
         case core::BuiltinType::kModfResultVec4Abstract:
-            return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(),
-                                                Vec(ident, AF(), 4));
+            return core::type::CreateModfResult(b.Types(), b.Symbols(), Vec(ident, AF(), 4));
         case core::BuiltinType::kModfResultVec4F16:
-            return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(),
-                                                Vec(ident, F16(ident), 4));
+            return core::type::CreateModfResult(b.Types(), b.Symbols(), Vec(ident, F16(ident), 4));
         case core::BuiltinType::kModfResultVec4F32:
-            return core::type::CreateModfResult(builder_->Types(), builder_->Symbols(),
-                                                Vec(ident, F32(), 4));
+            return core::type::CreateModfResult(b.Types(), b.Symbols(), Vec(ident, F32(), 4));
         case core::BuiltinType::kUndefined:
             break;
     }
@@ -2755,24 +2723,23 @@
 }
 
 core::type::AbstractFloat* Resolver::AF() {
-    return builder_->create<core::type::AbstractFloat>();
+    return b.create<core::type::AbstractFloat>();
 }
 
 core::type::F32* Resolver::F32() {
-    return builder_->create<core::type::F32>();
+    return b.create<core::type::F32>();
 }
 
 core::type::I32* Resolver::I32() {
-    return builder_->create<core::type::I32>();
+    return b.create<core::type::I32>();
 }
 
 core::type::U32* Resolver::U32() {
-    return builder_->create<core::type::U32>();
+    return b.create<core::type::U32>();
 }
 
 core::type::F16* Resolver::F16(const ast::Identifier* ident) {
-    return validator_.CheckF16Enabled(ident->source) ? builder_->create<core::type::F16>()
-                                                     : nullptr;
+    return validator_.CheckF16Enabled(ident->source) ? b.create<core::type::F16>() : nullptr;
 }
 
 core::type::Vector* Resolver::Vec(const ast::Identifier* ident, core::type::Type* el, uint32_t n) {
@@ -2782,7 +2749,7 @@
     if (TINT_UNLIKELY(!validator_.Vector(el, ident->source))) {
         return nullptr;
     }
-    return builder_->create<core::type::Vector>(el, n);
+    return b.create<core::type::Vector>(el, n);
 }
 
 core::type::Vector* Resolver::VecT(const ast::Identifier* ident, uint32_t n) {
@@ -2811,7 +2778,7 @@
     if (!column) {
         return nullptr;
     }
-    return builder_->create<core::type::Matrix>(column, num_columns);
+    return b.create<core::type::Matrix>(column, num_columns);
 }
 
 core::type::Matrix* Resolver::MatT(const ast::Identifier* ident,
@@ -2845,7 +2812,7 @@
     }
 
     const core::type::ArrayCount* el_count =
-        ast_count ? ArrayCount(ast_count) : builder_->create<core::type::RuntimeArrayCount>();
+        ast_count ? ArrayCount(ast_count) : b.create<core::type::RuntimeArrayCount>();
     if (!el_count) {
         return nullptr;
     }
@@ -2875,7 +2842,7 @@
     // Track the pipeline-overridable constants that are transitively referenced by this
     // array type.
     for (auto* var : transitively_referenced_overrides) {
-        builder_->Sem().AddTransitivelyReferencedOverride(out, var);
+        b.Sem().AddTransitivelyReferencedOverride(out, var);
     }
     return out;
 }
@@ -2892,7 +2859,7 @@
     }
     auto* ty = ty_expr->Type();
 
-    auto* out = builder_->create<core::type::Atomic>(ty);
+    auto* out = b.create<core::type::Atomic>(ty);
     if (!validator_.Atomic(tmpl_ident, out)) {
         return nullptr;
     }
@@ -2926,7 +2893,7 @@
         access = access_expr->Value();
     }
 
-    auto* out = builder_->create<core::type::Pointer>(address_space, store_ty, access);
+    auto* out = b.create<core::type::Pointer>(address_space, store_ty, access);
     if (!validator_.Pointer(tmpl_ident, out)) {
         return nullptr;
     }
@@ -2949,7 +2916,7 @@
     if (TINT_UNLIKELY(!ty_expr)) {
         return nullptr;
     }
-    auto* out = builder_->create<core::type::SampledTexture>(dim, ty_expr->Type());
+    auto* out = b.create<core::type::SampledTexture>(dim, ty_expr->Type());
     return validator_.SampledTexture(out, ident->source) ? out : nullptr;
 }
 
@@ -2964,7 +2931,7 @@
     if (TINT_UNLIKELY(!ty_expr)) {
         return nullptr;
     }
-    auto* out = builder_->create<core::type::MultisampledTexture>(dim, ty_expr->Type());
+    auto* out = b.create<core::type::MultisampledTexture>(dim, ty_expr->Type());
     return validator_.MultisampledTexture(out, ident->source) ? out : nullptr;
 }
 
@@ -2983,9 +2950,9 @@
     if (TINT_UNLIKELY(!access)) {
         return nullptr;
     }
-    auto* subtype = core::type::StorageTexture::SubtypeFor(format->Value(), builder_->Types());
-    auto* tex = builder_->create<core::type::StorageTexture>(dim, format->Value(), access->Value(),
-                                                             subtype);
+    auto* subtype = core::type::StorageTexture::SubtypeFor(format->Value(), b.Types());
+    auto* tex =
+        b.create<core::type::StorageTexture>(dim, format->Value(), access->Value(), subtype);
     if (!validator_.StorageTexture(tex, ident->source)) {
         return nullptr;
     }
@@ -3005,7 +2972,7 @@
     if (TINT_UNLIKELY(!validator_.Vector(el_ty, ident->source))) {
         return nullptr;
     }
-    return builder_->create<core::type::Vector>(el_ty, 3u, true);
+    return b.create<core::type::Vector>(el_ty, 3u, true);
 }
 
 const ast::TemplatedIdentifier* Resolver::TemplatedIdentifier(const ast::Identifier* ident,
@@ -3098,9 +3065,9 @@
     // TODO(crbug.com/tint/1420): For now, assume all function calls have side
     // effects.
     bool has_side_effects = true;
-    auto* call = builder_->create<sem::Call>(expr, target, core::EvaluationStage::kRuntime,
-                                             std::move(args), current_statement_,
-                                             /* constant_value */ nullptr, has_side_effects);
+    auto* call = b.create<sem::Call>(expr, target, core::EvaluationStage::kRuntime, std::move(args),
+                                     current_statement_,
+                                     /* constant_value */ nullptr, has_side_effects);
 
     target->AddCallSite(call);
 
@@ -3134,9 +3101,8 @@
     }
 
     // Associate the target identifier expression with the resolved function.
-    auto* fn_expr =
-        builder_->create<sem::FunctionExpression>(expr->target, current_statement_, target);
-    builder_->Sem().Add(expr->target, fn_expr);
+    auto* fn_expr = b.create<sem::FunctionExpression>(expr->target, current_statement_, target);
+    b.Sem().Add(expr->target, fn_expr);
 
     return call;
 }
@@ -3170,11 +3136,11 @@
         [&](const ast::IntLiteralExpression* i) -> core::type::Type* {
             switch (i->suffix) {
                 case ast::IntLiteralExpression::Suffix::kNone:
-                    return builder_->create<core::type::AbstractInt>();
+                    return b.create<core::type::AbstractInt>();
                 case ast::IntLiteralExpression::Suffix::kI:
-                    return builder_->create<core::type::I32>();
+                    return b.create<core::type::I32>();
                 case ast::IntLiteralExpression::Suffix::kU:
-                    return builder_->create<core::type::U32>();
+                    return b.create<core::type::U32>();
             }
             TINT_UNREACHABLE() << "Unhandled integer literal suffix: " << i->suffix;
             return nullptr;
@@ -3182,18 +3148,17 @@
         [&](const ast::FloatLiteralExpression* f) -> core::type::Type* {
             switch (f->suffix) {
                 case ast::FloatLiteralExpression::Suffix::kNone:
-                    return builder_->create<core::type::AbstractFloat>();
+                    return b.create<core::type::AbstractFloat>();
                 case ast::FloatLiteralExpression::Suffix::kF:
-                    return builder_->create<core::type::F32>();
+                    return b.create<core::type::F32>();
                 case ast::FloatLiteralExpression::Suffix::kH:
-                    return validator_.CheckF16Enabled(literal->source)
-                               ? builder_->create<core::type::F16>()
-                               : nullptr;
+                    return validator_.CheckF16Enabled(literal->source) ? b.create<core::type::F16>()
+                                                                       : nullptr;
             }
             TINT_UNREACHABLE() << "Unhandled float literal suffix: " << f->suffix;
             return nullptr;
         },
-        [&](const ast::BoolLiteralExpression*) { return builder_->create<core::type::Bool>(); },
+        [&](const ast::BoolLiteralExpression*) { return b.create<core::type::Bool>(); },
         [&](Default) {
             TINT_UNREACHABLE() << "Unhandled literal type: " << literal->TypeInfo().name;
             return nullptr;
@@ -3211,35 +3176,32 @@
     if (stage == core::EvaluationStage::kConstant) {
         val = Switch(
             literal,
-            [&](const ast::BoolLiteralExpression* lit) {
-                return builder_->constants.Get(lit->value);
-            },
+            [&](const ast::BoolLiteralExpression* lit) { return b.constants.Get(lit->value); },
             [&](const ast::IntLiteralExpression* lit) -> const core::constant::Value* {
                 switch (lit->suffix) {
                     case ast::IntLiteralExpression::Suffix::kNone:
-                        return builder_->constants.Get(AInt(lit->value));
+                        return b.constants.Get(AInt(lit->value));
                     case ast::IntLiteralExpression::Suffix::kI:
-                        return builder_->constants.Get(i32(lit->value));
+                        return b.constants.Get(i32(lit->value));
                     case ast::IntLiteralExpression::Suffix::kU:
-                        return builder_->constants.Get(u32(lit->value));
+                        return b.constants.Get(u32(lit->value));
                 }
                 return nullptr;
             },
             [&](const ast::FloatLiteralExpression* lit) -> const core::constant::Value* {
                 switch (lit->suffix) {
                     case ast::FloatLiteralExpression::Suffix::kNone:
-                        return builder_->constants.Get(AFloat(lit->value));
+                        return b.constants.Get(AFloat(lit->value));
                     case ast::FloatLiteralExpression::Suffix::kF:
-                        return builder_->constants.Get(f32(lit->value));
+                        return b.constants.Get(f32(lit->value));
                     case ast::FloatLiteralExpression::Suffix::kH:
-                        return builder_->constants.Get(f16(lit->value));
+                        return b.constants.Get(f16(lit->value));
                 }
                 return nullptr;
             });
     }
-    return builder_->create<sem::ValueExpression>(literal, ty, stage, current_statement_,
-                                                  std::move(val),
-                                                  /* has_side_effects */ false);
+    return b.create<sem::ValueExpression>(literal, ty, stage, current_statement_, std::move(val),
+                                          /* has_side_effects */ false);
 }
 
 sem::Expression* Resolver::Identifier(const ast::IdentifierExpression* expr) {
@@ -3271,8 +3233,8 @@
                     stage = core::EvaluationStage::kNotEvaluated;
                     value = nullptr;
                 }
-                auto* user = builder_->create<sem::VariableUser>(expr, stage, current_statement_,
-                                                                 value, variable);
+                auto* user =
+                    b.create<sem::VariableUser>(expr, stage, current_statement_, value, variable);
 
                 if (current_statement_) {
                     // If identifier is part of a loop continuing block, make sure it
@@ -3308,7 +3270,7 @@
                 if (current_function_) {
                     if (global) {
                         current_function_->AddDirectlyReferencedGlobal(global);
-                        auto* refs = builder_->Sem().TransitivelyReferencedOverrides(global);
+                        auto* refs = b.Sem().TransitivelyReferencedOverrides(global);
                         if (refs) {
                             for (auto* var : *refs) {
                                 current_function_->AddTransitivelyReferencedGlobal(var);
@@ -3320,7 +3282,7 @@
                         // Track the reference to this pipeline-overridable constant and any other
                         // pipeline-overridable constants that it references.
                         resolved_overrides_->Add(global);
-                        auto* refs = builder_->Sem().TransitivelyReferencedOverrides(global);
+                        auto* refs = b.Sem().TransitivelyReferencedOverrides(global);
                         if (refs) {
                             for (auto* var : *refs) {
                                 resolved_overrides_->Add(var);
@@ -3346,13 +3308,13 @@
                 if (!TINT_LIKELY(CheckNotTemplated("type", ident))) {
                     return nullptr;
                 }
-                return builder_->create<sem::TypeExpression>(expr, current_statement_, ty);
+                return b.create<sem::TypeExpression>(expr, current_statement_, ty);
             },
             [&](const sem::Function* fn) -> sem::FunctionExpression* {
                 if (!TINT_LIKELY(CheckNotTemplated("function", ident))) {
                     return nullptr;
                 }
-                return builder_->create<sem::FunctionExpression>(expr, current_statement_, fn);
+                return b.create<sem::FunctionExpression>(expr, current_statement_, fn);
             });
     }
 
@@ -3361,7 +3323,7 @@
         if (!ty) {
             return nullptr;
         }
-        return builder_->create<sem::TypeExpression>(expr, current_statement_, ty);
+        return b.create<sem::TypeExpression>(expr, current_statement_, ty);
     }
 
     if (resolved->BuiltinFn() != wgsl::BuiltinFn::kNone) {
@@ -3371,21 +3333,21 @@
 
     if (auto access = resolved->Access(); access != core::Access::kUndefined) {
         return CheckNotTemplated("access", ident)
-                   ? builder_->create<sem::BuiltinEnumExpression<core::Access>>(
-                         expr, current_statement_, access)
+                   ? b.create<sem::BuiltinEnumExpression<core::Access>>(expr, current_statement_,
+                                                                        access)
                    : nullptr;
     }
 
     if (auto addr = resolved->AddressSpace(); addr != core::AddressSpace::kUndefined) {
         return CheckNotTemplated("address space", ident)
-                   ? builder_->create<sem::BuiltinEnumExpression<core::AddressSpace>>(
+                   ? b.create<sem::BuiltinEnumExpression<core::AddressSpace>>(
                          expr, current_statement_, addr)
                    : nullptr;
     }
 
     if (auto builtin = resolved->BuiltinValue(); builtin != core::BuiltinValue::kUndefined) {
         return CheckNotTemplated("builtin value", ident)
-                   ? builder_->create<sem::BuiltinEnumExpression<core::BuiltinValue>>(
+                   ? b.create<sem::BuiltinEnumExpression<core::BuiltinValue>>(
                          expr, current_statement_, builtin)
                    : nullptr;
     }
@@ -3393,7 +3355,7 @@
     if (auto i_smpl = resolved->InterpolationSampling();
         i_smpl != core::InterpolationSampling::kUndefined) {
         return CheckNotTemplated("interpolation sampling", ident)
-                   ? builder_->create<sem::BuiltinEnumExpression<core::InterpolationSampling>>(
+                   ? b.create<sem::BuiltinEnumExpression<core::InterpolationSampling>>(
                          expr, current_statement_, i_smpl)
                    : nullptr;
     }
@@ -3401,14 +3363,14 @@
     if (auto i_type = resolved->InterpolationType();
         i_type != core::InterpolationType::kUndefined) {
         return CheckNotTemplated("interpolation type", ident)
-                   ? builder_->create<sem::BuiltinEnumExpression<core::InterpolationType>>(
+                   ? b.create<sem::BuiltinEnumExpression<core::InterpolationType>>(
                          expr, current_statement_, i_type)
                    : nullptr;
     }
 
     if (auto fmt = resolved->TexelFormat(); fmt != core::TexelFormat::kUndefined) {
         return CheckNotTemplated("texel format", ident)
-                   ? builder_->create<sem::BuiltinEnumExpression<core::TexelFormat>>(
+                   ? b.create<sem::BuiltinEnumExpression<core::TexelFormat>>(
                          expr, current_statement_, fmt)
                    : nullptr;
     }
@@ -3481,16 +3443,15 @@
 
             // If we're extracting from a reference, we return a reference.
             if (auto* ref = object_ty->As<core::type::Reference>()) {
-                ty =
-                    builder_->create<core::type::Reference>(ref->AddressSpace(), ty, ref->Access());
+                ty = b.create<core::type::Reference>(ref->AddressSpace(), ty, ref->Access());
             }
 
             const core::constant::Value* val = nullptr;
             if (auto* obj_val = object->ConstantValue()) {
                 val = obj_val->Index(static_cast<size_t>(member->Index()));
             }
-            return builder_->create<sem::StructMemberAccess>(
-                expr, ty, current_statement_, val, object, member, has_side_effects, root_ident);
+            return b.create<sem::StructMemberAccess>(expr, ty, current_statement_, val, object,
+                                                     member, has_side_effects, root_ident);
         },
 
         [&](const core::type::Vector* vec) -> sem::ValueExpression* {
@@ -3550,13 +3511,12 @@
                 ty = vec->type();
                 // If we're extracting from a reference, we return a reference.
                 if (auto* ref = object_ty->As<core::type::Reference>()) {
-                    ty = builder_->create<core::type::Reference>(ref->AddressSpace(), ty,
-                                                                 ref->Access());
+                    ty = b.create<core::type::Reference>(ref->AddressSpace(), ty, ref->Access());
                 }
             } else {
                 // The vector will have a number of components equal to the length of
                 // the swizzle.
-                ty = builder_->create<core::type::Vector>(vec->type(), static_cast<uint32_t>(size));
+                ty = b.create<core::type::Vector>(vec->type(), static_cast<uint32_t>(size));
 
                 // The load rule is invoked before the swizzle, if necessary.
                 obj_expr = Load(object);
@@ -3569,8 +3529,8 @@
                 }
                 val = res.Get();
             }
-            return builder_->create<sem::Swizzle>(expr, ty, current_statement_, val, obj_expr,
-                                                  std::move(swizzle), has_side_effects, root_ident);
+            return b.create<sem::Swizzle>(expr, ty, current_statement_, val, obj_expr,
+                                          std::move(swizzle), has_side_effects, root_ident);
         },
 
         [&](Default) {
@@ -3660,8 +3620,8 @@
     }
 
     bool has_side_effects = lhs->HasSideEffects() || rhs->HasSideEffects();
-    auto* sem = builder_->create<sem::ValueExpression>(expr, res_ty, stage, current_statement_,
-                                                       value, has_side_effects);
+    auto* sem = b.create<sem::ValueExpression>(expr, res_ty, stage, current_statement_, value,
+                                               has_side_effects);
     sem->Behaviors() = lhs->Behaviors() + rhs->Behaviors();
 
     return sem;
@@ -3697,8 +3657,8 @@
                     return nullptr;
                 }
 
-                ty = builder_->create<core::type::Pointer>(ref->AddressSpace(), ref->StoreType(),
-                                                           ref->Access());
+                ty = b.create<core::type::Pointer>(ref->AddressSpace(), ref->StoreType(),
+                                                   ref->Access());
 
                 root_ident = expr->RootIdentifier();
             } else {
@@ -3709,8 +3669,8 @@
 
         case core::UnaryOp::kIndirection:
             if (auto* ptr = expr_ty->As<core::type::Pointer>()) {
-                ty = builder_->create<core::type::Reference>(ptr->AddressSpace(), ptr->StoreType(),
-                                                             ptr->Access());
+                ty = b.create<core::type::Reference>(ptr->AddressSpace(), ptr->StoreType(),
+                                                     ptr->Access());
                 root_ident = expr->RootIdentifier();
             } else {
                 AddError("cannot dereference expression of type '" + sem_.TypeNameOf(expr_ty) + "'",
@@ -3757,8 +3717,8 @@
         }
     }
 
-    auto* sem = builder_->create<sem::ValueExpression>(unary, ty, stage, current_statement_, value,
-                                                       expr->HasSideEffects(), root_ident);
+    auto* sem = b.create<sem::ValueExpression>(unary, ty, stage, current_statement_, value,
+                                               expr->HasSideEffects(), root_ident);
     sem->Behaviors() = expr->Behaviors();
     return sem;
 }
@@ -3906,7 +3866,7 @@
 
     // If all arguments are abstract-integers, then materialize to i32.
     if (common_ty->Is<core::type::AbstractInt>()) {
-        common_ty = builder_->create<core::type::I32>();
+        common_ty = b.create<core::type::I32>();
     }
 
     for (size_t i = 0; i < args.Length(); i++) {
@@ -3945,7 +3905,7 @@
     }
     // Apply the resolved tint::sem::BuiltinEnumExpression<tint::core::BuiltinValue> to the
     // attribute.
-    builder_->Sem().Add(attr, builtin_expr);
+    b.Sem().Add(attr, builtin_expr);
     return builtin_expr->Value();
 }
 
@@ -4055,7 +4015,7 @@
         return nullptr;
     }
 
-    builder_->Sem().Add(named_type, result);
+    b.Sem().Add(named_type, result);
     return result;
 }
 
@@ -4071,10 +4031,10 @@
         // Is the count a named 'override'?
         if (auto* user = count_sem->UnwrapMaterialize()->As<sem::VariableUser>()) {
             if (auto* global = user->Variable()->As<sem::GlobalVariable>()) {
-                return builder_->create<sem::NamedOverrideArrayCount>(global);
+                return b.create<sem::NamedOverrideArrayCount>(global);
             }
         }
-        return builder_->create<sem::UnnamedOverrideArrayCount>(count_sem);
+        return b.create<sem::UnnamedOverrideArrayCount>(count_sem);
     }
 
     auto* count_val = count_sem->ConstantValue();
@@ -4098,7 +4058,7 @@
         return nullptr;
     }
 
-    return builder_->create<core::type::ConstantArrayCount>(static_cast<uint32_t>(count));
+    return b.create<core::type::ConstantArrayCount>(static_cast<uint32_t>(count));
 }
 
 bool Resolver::ArrayAttributes(VectorRef<const ast::Attribute*> attributes,
@@ -4161,9 +4121,9 @@
     } else if (el_count->Is<core::type::RuntimeArrayCount>()) {
         size = stride;
     }
-    auto* out = builder_->create<core::type::Array>(
-        el_ty, el_count, el_align, static_cast<uint32_t>(size), static_cast<uint32_t>(stride),
-        static_cast<uint32_t>(implicit_stride));
+    auto* out = b.create<core::type::Array>(el_ty, el_count, el_align, static_cast<uint32_t>(size),
+                                            static_cast<uint32_t>(stride),
+                                            static_cast<uint32_t>(implicit_stride));
 
     // Maximum nesting depth of composite types
     //  https://gpuweb.github.io/gpuweb/wgsl/#limits
@@ -4445,11 +4405,11 @@
             return nullptr;
         }
 
-        auto* sem_member = builder_->create<sem::StructMember>(
+        auto* sem_member = b.create<sem::StructMember>(
             member, member->name->symbol, type, static_cast<uint32_t>(sem_members.Length()),
             static_cast<uint32_t>(offset), static_cast<uint32_t>(align),
             static_cast<uint32_t>(size), attributes);
-        builder_->Sem().Add(member, sem_member);
+        b.Sem().Add(member, sem_member);
         sem_members.Push(sem_member);
 
         struct_size = offset + size;
@@ -4470,7 +4430,7 @@
         return nullptr;
     }
 
-    auto* out = builder_->create<sem::Struct>(
+    auto* out = b.create<sem::Struct>(
         str, str->name->symbol, std::move(sem_members), static_cast<uint32_t>(struct_align),
         static_cast<uint32_t>(struct_size), static_cast<uint32_t>(size_no_padding));
 
@@ -4511,8 +4471,7 @@
 }
 
 sem::Statement* Resolver::ReturnStatement(const ast::ReturnStatement* stmt) {
-    auto* sem =
-        builder_->create<sem::Statement>(stmt, current_compound_statement_, current_function_);
+    auto* sem = b.create<sem::Statement>(stmt, current_compound_statement_, current_function_);
     return StatementScope(stmt, sem, [&] {
         auto& behaviors = current_statement_->Behaviors();
         behaviors = sem::Behavior::kReturn;
@@ -4533,7 +4492,7 @@
 
             value_ty = expr->Type();
         } else {
-            value_ty = builder_->create<core::type::Void>();
+            value_ty = b.create<core::type::Void>();
         }
 
         // Validate after processing the return value expression so that its type
@@ -4544,8 +4503,8 @@
 }
 
 sem::SwitchStatement* Resolver::SwitchStatement(const ast::SwitchStatement* stmt) {
-    auto* sem = builder_->create<sem::SwitchStatement>(stmt, current_compound_statement_,
-                                                       current_function_);
+    auto* sem =
+        b.create<sem::SwitchStatement>(stmt, current_compound_statement_, current_function_);
     return StatementScope(stmt, sem, [&] {
         auto& behaviors = sem->Behaviors();
 
@@ -4577,7 +4536,7 @@
         if (!common_ty || !common_ty->is_integer_scalar()) {
             // No common type found or the common type was abstract.
             // Pick i32 and let validation deal with any mismatches.
-            common_ty = builder_->create<core::type::I32>();
+            common_ty = b.create<core::type::I32>();
         }
         cond = Materialize(cond, common_ty);
         if (!cond) {
@@ -4627,8 +4586,7 @@
 }
 
 sem::Statement* Resolver::VariableDeclStatement(const ast::VariableDeclStatement* stmt) {
-    auto* sem =
-        builder_->create<sem::Statement>(stmt, current_compound_statement_, current_function_);
+    auto* sem = b.create<sem::Statement>(stmt, current_compound_statement_, current_function_);
     return StatementScope(stmt, sem, [&] {
         Mark(stmt->variable);
 
@@ -4648,8 +4606,7 @@
 }
 
 sem::Statement* Resolver::AssignmentStatement(const ast::AssignmentStatement* stmt) {
-    auto* sem =
-        builder_->create<sem::Statement>(stmt, current_compound_statement_, current_function_);
+    auto* sem = b.create<sem::Statement>(stmt, current_compound_statement_, current_function_);
     return StatementScope(stmt, sem, [&] {
         auto* lhs = ValueExpression(stmt->lhs);
         if (!lhs) {
@@ -4690,8 +4647,7 @@
 }
 
 sem::Statement* Resolver::BreakStatement(const ast::BreakStatement* stmt) {
-    auto* sem =
-        builder_->create<sem::Statement>(stmt, current_compound_statement_, current_function_);
+    auto* sem = b.create<sem::Statement>(stmt, current_compound_statement_, current_function_);
     return StatementScope(stmt, sem, [&] {
         sem->Behaviors() = sem::Behavior::kBreak;
 
@@ -4700,8 +4656,8 @@
 }
 
 sem::Statement* Resolver::BreakIfStatement(const ast::BreakIfStatement* stmt) {
-    auto* sem = builder_->create<sem::BreakIfStatement>(stmt, current_compound_statement_,
-                                                        current_function_);
+    auto* sem =
+        b.create<sem::BreakIfStatement>(stmt, current_compound_statement_, current_function_);
     return StatementScope(stmt, sem, [&] {
         auto* cond = Load(ValueExpression(stmt->condition));
         if (!cond) {
@@ -4716,8 +4672,7 @@
 }
 
 sem::Statement* Resolver::CallStatement(const ast::CallStatement* stmt) {
-    auto* sem =
-        builder_->create<sem::Statement>(stmt, current_compound_statement_, current_function_);
+    auto* sem = b.create<sem::Statement>(stmt, current_compound_statement_, current_function_);
     return StatementScope(stmt, sem, [&] {
         if (auto* expr = ValueExpression(stmt->expr)) {
             sem->Behaviors() = expr->Behaviors();
@@ -4729,8 +4684,7 @@
 
 sem::Statement* Resolver::CompoundAssignmentStatement(
     const ast::CompoundAssignmentStatement* stmt) {
-    auto* sem =
-        builder_->create<sem::Statement>(stmt, current_compound_statement_, current_function_);
+    auto* sem = b.create<sem::Statement>(stmt, current_compound_statement_, current_function_);
     return StatementScope(stmt, sem, [&] {
         auto* lhs = ValueExpression(stmt->lhs);
         if (!lhs) {
@@ -4766,8 +4720,7 @@
 }
 
 sem::Statement* Resolver::ContinueStatement(const ast::ContinueStatement* stmt) {
-    auto* sem =
-        builder_->create<sem::Statement>(stmt, current_compound_statement_, current_function_);
+    auto* sem = b.create<sem::Statement>(stmt, current_compound_statement_, current_function_);
     return StatementScope(stmt, sem, [&] {
         sem->Behaviors() = sem::Behavior::kContinue;
 
@@ -4784,8 +4737,7 @@
 }
 
 sem::Statement* Resolver::DiscardStatement(const ast::DiscardStatement* stmt) {
-    auto* sem =
-        builder_->create<sem::Statement>(stmt, current_compound_statement_, current_function_);
+    auto* sem = b.create<sem::Statement>(stmt, current_compound_statement_, current_function_);
     return StatementScope(stmt, sem, [&] {
         current_function_->SetDiscardStatement(sem);
         return true;
@@ -4794,8 +4746,7 @@
 
 sem::Statement* Resolver::IncrementDecrementStatement(
     const ast::IncrementDecrementStatement* stmt) {
-    auto* sem =
-        builder_->create<sem::Statement>(stmt, current_compound_statement_, current_function_);
+    auto* sem = b.create<sem::Statement>(stmt, current_compound_statement_, current_function_);
     return StatementScope(stmt, sem, [&] {
         auto* lhs = ValueExpression(stmt->lhs);
         if (!lhs) {
@@ -4869,7 +4820,7 @@
 
 template <typename SEM, typename F>
 SEM* Resolver::StatementScope(const ast::Statement* ast, SEM* sem, F&& callback) {
-    builder_->Sem().Add(ast, sem);
+    b.Sem().Add(ast, sem);
 
     auto* as_compound =
         As<sem::CompoundStatement, tint::CastFlags::kDontErrorOnImpossibleCast>(sem);
diff --git a/src/tint/lang/wgsl/resolver/resolver.h b/src/tint/lang/wgsl/resolver/resolver.h
index 7641849..2ba9a26 100644
--- a/src/tint/lang/wgsl/resolver/resolver.h
+++ b/src/tint/lang/wgsl/resolver/resolver.h
@@ -676,7 +676,7 @@
         tint::Slice<char const* const> suggestions = tint::Empty;
     };
 
-    ProgramBuilder* const builder_;
+    ProgramBuilder& b;
     diag::List& diagnostics_;
     core::constant::Eval const_eval_;
     core::intrinsic::Table<wgsl::intrinsic::Dialect> intrinsic_table_;
diff --git a/src/tint/lang/wgsl/resolver/uniformity.cc b/src/tint/lang/wgsl/resolver/uniformity.cc
index 506a20b..aa7190b 100644
--- a/src/tint/lang/wgsl/resolver/uniformity.cc
+++ b/src/tint/lang/wgsl/resolver/uniformity.cc
@@ -176,8 +176,8 @@
 struct FunctionInfo {
     /// Constructor
     /// @param func the AST function
-    /// @param builder the program builder
-    FunctionInfo(const ast::Function* func, const ProgramBuilder* builder) {
+    /// @param b the program builder
+    FunctionInfo(const ast::Function* func, const ProgramBuilder& b) {
         name = func->name->symbol.Name();
         callsite_tag = {CallSiteTag::CallSiteNoRestriction};
         function_tag = NoRestriction;
@@ -197,7 +197,7 @@
         for (size_t i = 0; i < func->params.Length(); i++) {
             auto* param = func->params[i];
             auto param_name = param->name->symbol.Name();
-            auto* sem = builder->Sem().Get<sem::Parameter>(param);
+            auto* sem = b.Sem().Get<sem::Parameter>(param);
             parameters[i].sem = sem;
 
             parameters[i].value = CreateNode({"param_", param_name});
@@ -339,8 +339,8 @@
   public:
     /// Constructor.
     /// @param builder the program to analyze
-    explicit UniformityGraph(ProgramBuilder* builder)
-        : builder_(builder), sem_(builder->Sem()), diagnostics_(builder->Diagnostics()) {}
+    explicit UniformityGraph(ProgramBuilder& builder)
+        : b(builder), sem_(b.Sem()), diagnostics_(builder.Diagnostics()) {}
 
     /// Destructor.
     ~UniformityGraph() {}
@@ -374,7 +374,7 @@
     }
 
   private:
-    const ProgramBuilder* builder_;
+    const ProgramBuilder& b;
     const sem::Info& sem_;
     diag::List& diagnostics_;
 
@@ -418,7 +418,7 @@
     /// @param func the function to process
     /// @returns true if there are no uniformity issues, false otherwise
     bool ProcessFunction(const ast::Function* func) {
-        current_function_ = functions_.Add(func, FunctionInfo(func, builder_)).value;
+        current_function_ = functions_.Add(func, FunctionInfo(func, b)).value;
 
         // Process function body.
         if (func->body) {
@@ -565,21 +565,22 @@
                 return cf_r;
             },
 
-            [&](const ast::BlockStatement* b) {
+            [&](const ast::BlockStatement* block) {
                 Hashmap<const sem::Variable*, Node*, 4> scoped_assignments;
+                auto* sem = sem_.Get(block);
                 {
                     // Push a new scope for variable assignments in the block.
                     current_function_->variables.Push();
                     TINT_DEFER(current_function_->variables.Pop());
 
-                    for (auto* s : b->statements) {
+                    for (auto* s : block->statements) {
                         cf = ProcessStatement(cf, s);
                         if (!sem_.Get(s)->Behaviors().Contains(sem::Behavior::kNext)) {
                             break;
                         }
                     }
 
-                    auto* parent = sem_.Get(b)->Parent();
+                    auto* parent = sem->Parent();
                     auto* loop = parent ? parent->As<sem::LoopStatement>() : nullptr;
                     if (loop) {
                         // We've reached the end of a loop body. If there is a continuing block,
@@ -587,7 +588,7 @@
                         // loop body are visible to the continuing block.
                         if (auto* continuing =
                                 loop->Declaration()->As<ast::LoopStatement>()->continuing) {
-                            auto& loop_body_behavior = sem_.Get(b)->Behaviors();
+                            auto& loop_body_behavior = sem->Behaviors();
                             if (loop_body_behavior.Contains(sem::Behavior::kNext) ||
                                 loop_body_behavior.Contains(sem::Behavior::kContinue)) {
                                 cf = ProcessStatement(cf, continuing);
@@ -595,7 +596,7 @@
                         }
                     }
 
-                    if (sem_.Get<sem::FunctionBlockStatement>(b)) {
+                    if (sem_.Get<sem::FunctionBlockStatement>(block)) {
                         // We've reached the end of the function body.
                         // Add edges from pointer parameter outputs to their current value.
                         for (auto& param : current_function_->parameters) {
@@ -611,7 +612,7 @@
 
                 // Propagate all variables assignments to the containing scope if the behavior is
                 // 'Next'.
-                auto& behaviors = sem_.Get(b)->Behaviors();
+                auto& behaviors = sem->Behaviors();
                 if (behaviors.Contains(sem::Behavior::kNext)) {
                     for (auto var : scoped_assignments) {
                         current_function_->variables.Set(var.key, var.value);
@@ -619,16 +620,16 @@
                 }
 
                 // Remove any variables declared in this scope from the set of in-scope variables.
-                for (auto decl : sem_.Get<sem::BlockStatement>(b)->Decls()) {
+                for (auto decl : sem->Decls()) {
                     current_function_->local_var_decls.Remove(decl.value.variable);
                 }
 
                 return cf;
             },
 
-            [&](const ast::BreakStatement* b) {
+            [&](const ast::BreakStatement* brk) {
                 // Find the loop or switch statement that we are in.
-                auto* parent = sem_.Get(b)
+                auto* parent = sem_.Get(brk)
                                    ->FindFirstParent<sem::SwitchStatement, sem::LoopStatement,
                                                      sem::ForLoopStatement, sem::WhileStatement>();
 
@@ -654,20 +655,21 @@
                 return cf;
             },
 
-            [&](const ast::BreakIfStatement* b) {
+            [&](const ast::BreakIfStatement* brk) {
                 // This works very similar to the IfStatement uniformity below, execpt instead of
                 // processing the body, we directly inline the BreakStatement uniformity from
                 // above.
+                auto* sem = sem_.Get(brk);
 
-                auto [_, v_cond] = ProcessExpression(cf, b->condition);
+                auto [_, v_cond] = ProcessExpression(cf, brk->condition);
 
                 // Add a diagnostic node to capture the control flow change.
-                auto* v = CreateNode({"break_if_stmt"}, b);
+                auto* v = CreateNode({"break_if_stmt"}, brk);
                 v->affects_control_flow = true;
                 v->AddEdge(v_cond);
 
                 {
-                    auto* parent = sem_.Get(b)->FindFirstParent<sem::LoopStatement>();
+                    auto* parent = sem->FindFirstParent<sem::LoopStatement>();
                     auto& info = current_function_->LoopSwitchInfoFor(parent);
 
                     // Propagate variable values to the loop exit nodes.
@@ -689,8 +691,7 @@
                     }
                 }
 
-                auto* sem_break_if = sem_.Get(b);
-                if (sem_break_if->Behaviors() != sem::Behaviors{sem::Behavior::kNext}) {
+                if (sem->Behaviors() != sem::Behaviors{sem::Behavior::kNext}) {
                     auto* cf_end = CreateNode({"break_if_CFend"});
                     cf_end->AddEdge(v);
                     return cf_end;
@@ -1178,7 +1179,7 @@
         auto has_nonuniform_entry_point_attribute = [&](auto* obj) {
             // Only the num_workgroups and workgroup_id builtins are uniform.
             if (auto* builtin_attr = ast::GetAttribute<ast::BuiltinAttribute>(obj->attributes)) {
-                auto builtin = builder_->Sem().Get(builtin_attr)->Value();
+                auto builtin = b.Sem().Get(builtin_attr)->Value();
                 if (builtin == core::BuiltinValue::kNumWorkgroups ||
                     builtin == core::BuiltinValue::kWorkgroupId) {
                     return false;
@@ -1316,29 +1317,29 @@
         return Switch(
             expr,
 
-            [&](const ast::BinaryExpression* b) {
-                if (b->IsLogical()) {
+            [&](const ast::BinaryExpression* e) {
+                if (e->IsLogical()) {
                     // Short-circuiting binary operators are a special case.
-                    auto [cf1, v1] = ProcessExpression(cf, b->lhs);
+                    auto [cf1, v1] = ProcessExpression(cf, e->lhs);
 
                     // Add a diagnostic node to capture the control flow change.
-                    auto* v1_cf = CreateNode({"short_circuit_op"}, b);
+                    auto* v1_cf = CreateNode({"short_circuit_op"}, e);
                     v1_cf->affects_control_flow = true;
                     v1_cf->AddEdge(v1);
 
-                    auto [cf2, v2] = ProcessExpression(v1_cf, b->rhs);
+                    auto [cf2, v2] = ProcessExpression(v1_cf, e->rhs);
                     return std::pair<Node*, Node*>(cf, v2);
                 } else {
-                    auto [cf1, v1] = ProcessExpression(cf, b->lhs);
-                    auto [cf2, v2] = ProcessExpression(cf1, b->rhs);
-                    auto* result = CreateNode({"binary_expr_result"}, b);
+                    auto [cf1, v1] = ProcessExpression(cf, e->lhs);
+                    auto [cf2, v2] = ProcessExpression(cf1, e->rhs);
+                    auto* result = CreateNode({"binary_expr_result"}, e);
                     result->AddEdge(v1);
                     result->AddEdge(v2);
                     return std::pair<Node*, Node*>(cf2, result);
                 }
             },
 
-            [&](const ast::BitcastExpression* b) { return ProcessExpression(cf, b->expr); },
+            [&](const ast::BitcastExpression* e) { return ProcessExpression(cf, e->expr); },
 
             [&](const ast::CallExpression* c) { return ProcessCall(cf, c); },
 
@@ -1977,7 +1978,7 @@
 
 }  // namespace
 
-bool AnalyzeUniformity(ProgramBuilder* builder, const DependencyGraph& dependency_graph) {
+bool AnalyzeUniformity(ProgramBuilder& builder, const DependencyGraph& dependency_graph) {
     UniformityGraph graph(builder);
     return graph.Build(dependency_graph);
 }
diff --git a/src/tint/lang/wgsl/resolver/uniformity.h b/src/tint/lang/wgsl/resolver/uniformity.h
index 7fa7e04..93e8a70 100644
--- a/src/tint/lang/wgsl/resolver/uniformity.h
+++ b/src/tint/lang/wgsl/resolver/uniformity.h
@@ -32,7 +32,7 @@
 /// @param builder the program to analyze
 /// @param dependency_graph the dependency-ordered module-scope declarations
 /// @returns true if there are no uniformity issues, false otherwise
-bool AnalyzeUniformity(ProgramBuilder* builder, const resolver::DependencyGraph& dependency_graph);
+bool AnalyzeUniformity(ProgramBuilder& builder, const resolver::DependencyGraph& dependency_graph);
 
 }  // namespace tint::resolver
 
diff --git a/src/tint/lang/wgsl/sem/type_mappings.h b/src/tint/lang/wgsl/sem/type_mappings.h
index 2dfb6ac..7518167 100644
--- a/src/tint/lang/wgsl/sem/type_mappings.h
+++ b/src/tint/lang/wgsl/sem/type_mappings.h
@@ -27,6 +27,7 @@
 class AccessorExpression;
 class BinaryExpression;
 class BitcastExpression;
+class BlockStatement;
 class BuiltinAttribute;
 class CallExpression;
 class Expression;
@@ -42,14 +43,15 @@
 class StructMember;
 class SwitchStatement;
 class TypeDecl;
+class UnaryOpExpression;
 class Variable;
 class WhileStatement;
-class UnaryOpExpression;
 }  // namespace tint::ast
 namespace tint::core {
 enum class BuiltinValue : uint8_t;
 }
 namespace tint::sem {
+class BlockStatement;
 class Expression;
 class ForLoopStatement;
 class Function;
@@ -77,6 +79,7 @@
 /// rules will be used to infer the return type based on the argument type.
 struct TypeMappings {
     //! @cond Doxygen_Suppress
+    BlockStatement* operator()(ast::BlockStatement*);
     BuiltinEnumExpression<core::BuiltinValue>* operator()(ast::BuiltinAttribute*);
     CastableBase* operator()(ast::Node*);
     Expression* operator()(ast::Expression*);