[tint] Split diagnostic from result.

This CL splits the `Diagnostic` out from the `Result` class. This breaks
the dependency. A `diag::Result` is available for a result with a
default diagnostic failure.

Bug: 383726508
Change-Id: I8b8cab998e1569a724c0a63a9797ef6f982781ef
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/230714
Auto-Submit: dan sinclair <dsinclair@chromium.org>
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: James Price <jrprice@google.com>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
diff --git a/src/dawn/native/d3d/ShaderUtils.cpp b/src/dawn/native/d3d/ShaderUtils.cpp
index 20760ee..2095727 100644
--- a/src/dawn/native/d3d/ShaderUtils.cpp
+++ b/src/dawn/native/d3d/ShaderUtils.cpp
@@ -264,7 +264,7 @@
     }
 
     TRACE_EVENT0(tracePlatform.UnsafeGetValue(), General, "tint::hlsl::writer::Generate");
-    tint::Result<tint::hlsl::writer::Output> result;
+    tint::diag::Result<tint::hlsl::writer::Output> result;
     if (r.useTintIR) {
         // Convert the AST program to an IR module.
         auto ir = tint::wgsl::reader::ProgramToLoweredIR(transformedProgram);
diff --git a/src/tint/cmd/bench/bench.cc b/src/tint/cmd/bench/bench.cc
index f21f69b..7a62cb5 100644
--- a/src/tint/cmd/bench/bench.cc
+++ b/src/tint/cmd/bench/bench.cc
@@ -36,15 +36,15 @@
 
 namespace tint::bench {
 
-Result<Source::File> GetWgslFile(std::string name) {
+diag::Result<Source::File> GetWgslFile(std::string name) {
     auto wgsl = kBenchmarkInputs.find(name);
     if (wgsl == kBenchmarkInputs.end()) {
-        return Failure{"failed to find WGSL shader for '" + name + "'"};
+        return diag::Failure{"failed to find WGSL shader for '" + name + "'"};
     }
     return tint::Source::File("<input>", wgsl->second);
 }
 
-Result<ProgramAndFile> GetWgslProgram(std::string name) {
+diag::Result<ProgramAndFile> GetWgslProgram(std::string name) {
     auto res = GetWgslFile(name);
     if (res != Success) {
         return res.Failure();
@@ -52,7 +52,7 @@
     auto file = std::make_unique<Source::File>(res.Get());
     auto program = wgsl::reader::Parse(file.get());
     if (!program.IsValid()) {
-        return Failure{program.Diagnostics()};
+        return diag::Failure{program.Diagnostics()};
     }
     return ProgramAndFile{std::move(program), std::move(file)};
 }
diff --git a/src/tint/cmd/bench/bench.h b/src/tint/cmd/bench/bench.h
index 942d8cb..2920c52 100644
--- a/src/tint/cmd/bench/bench.h
+++ b/src/tint/cmd/bench/bench.h
@@ -33,8 +33,8 @@
 
 #include "benchmark/benchmark.h"  // IWYU pragma: export
 #include "src/tint/lang/wgsl/program/program.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 #include "src/tint/utils/macros/compiler.h"
-#include "src/tint/utils/result/result.h"
 
 // Autogenerated header that defines the benchmark shaders and macros for registering benchmarks.
 #include "src/tint/cmd/bench/benchmark_inputs.h"  // GEN_BUILD:IGNORE_INCLUDE
@@ -52,12 +52,12 @@
 /// Benchmarks that are SPIR-V shaders will have been converted to WGSL at startup.
 /// @param name the benchmark input name
 /// @returns the Source::File
-Result<Source::File> GetWgslFile(std::string name);
+diag::Result<Source::File> GetWgslFile(std::string name);
 
 /// GetWgslProgram parses the WGSL for a benchmark input program with the given name.
 /// @param name the benchmark input name
 /// @returns the parsed WGSL program
-Result<ProgramAndFile> GetWgslProgram(std::string name);
+diag::Result<ProgramAndFile> GetWgslProgram(std::string name);
 
 }  // namespace tint::bench
 
diff --git a/src/tint/cmd/fuzz/ir/as/main.cc b/src/tint/cmd/fuzz/ir/as/main.cc
index 27d2e08..d14246b 100644
--- a/src/tint/cmd/fuzz/ir/as/main.cc
+++ b/src/tint/cmd/fuzz/ir/as/main.cc
@@ -172,15 +172,15 @@
 /// enables, and validation.
 /// @param program the program to generate
 /// @returns generated module on success, tint::failure on failure
-tint::Result<tint::core::ir::Module> GenerateIrModule(const tint::Program& program) {
+tint::diag::Result<tint::core::ir::Module> GenerateIrModule(const tint::Program& program) {
     if (program.AST().Enables().Any(tint::wgsl::reader::IsUnsupportedByIR)) {
-        return tint::Failure{"Unsupported enable used in shader"};
+        return tint::diag::Failure{"Unsupported enable used in shader"};
     }
 
     auto transformed = tint::wgsl::ApplySubstituteOverrides(program);
     auto& src = transformed ? transformed.value() : program;
     if (!src.IsValid()) {
-        return tint::Failure{src.Diagnostics()};
+        return tint::diag::Failure{src.Diagnostics()};
     }
 
     auto ir = tint::wgsl::reader::ProgramToLoweredIR(src);
diff --git a/src/tint/cmd/fuzz/ir/fuzz.cc b/src/tint/cmd/fuzz/ir/fuzz.cc
index 97a73d0..1703665 100644
--- a/src/tint/cmd/fuzz/ir/fuzz.cc
+++ b/src/tint/cmd/fuzz/ir/fuzz.cc
@@ -31,13 +31,11 @@
 #include <functional>
 #include <iostream>
 #include <string>
-#include <string_view>
 #include <thread>
 
 #include "src/tint/utils/containers/vector.h"
 #include "src/tint/utils/ice/ice.h"
 #include "src/tint/utils/macros/defer.h"
-#include "src/tint/utils/macros/static_init.h"
 
 #if TINT_BUILD_WGSL_READER
 #include "src/tint/cmd/fuzz/wgsl/fuzz.h"
diff --git a/src/tint/cmd/fuzz/ir/fuzz.h b/src/tint/cmd/fuzz/ir/fuzz.h
index 002be50..1e0a080 100644
--- a/src/tint/cmd/fuzz/ir/fuzz.h
+++ b/src/tint/cmd/fuzz/ir/fuzz.h
@@ -37,6 +37,7 @@
 #include "src/tint/utils/bytes/buffer_reader.h"
 #include "src/tint/utils/bytes/decoder.h"
 #include "src/tint/utils/containers/slice.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 #include "src/tint/utils/macros/static_init.h"
 
 namespace tint::core::ir {
@@ -75,14 +76,16 @@
     /// additional arguments which are deserialized from the fuzzer input.
     template <typename... ARGS>
     static IRFuzzer Create(std::string_view name,
-                           Result<SuccessType> (*fn)(core::ir::Module&, const Context&, ARGS...),
+                           diag::Result<SuccessType> (*fn)(core::ir::Module&,
+                                                           const Context&,
+                                                           ARGS...),
                            core::ir::Capabilities pre_capabilities,
                            core::ir::Capabilities post_capabilities) {
         if constexpr (sizeof...(ARGS) > 0) {
             auto fn_with_decode = [fn](core::ir::Module& module, const Context& context,
-                                       Slice<const std::byte> data) -> Result<SuccessType> {
+                                       Slice<const std::byte> data) -> diag::Result<SuccessType> {
                 if (!data.data) {
-                    return Failure{"Invalid data"};
+                    return diag::Failure{"Invalid data"};
                 }
 
                 bytes::BufferReader reader{data};
@@ -100,8 +103,8 @@
         } else {
             return IRFuzzer{
                 name,
-                [fn](core::ir::Module& module, const Context& context,
-                     Slice<const std::byte>) -> Result<SuccessType> { return fn(module, context); },
+                [fn](core::ir::Module& module, const Context& context, Slice<const std::byte>)
+                    -> diag::Result<SuccessType> { return fn(module, context); },
                 pre_capabilities,
                 post_capabilities,
             };
@@ -115,7 +118,9 @@
     /// additional arguments which are deserialized from the fuzzer input.
     template <typename... ARGS>
     static IRFuzzer Create(std::string_view name,
-                           Result<SuccessType> (*fn)(core::ir::Module&, const Context&, ARGS...),
+                           diag::Result<SuccessType> (*fn)(core::ir::Module&,
+                                                           const Context&,
+                                                           ARGS...),
                            core::ir::Capabilities capabilities) {
         return Create(name, fn, capabilities, capabilities);
     }
@@ -126,7 +131,7 @@
     /// Takes in the module and any sidecar data, returns true iff transform succeeded in running,
     /// otherwise false
     std::function<
-        Result<SuccessType>(core::ir::Module&, const Context&, Slice<const std::byte> data)>
+        diag::Result<SuccessType>(core::ir::Module&, const Context&, Slice<const std::byte> data)>
         fn;
     /// The IR capabilities that are used before the fuzzer runs.
     core::ir::Capabilities pre_capabilities;
diff --git a/src/tint/cmd/tint/main.cc b/src/tint/cmd/tint/main.cc
index 8bb9438..8a56551 100644
--- a/src/tint/cmd/tint/main.cc
+++ b/src/tint/cmd/tint/main.cc
@@ -54,6 +54,7 @@
 #include "src/tint/utils/command/cli.h"
 #include "src/tint/utils/command/command.h"
 #include "src/tint/utils/containers/transform.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 #include "src/tint/utils/diagnostic/formatter.h"
 #include "src/tint/utils/macros/defer.h"
 #include "src/tint/utils/text/string.h"
@@ -637,7 +638,7 @@
     }
 }
 
-tint::Result<std::unordered_map<tint::OverrideId, double>> CreateOverrideMap(
+tint::diag::Result<std::unordered_map<tint::OverrideId, double>> CreateOverrideMap(
     Options& options,
     tint::inspector::Inspector& inspector) {
     auto override_names = inspector.GetNamedOverrideIds();
@@ -648,7 +649,7 @@
         const auto& override_name = override.key.Value();
         const auto& override_value = override.value;
         if (override_name.empty()) {
-            return tint::Failure("empty override name");
+            return tint::diag::Failure("empty override name");
         }
 
         auto num = tint::strconv::ParseNumber<decltype(tint::OverrideId::value)>(override_name);
@@ -660,7 +661,7 @@
 
         auto it = override_names.find(override_name);
         if (it == override_names.end()) {
-            return tint::Failure("unknown override '" + override_name + "'");
+            return tint::diag::Failure("unknown override '" + override_name + "'");
         }
         values.emplace(it->second, override_value);
     }
@@ -677,7 +678,7 @@
     transform_manager.Add<tint::ast::transform::SubstituteOverride>();
 }
 
-[[maybe_unused]] tint::Result<tint::Program> ProcessASTTransforms(
+[[maybe_unused]] tint::diag::Result<tint::Program> ProcessASTTransforms(
     Options& options,
     tint::inspector::Inspector& inspector,
     tint::Program& program,
@@ -712,7 +713,7 @@
         std::stringstream err;
         tint::cmd::PrintWGSL(err, transformed);
         err << transformed.Diagnostics() << "\n";
-        return tint::Failure(err.str());
+        return tint::diag::Failure(err.str());
     }
     return transformed;
 }
@@ -1104,7 +1105,7 @@
     gen_options.compiler = for_fxc ? tint::hlsl::writer::Options::Compiler::kFXC
                                    : tint::hlsl::writer::Options::Compiler::kDXC;
 
-    tint::Result<tint::hlsl::writer::Output> result;
+    tint::diag::Result<tint::hlsl::writer::Output> result;
     if (options.use_ir) {
         // Convert the AST program to an IR module.
         auto ir = tint::wgsl::reader::ProgramToLoweredIR(res.Get());
diff --git a/src/tint/cmd/tintd/BUILD.bazel b/src/tint/cmd/tintd/BUILD.bazel
index 80ddaa4..0b24014 100644
--- a/src/tint/cmd/tintd/BUILD.bazel
+++ b/src/tint/cmd/tintd/BUILD.bazel
@@ -42,15 +42,10 @@
     "main.cc",
   ],
   deps = [
-    "//src/tint/utils/containers",
-    "//src/tint/utils/diagnostic",
     "//src/tint/utils/ice",
     "//src/tint/utils/macros",
-    "//src/tint/utils/math",
-    "//src/tint/utils/memory",
     "//src/tint/utils/result",
     "//src/tint/utils/rtti",
-    "//src/tint/utils/text",
     "//src/utils",
   ] + select({
     ":tint_build_tintd": [
diff --git a/src/tint/cmd/tintd/BUILD.cmake b/src/tint/cmd/tintd/BUILD.cmake
index d1b96aa..1aec6c7 100644
--- a/src/tint/cmd/tintd/BUILD.cmake
+++ b/src/tint/cmd/tintd/BUILD.cmake
@@ -45,15 +45,10 @@
 )
 
 tint_target_add_dependencies(tint_cmd_tintd_cmd cmd
-  tint_utils_containers
-  tint_utils_diagnostic
   tint_utils_ice
   tint_utils_macros
-  tint_utils_math
-  tint_utils_memory
   tint_utils_result
   tint_utils_rtti
-  tint_utils_text
 )
 
 tint_target_add_external_dependencies(tint_cmd_tintd_cmd cmd
diff --git a/src/tint/cmd/tintd/BUILD.gn b/src/tint/cmd/tintd/BUILD.gn
index 1e0331d..01dd2bf 100644
--- a/src/tint/cmd/tintd/BUILD.gn
+++ b/src/tint/cmd/tintd/BUILD.gn
@@ -44,15 +44,10 @@
     sources = [ "main.cc" ]
     deps = [
       "${dawn_root}/src/utils:utils",
-      "${tint_src_dir}/utils/containers",
-      "${tint_src_dir}/utils/diagnostic",
       "${tint_src_dir}/utils/ice",
       "${tint_src_dir}/utils/macros",
-      "${tint_src_dir}/utils/math",
-      "${tint_src_dir}/utils/memory",
       "${tint_src_dir}/utils/result",
       "${tint_src_dir}/utils/rtti",
-      "${tint_src_dir}/utils/text",
     ]
 
     if (tint_build_tintd) {
diff --git a/src/tint/lang/core/constant/eval.cc b/src/tint/lang/core/constant/eval.cc
index ef47d50..b2c544b 100644
--- a/src/tint/lang/core/constant/eval.cc
+++ b/src/tint/lang/core/constant/eval.cc
@@ -28,9 +28,7 @@
 #include "src/tint/lang/core/constant/eval.h"
 
 #include <algorithm>
-#include <iomanip>
 #include <limits>
-#include <optional>
 #include <string>
 #include <type_traits>
 #include <utility>
diff --git a/src/tint/lang/core/constant/eval.h b/src/tint/lang/core/constant/eval.h
index 9efe390..17f9078 100644
--- a/src/tint/lang/core/constant/eval.h
+++ b/src/tint/lang/core/constant/eval.h
@@ -28,13 +28,9 @@
 #ifndef SRC_TINT_LANG_CORE_CONSTANT_EVAL_H_
 #define SRC_TINT_LANG_CORE_CONSTANT_EVAL_H_
 
-#include <stddef.h>
-#include <algorithm>
-#include <string>
-
-#include "src/tint/lang/core/number.h"
 #include "src/tint/lang/core/type/type.h"
 #include "src/tint/utils/containers/vector.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 #include "src/tint/utils/result/result.h"
 
 // Forward declarations
@@ -695,6 +691,7 @@
     /// @param args the input arguments
     /// @param source the source location
     /// @return the result value, or null if the value cannot be calculated
+    // NOLINTNEXTLINE(build/include_what_you_use) This isn't std::max ...
     Result max(const core::type::Type* ty, VectorRef<const Value*> args, const Source& source);
 
     /// min builtin
diff --git a/src/tint/lang/core/ir/binary/decode.cc b/src/tint/lang/core/ir/binary/decode.cc
index 6c43e04..4374d56 100644
--- a/src/tint/lang/core/ir/binary/decode.cc
+++ b/src/tint/lang/core/ir/binary/decode.cc
@@ -84,7 +84,7 @@
     diag::List diags_{};
     Hashset<std::string, 4> struct_names_{};
 
-    Result<Module> Decode() {
+    diag::Result<Module> Decode() {
         {
             const size_t n = static_cast<size_t>(mod_in_.types().size());
             types_.Reserve(n);
@@ -135,7 +135,7 @@
 
         if (diags_.ContainsErrors()) {
             // Note: Its not safe to call InferControlInstruction() with a broken IR.
-            return Failure{std::move(diags_)};
+            return diag::Failure{std::move(diags_)};
         }
 
         if (CheckBlocks()) {
@@ -160,7 +160,7 @@
         }
 
         if (diags_.ContainsErrors()) {
-            return Failure{std::move(diags_)};
+            return diag::Failure{std::move(diags_)};
         }
         return std::move(mod_out_);
     }
@@ -1807,18 +1807,18 @@
 
 }  // namespace
 
-Result<Module> Decode(Slice<const std::byte> encoded) {
+diag::Result<Module> Decode(Slice<const std::byte> encoded) {
     GOOGLE_PROTOBUF_VERIFY_VERSION;
 
     pb::Module mod_in;
     if (!mod_in.ParseFromArray(encoded.data, static_cast<int>(encoded.len))) {
-        return Failure{"failed to deserialize protobuf"};
+        return diag::Failure{"failed to deserialize protobuf"};
     }
 
     return Decode(mod_in);
 }
 
-Result<Module> Decode(const pb::Module& mod_in) {
+diag::Result<Module> Decode(const pb::Module& mod_in) {
     return Decoder{mod_in}.Decode();
 }
 
diff --git a/src/tint/lang/core/ir/binary/decode.h b/src/tint/lang/core/ir/binary/decode.h
index 3e1a3ed..fd25683 100644
--- a/src/tint/lang/core/ir/binary/decode.h
+++ b/src/tint/lang/core/ir/binary/decode.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_CORE_IR_BINARY_DECODE_H_
 #define SRC_TINT_LANG_CORE_IR_BINARY_DECODE_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations
 namespace tint::core::ir {
@@ -41,10 +41,10 @@
 namespace tint::core::ir::binary {
 
 /// @returns the decoded Module from the serialized protobuf.
-Result<Module> Decode(Slice<const std::byte> encoded);
+diag::Result<Module> Decode(Slice<const std::byte> encoded);
 
 /// @returns the decoded Module from the protobuf.
-Result<Module> Decode(const pb::Module& module);
+diag::Result<Module> Decode(const pb::Module& module);
 
 }  // namespace tint::core::ir::binary
 
diff --git a/src/tint/lang/core/ir/binary/encode.cc b/src/tint/lang/core/ir/binary/encode.cc
index d7efa63..945b032 100644
--- a/src/tint/lang/core/ir/binary/encode.cc
+++ b/src/tint/lang/core/ir/binary/encode.cc
@@ -106,7 +106,7 @@
 
     diag::List diags_{};
 
-    Result<SuccessType> Encode() {
+    diag::Result<SuccessType> Encode() {
         // Encode all user-declared structures first. This is to ensure that the IR disassembly
         // (which prints structure types first) does not reorder after encoding and decoding.
         for (auto* ty : mod_in_.Types()) {
@@ -126,7 +126,7 @@
         mod_out_.set_root_block(Block(mod_in_.root_block));
 
         if (diags_.ContainsErrors()) {
-            return Failure{std::move(diags_)};
+            return diag::Failure{std::move(diags_)};
         }
         return Success;
     }
@@ -1322,7 +1322,7 @@
 
 }  // namespace
 
-Result<std::unique_ptr<pb::Module>> EncodeToProto(const Module& mod_in) {
+diag::Result<std::unique_ptr<pb::Module>> EncodeToProto(const Module& mod_in) {
     GOOGLE_PROTOBUF_VERIFY_VERSION;
 
     pb::Module mod_out;
@@ -1334,7 +1334,7 @@
     return std::make_unique<pb::Module>(mod_out);
 }
 
-Result<Vector<std::byte, 0>> EncodeToBinary(const Module& mod_in) {
+diag::Result<Vector<std::byte, 0>> EncodeToBinary(const Module& mod_in) {
     auto mod_out = EncodeToProto(mod_in);
     if (mod_out != Success) {
         return mod_out.Failure();
@@ -1345,7 +1345,7 @@
     buffer.Resize(len);
     if (len > 0) {
         if (!mod_out.Get()->SerializeToArray(&buffer[0], static_cast<int>(len))) {
-            return Failure{"failed to serialize protobuf"};
+            return diag::Failure{"failed to serialize protobuf"};
         }
     }
     return buffer;
diff --git a/src/tint/lang/core/ir/binary/encode.h b/src/tint/lang/core/ir/binary/encode.h
index 82e94f6..529e3ae 100644
--- a/src/tint/lang/core/ir/binary/encode.h
+++ b/src/tint/lang/core/ir/binary/encode.h
@@ -29,10 +29,9 @@
 #define SRC_TINT_LANG_CORE_IR_BINARY_ENCODE_H_
 
 #include <memory>
-#include <string>
 
 #include "src/tint/utils/containers/vector.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations
 namespace tint::core::ir {
@@ -46,10 +45,10 @@
 namespace tint::core::ir::binary {
 
 // Encode the module into a proto representation.
-Result<std::unique_ptr<pb::Module>> EncodeToProto(const Module& module);
+diag::Result<std::unique_ptr<pb::Module>> EncodeToProto(const Module& module);
 
 // Encode the module into a binary representation.
-Result<Vector<std::byte, 0>> EncodeToBinary(const Module& module);
+diag::Result<Vector<std::byte, 0>> EncodeToBinary(const Module& module);
 
 }  // namespace tint::core::ir::binary
 
diff --git a/src/tint/lang/core/ir/binary/roundtrip_fuzz.cc b/src/tint/lang/core/ir/binary/roundtrip_fuzz.cc
index 7a233cf..f109e0b 100644
--- a/src/tint/lang/core/ir/binary/roundtrip_fuzz.cc
+++ b/src/tint/lang/core/ir/binary/roundtrip_fuzz.cc
@@ -34,14 +34,15 @@
 namespace tint::core::ir::binary {
 namespace {
 
-Result<SuccessType> IRBinaryRoundtripFuzzer(core::ir::Module& module, const fuzz::ir::Context&) {
+diag::Result<SuccessType> IRBinaryRoundtripFuzzer(core::ir::Module& module,
+                                                  const fuzz::ir::Context&) {
     auto encoded = EncodeToBinary(module);
     if (encoded != Success) {
         // Failing to encode, not ICE'ing, indicates that an internal limit to the IR binary
         // encoding/decoding logic was hit. Due to differences between the AST and IR
         // implementations, there exist corner cases where these internal limits are hit for IR,
         // but not AST.
-        return Failure{"Failed to encode module to binary"};
+        return diag::Failure{"Failed to encode module to binary"};
     }
 
     auto decoded = Decode(encoded->Slice());
diff --git a/src/tint/lang/core/ir/const_param_validator.cc b/src/tint/lang/core/ir/const_param_validator.cc
index ea6bc7e..f35d3db 100644
--- a/src/tint/lang/core/ir/const_param_validator.cc
+++ b/src/tint/lang/core/ir/const_param_validator.cc
@@ -65,7 +65,7 @@
 
     /// Runs the const param validator over the module provided during construction
     /// @returns success or failure
-    Result<SuccessType> Run();
+    diag::Result<SuccessType> Run();
 
     void CheckSubgroupCall(const CoreBuiltinCall* call);
     void CheckBuiltinCall(const BuiltinCall* call);
@@ -291,7 +291,7 @@
     }
 }
 
-Result<SuccessType> ConstParamValidator::Run() {
+diag::Result<SuccessType> ConstParamValidator::Run() {
     auto instructions = this->mod_.Instructions();
 
     for (auto inst : instructions) {
@@ -303,7 +303,7 @@
     }
 
     if (diagnostics_.ContainsErrors()) {
-        return Failure{std::move(diagnostics_)};
+        return diag::Failure{std::move(diagnostics_)};
     }
 
     return Success;
@@ -311,7 +311,7 @@
 
 }  // namespace
 
-Result<SuccessType> ValidateConstParam(Module& mod) {
+diag::Result<SuccessType> ValidateConstParam(Module& mod) {
     ConstParamValidator v(mod);
     auto ret = v.Run();
     return ret;
diff --git a/src/tint/lang/core/ir/const_param_validator.h b/src/tint/lang/core/ir/const_param_validator.h
index 3985c18..3c63a9f 100644
--- a/src/tint/lang/core/ir/const_param_validator.h
+++ b/src/tint/lang/core/ir/const_param_validator.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_CORE_IR_CONST_PARAM_VALIDATOR_H_
 #define SRC_TINT_LANG_CORE_IR_CONST_PARAM_VALIDATOR_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations
 namespace tint::core::ir {
@@ -40,7 +40,7 @@
 /// Validates the constant params for all instructions in the IR.
 /// @param mod the module to validate
 /// @returns success or failure
-Result<SuccessType> ValidateConstParam(Module& mod);
+diag::Result<SuccessType> ValidateConstParam(Module& mod);
 
 }  // namespace tint::core::ir
 
diff --git a/src/tint/lang/core/ir/evaluator.cc b/src/tint/lang/core/ir/evaluator.cc
index a6bc3fe..d491fab 100644
--- a/src/tint/lang/core/ir/evaluator.cc
+++ b/src/tint/lang/core/ir/evaluator.cc
@@ -32,18 +32,17 @@
 #include "src/tint/lang/core/ir/function_param.h"
 #include "src/tint/lang/core/ir/override.h"
 #include "src/tint/lang/core/number.h"
-#include "src/tint/lang/core/type/bool.h"
 #include "src/tint/lang/core/type/matrix.h"
 #include "src/tint/utils/rtti/switch.h"
 
 namespace tint::core::ir {
 namespace eval {
 
-Result<core::ir::Constant*> Eval(core::ir::Builder& b, core::ir::Instruction* inst) {
+diag::Result<core::ir::Constant*> Eval(core::ir::Builder& b, core::ir::Instruction* inst) {
     return Eval(b, inst->Result(0));
 }
 
-Result<core::ir::Constant*> Eval(core::ir::Builder& b, core::ir::Value* val) {
+diag::Result<core::ir::Constant*> Eval(core::ir::Builder& b, core::ir::Value* val) {
     ir::Evaluator e(b);
     return e.Evaluate(val);
 }
@@ -55,10 +54,10 @@
 
 Evaluator::~Evaluator() = default;
 
-Result<core::ir::Constant*> Evaluator::Evaluate(core::ir::Value* src) {
+diag::Result<core::ir::Constant*> Evaluator::Evaluate(core::ir::Value* src) {
     auto res = EvalValue(src);
     if (res != Success) {
-        return Failure(diagnostics_);
+        return diag::Failure(diagnostics_);
     }
     if (!res.Get()) {
         return nullptr;
diff --git a/src/tint/lang/core/ir/evaluator.h b/src/tint/lang/core/ir/evaluator.h
index 2f778e3..e8fe27a 100644
--- a/src/tint/lang/core/ir/evaluator.h
+++ b/src/tint/lang/core/ir/evaluator.h
@@ -53,7 +53,7 @@
     /// Evaluate the given `src` expression.
     /// @param src the source expression
     /// @returns the generated constant or a failure result.
-    Result<core::ir::Constant*> Evaluate(core::ir::Value* src);
+    diag::Result<core::ir::Constant*> Evaluate(core::ir::Value* src);
 
   private:
     using EvalResult = Result<const core::constant::Value*>;
@@ -84,13 +84,13 @@
 /// @param b the builder
 /// @param inst the instruction
 /// @returns the evaluated constant for `inst` or a `Failure` otherwise.
-Result<core::ir::Constant*> Eval(core::ir::Builder& b, core::ir::Instruction* inst);
+diag::Result<core::ir::Constant*> Eval(core::ir::Builder& b, core::ir::Instruction* inst);
 
 /// Evaluate the given `val` with the provided `b`.
 /// @param b the builder
 /// @param val the value
 /// @returns the evaluated constant for `val` or a `Failure` otherwise.
-Result<core::ir::Constant*> Eval(core::ir::Builder& b, core::ir::Value* val);
+diag::Result<core::ir::Constant*> Eval(core::ir::Builder& b, core::ir::Value* val);
 
 }  // namespace eval
 
diff --git a/src/tint/lang/core/ir/transform/add_empty_entry_point.cc b/src/tint/lang/core/ir/transform/add_empty_entry_point.cc
index 19f9fff..e9fc0a4 100644
--- a/src/tint/lang/core/ir/transform/add_empty_entry_point.cc
+++ b/src/tint/lang/core/ir/transform/add_empty_entry_point.cc
@@ -27,10 +27,7 @@
 
 #include "src/tint/lang/core/ir/transform/add_empty_entry_point.h"
 
-#include <utility>
-
 #include "src/tint/lang/core/ir/builder.h"
-#include "src/tint/lang/core/ir/constant.h"
 #include "src/tint/lang/core/ir/module.h"
 #include "src/tint/lang/core/ir/validator.h"
 
@@ -54,7 +51,7 @@
 
 }  // namespace
 
-Result<SuccessType> AddEmptyEntryPoint(Module& ir) {
+diag::Result<SuccessType> AddEmptyEntryPoint(Module& ir) {
     auto result =
         ValidateAndDumpIfNeeded(ir, "core.AddEmptyEntryPoint", kAddEmptyEntryPointCapabilities);
     if (result != Success) {
diff --git a/src/tint/lang/core/ir/transform/add_empty_entry_point.h b/src/tint/lang/core/ir/transform/add_empty_entry_point.h
index 46ca5ca..45d62ed 100644
--- a/src/tint/lang/core/ir/transform/add_empty_entry_point.h
+++ b/src/tint/lang/core/ir/transform/add_empty_entry_point.h
@@ -28,10 +28,8 @@
 #ifndef SRC_TINT_LANG_CORE_IR_TRANSFORM_ADD_EMPTY_ENTRY_POINT_H_
 #define SRC_TINT_LANG_CORE_IR_TRANSFORM_ADD_EMPTY_ENTRY_POINT_H_
 
-#include <string>
-
 #include "src/tint/lang/core/ir/validator.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -48,7 +46,7 @@
 /// Add an empty entry point to the module, if no other entry points exist.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> AddEmptyEntryPoint(Module& module);
+diag::Result<SuccessType> AddEmptyEntryPoint(Module& module);
 
 }  // namespace tint::core::ir::transform
 
diff --git a/src/tint/lang/core/ir/transform/add_empty_entry_point_fuzz.cc b/src/tint/lang/core/ir/transform/add_empty_entry_point_fuzz.cc
index a5836d3..d9d2ac6 100644
--- a/src/tint/lang/core/ir/transform/add_empty_entry_point_fuzz.cc
+++ b/src/tint/lang/core/ir/transform/add_empty_entry_point_fuzz.cc
@@ -33,7 +33,7 @@
 namespace tint::core::ir::transform {
 namespace {
 
-Result<SuccessType> AddEmptyEntryPointFuzzer(Module& ir, const fuzz::ir::Context&) {
+diag::Result<SuccessType> AddEmptyEntryPointFuzzer(Module& ir, const fuzz::ir::Context&) {
     return AddEmptyEntryPoint(ir);
 }
 
diff --git a/src/tint/lang/core/ir/transform/array_length_from_uniform.cc b/src/tint/lang/core/ir/transform/array_length_from_uniform.cc
index 63f4cb7..ba03146 100644
--- a/src/tint/lang/core/ir/transform/array_length_from_uniform.cc
+++ b/src/tint/lang/core/ir/transform/array_length_from_uniform.cc
@@ -231,7 +231,7 @@
 
 }  // namespace
 
-Result<ArrayLengthFromUniformResult> ArrayLengthFromUniform(
+diag::Result<ArrayLengthFromUniformResult> ArrayLengthFromUniform(
     Module& ir,
     BindingPoint ubo_binding,
     const std::unordered_map<BindingPoint, uint32_t>& bindpoint_to_size_index) {
diff --git a/src/tint/lang/core/ir/transform/array_length_from_uniform.h b/src/tint/lang/core/ir/transform/array_length_from_uniform.h
index 294997c..2977a96 100644
--- a/src/tint/lang/core/ir/transform/array_length_from_uniform.h
+++ b/src/tint/lang/core/ir/transform/array_length_from_uniform.h
@@ -31,7 +31,7 @@
 #include <unordered_map>
 
 #include "src/tint/api/common/binding_point.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -63,7 +63,7 @@
 /// @param ubo_binding the binding point to use for the uniform buffer
 /// @param bindpoint_to_size_index the map from binding point to an index which holds the size
 /// @returns the transform result or failure
-Result<ArrayLengthFromUniformResult> ArrayLengthFromUniform(
+diag::Result<ArrayLengthFromUniformResult> ArrayLengthFromUniform(
     Module& module,
     BindingPoint ubo_binding,
     const std::unordered_map<BindingPoint, uint32_t>& bindpoint_to_size_index);
diff --git a/src/tint/lang/core/ir/transform/array_length_from_uniform_fuzz.cc b/src/tint/lang/core/ir/transform/array_length_from_uniform_fuzz.cc
index 5f26884..2ca5bd9 100644
--- a/src/tint/lang/core/ir/transform/array_length_from_uniform_fuzz.cc
+++ b/src/tint/lang/core/ir/transform/array_length_from_uniform_fuzz.cc
@@ -35,7 +35,7 @@
 
 // Note: ArrayLengthFromUniform uses a different success type than the default SuccessType, so the
 // impl function cannot be passed in directly to fuzzing infra
-Result<SuccessType> ArrayLengthFromUniformFuzzer(
+diag::Result<SuccessType> ArrayLengthFromUniformFuzzer(
     Module& module,
     const fuzz::ir::Context&,
     BindingPoint ubo_binding,
diff --git a/src/tint/lang/core/ir/transform/bgra8unorm_polyfill.cc b/src/tint/lang/core/ir/transform/bgra8unorm_polyfill.cc
index e45b4e5..f91fa83 100644
--- a/src/tint/lang/core/ir/transform/bgra8unorm_polyfill.cc
+++ b/src/tint/lang/core/ir/transform/bgra8unorm_polyfill.cc
@@ -181,7 +181,7 @@
 
 }  // namespace
 
-Result<SuccessType> Bgra8UnormPolyfill(Module& ir) {
+diag::Result<SuccessType> Bgra8UnormPolyfill(Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "core.Bgra8UnormPolyfill");
     if (result != Success) {
         return result;
diff --git a/src/tint/lang/core/ir/transform/bgra8unorm_polyfill.h b/src/tint/lang/core/ir/transform/bgra8unorm_polyfill.h
index d427836..3fbcc12 100644
--- a/src/tint/lang/core/ir/transform/bgra8unorm_polyfill.h
+++ b/src/tint/lang/core/ir/transform/bgra8unorm_polyfill.h
@@ -28,9 +28,7 @@
 #ifndef SRC_TINT_LANG_CORE_IR_TRANSFORM_BGRA8UNORM_POLYFILL_H_
 #define SRC_TINT_LANG_CORE_IR_TRANSFORM_BGRA8UNORM_POLYFILL_H_
 
-#include <string>
-
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -43,7 +41,7 @@
 /// bgra8unorm to rgba8unorm, inserting swizzles before and after texture accesses as necessary.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> Bgra8UnormPolyfill(Module& module);
+diag::Result<SuccessType> Bgra8UnormPolyfill(Module& module);
 
 }  // namespace tint::core::ir::transform
 
diff --git a/src/tint/lang/core/ir/transform/bgra8unorm_polyfill_fuzz.cc b/src/tint/lang/core/ir/transform/bgra8unorm_polyfill_fuzz.cc
index d6252ad..98bc391 100644
--- a/src/tint/lang/core/ir/transform/bgra8unorm_polyfill_fuzz.cc
+++ b/src/tint/lang/core/ir/transform/bgra8unorm_polyfill_fuzz.cc
@@ -33,7 +33,7 @@
 namespace tint::core::ir::transform {
 namespace {
 
-Result<SuccessType> Bgra8UnormPolyfillFuzzer(Module& ir, const fuzz::ir::Context&) {
+diag::Result<SuccessType> Bgra8UnormPolyfillFuzzer(Module& ir, const fuzz::ir::Context&) {
     return Bgra8UnormPolyfill(ir);
 }
 
diff --git a/src/tint/lang/core/ir/transform/binary_polyfill.cc b/src/tint/lang/core/ir/transform/binary_polyfill.cc
index 4a2da27..541e0dc 100644
--- a/src/tint/lang/core/ir/transform/binary_polyfill.cc
+++ b/src/tint/lang/core/ir/transform/binary_polyfill.cc
@@ -200,7 +200,7 @@
 
 }  // namespace
 
-Result<SuccessType> BinaryPolyfill(Module& ir, const BinaryPolyfillConfig& config) {
+diag::Result<SuccessType> BinaryPolyfill(Module& ir, const BinaryPolyfillConfig& config) {
     auto result = ValidateAndDumpIfNeeded(ir, "core.BinaryPolyfill");
     if (result != Success) {
         return result;
diff --git a/src/tint/lang/core/ir/transform/binary_polyfill.h b/src/tint/lang/core/ir/transform/binary_polyfill.h
index c28e3bc..3cf87e2 100644
--- a/src/tint/lang/core/ir/transform/binary_polyfill.h
+++ b/src/tint/lang/core/ir/transform/binary_polyfill.h
@@ -28,10 +28,8 @@
 #ifndef SRC_TINT_LANG_CORE_IR_TRANSFORM_BINARY_POLYFILL_H_
 #define SRC_TINT_LANG_CORE_IR_TRANSFORM_BINARY_POLYFILL_H_
 
-#include <string>
-
+#include "src/tint/utils/diagnostic/diagnostic.h"
 #include "src/tint/utils/reflection.h"
-#include "src/tint/utils/result/result.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -56,7 +54,7 @@
 /// @param module the module to transform
 /// @param config the polyfill configuration
 /// @returns success or failure
-Result<SuccessType> BinaryPolyfill(Module& module, const BinaryPolyfillConfig& config);
+diag::Result<SuccessType> BinaryPolyfill(Module& module, const BinaryPolyfillConfig& config);
 
 }  // namespace tint::core::ir::transform
 
diff --git a/src/tint/lang/core/ir/transform/binary_polyfill_fuzz.cc b/src/tint/lang/core/ir/transform/binary_polyfill_fuzz.cc
index 666bde9..276d481 100644
--- a/src/tint/lang/core/ir/transform/binary_polyfill_fuzz.cc
+++ b/src/tint/lang/core/ir/transform/binary_polyfill_fuzz.cc
@@ -33,9 +33,9 @@
 namespace tint::core::ir::transform {
 namespace {
 
-Result<SuccessType> BinaryPolyfillFuzzer(Module& ir,
-                                         const fuzz::ir::Context&,
-                                         const BinaryPolyfillConfig& config) {
+diag::Result<SuccessType> BinaryPolyfillFuzzer(Module& ir,
+                                               const fuzz::ir::Context&,
+                                               const BinaryPolyfillConfig& config) {
     return BinaryPolyfill(ir, config);
 }
 
diff --git a/src/tint/lang/core/ir/transform/binding_remapper.cc b/src/tint/lang/core/ir/transform/binding_remapper.cc
index efa1e14..a020e5a 100644
--- a/src/tint/lang/core/ir/transform/binding_remapper.cc
+++ b/src/tint/lang/core/ir/transform/binding_remapper.cc
@@ -32,8 +32,6 @@
 #include "src/tint/lang/core/ir/module.h"
 #include "src/tint/lang/core/ir/validator.h"
 #include "src/tint/lang/core/ir/var.h"
-#include "src/tint/utils/result/result.h"
-#include "src/tint/utils/text/string.h"
 
 using namespace tint::core::number_suffixes;  // NOLINT
 
@@ -41,13 +39,12 @@
 
 namespace {
 
-Result<SuccessType> Run(ir::Module& ir,
-                        const std::unordered_map<BindingPoint, BindingPoint>& binding_points) {
+void Run(ir::Module& ir, const std::unordered_map<BindingPoint, BindingPoint>& binding_points) {
     if (binding_points.empty()) {
-        return Success;
+        return;
     }
     if (ir.root_block->IsEmpty()) {
-        return Success;
+        return;
     }
 
     // Find binding resources.
@@ -68,13 +65,11 @@
             var->SetBindingPoint(to->second.group, to->second.binding);
         }
     }
-
-    return Success;
 }
 
 }  // namespace
 
-Result<SuccessType> BindingRemapper(
+diag::Result<SuccessType> BindingRemapper(
     Module& ir,
     const std::unordered_map<BindingPoint, BindingPoint>& binding_points) {
     auto result = ValidateAndDumpIfNeeded(ir, "core.BindingRemapper");
@@ -82,7 +77,9 @@
         return result;
     }
 
-    return Run(ir, binding_points);
+    Run(ir, binding_points);
+
+    return Success;
 }
 
 }  // namespace tint::core::ir::transform
diff --git a/src/tint/lang/core/ir/transform/binding_remapper.h b/src/tint/lang/core/ir/transform/binding_remapper.h
index 6b656c8..e8b3ba0 100644
--- a/src/tint/lang/core/ir/transform/binding_remapper.h
+++ b/src/tint/lang/core/ir/transform/binding_remapper.h
@@ -28,11 +28,10 @@
 #ifndef SRC_TINT_LANG_CORE_IR_TRANSFORM_BINDING_REMAPPER_H_
 #define SRC_TINT_LANG_CORE_IR_TRANSFORM_BINDING_REMAPPER_H_
 
-#include <string>
 #include <unordered_map>
 
 #include "src/tint/api/common/binding_point.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -45,7 +44,7 @@
 /// @param module the module to transform
 /// @param binding_points the remapping data
 /// @returns success or failure
-Result<SuccessType> BindingRemapper(
+diag::Result<SuccessType> BindingRemapper(
     Module& module,
     const std::unordered_map<BindingPoint, BindingPoint>& binding_points);
 
diff --git a/src/tint/lang/core/ir/transform/binding_remapper_fuzz.cc b/src/tint/lang/core/ir/transform/binding_remapper_fuzz.cc
index d38cc04..3599e98 100644
--- a/src/tint/lang/core/ir/transform/binding_remapper_fuzz.cc
+++ b/src/tint/lang/core/ir/transform/binding_remapper_fuzz.cc
@@ -33,7 +33,7 @@
 namespace tint::core::ir::transform {
 namespace {
 
-Result<SuccessType> BindingRemapperFuzzer(
+diag::Result<SuccessType> BindingRemapperFuzzer(
     Module& ir,
     const fuzz::ir::Context&,
     const std::unordered_map<BindingPoint, BindingPoint>& binding_points) {
diff --git a/src/tint/lang/core/ir/transform/block_decorated_structs.cc b/src/tint/lang/core/ir/transform/block_decorated_structs.cc
index b565a7c..6186a59 100644
--- a/src/tint/lang/core/ir/transform/block_decorated_structs.cc
+++ b/src/tint/lang/core/ir/transform/block_decorated_structs.cc
@@ -27,8 +27,6 @@
 
 #include "src/tint/lang/core/ir/transform/block_decorated_structs.h"
 
-#include <utility>
-
 #include "src/tint/lang/core/ir/builder.h"
 #include "src/tint/lang/core/ir/module.h"
 #include "src/tint/lang/core/ir/validator.h"
@@ -119,7 +117,7 @@
 
 }  // namespace
 
-Result<SuccessType> BlockDecoratedStructs(Module& ir) {
+diag::Result<SuccessType> BlockDecoratedStructs(Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "core.BlockDecoratedStructs");
     if (result != Success) {
         return result;
diff --git a/src/tint/lang/core/ir/transform/block_decorated_structs.h b/src/tint/lang/core/ir/transform/block_decorated_structs.h
index bf2ed1e..063c34f 100644
--- a/src/tint/lang/core/ir/transform/block_decorated_structs.h
+++ b/src/tint/lang/core/ir/transform/block_decorated_structs.h
@@ -28,9 +28,7 @@
 #ifndef SRC_TINT_LANG_CORE_IR_TRANSFORM_BLOCK_DECORATED_STRUCTS_H_
 #define SRC_TINT_LANG_CORE_IR_TRANSFORM_BLOCK_DECORATED_STRUCTS_H_
 
-#include <string>
-
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -44,7 +42,7 @@
 /// existing store type in a new structure if necessary.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> BlockDecoratedStructs(Module& module);
+diag::Result<SuccessType> BlockDecoratedStructs(Module& module);
 
 }  // namespace tint::core::ir::transform
 
diff --git a/src/tint/lang/core/ir/transform/block_decorated_structs_fuzz.cc b/src/tint/lang/core/ir/transform/block_decorated_structs_fuzz.cc
index 93c5fde..6f31d31 100644
--- a/src/tint/lang/core/ir/transform/block_decorated_structs_fuzz.cc
+++ b/src/tint/lang/core/ir/transform/block_decorated_structs_fuzz.cc
@@ -33,7 +33,7 @@
 namespace tint::core::ir::transform {
 namespace {
 
-Result<SuccessType> BlockDecoratedStructsFuzzer(Module& ir, const fuzz::ir::Context&) {
+diag::Result<SuccessType> BlockDecoratedStructsFuzzer(Module& ir, const fuzz::ir::Context&) {
     return BlockDecoratedStructs(ir);
 }
 
diff --git a/src/tint/lang/core/ir/transform/builtin_polyfill.cc b/src/tint/lang/core/ir/transform/builtin_polyfill.cc
index c012a30..0437e7c 100644
--- a/src/tint/lang/core/ir/transform/builtin_polyfill.cc
+++ b/src/tint/lang/core/ir/transform/builtin_polyfill.cc
@@ -1144,7 +1144,7 @@
 
 }  // namespace
 
-Result<SuccessType> BuiltinPolyfill(Module& ir, const BuiltinPolyfillConfig& config) {
+diag::Result<SuccessType> BuiltinPolyfill(Module& ir, const BuiltinPolyfillConfig& config) {
     auto result = ValidateAndDumpIfNeeded(ir, "core.BuiltinPolyfill");
     if (result != Success) {
         return result;
diff --git a/src/tint/lang/core/ir/transform/builtin_polyfill.h b/src/tint/lang/core/ir/transform/builtin_polyfill.h
index 825b550..b82ade5 100644
--- a/src/tint/lang/core/ir/transform/builtin_polyfill.h
+++ b/src/tint/lang/core/ir/transform/builtin_polyfill.h
@@ -28,10 +28,8 @@
 #ifndef SRC_TINT_LANG_CORE_IR_TRANSFORM_BUILTIN_POLYFILL_H_
 #define SRC_TINT_LANG_CORE_IR_TRANSFORM_BUILTIN_POLYFILL_H_
 
-#include <string>
-
+#include "src/tint/utils/diagnostic/diagnostic.h"
 #include "src/tint/utils/reflection.h"
-#include "src/tint/utils/result/result.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -110,7 +108,7 @@
 /// @param module the module to transform
 /// @param config the polyfill configuration
 /// @returns success or failure
-Result<SuccessType> BuiltinPolyfill(Module& module, const BuiltinPolyfillConfig& config);
+diag::Result<SuccessType> BuiltinPolyfill(Module& module, const BuiltinPolyfillConfig& config);
 
 }  // namespace tint::core::ir::transform
 
diff --git a/src/tint/lang/core/ir/transform/builtin_polyfill_fuzz.cc b/src/tint/lang/core/ir/transform/builtin_polyfill_fuzz.cc
index b37d755..aedf5f9 100644
--- a/src/tint/lang/core/ir/transform/builtin_polyfill_fuzz.cc
+++ b/src/tint/lang/core/ir/transform/builtin_polyfill_fuzz.cc
@@ -33,9 +33,9 @@
 namespace tint::core::ir::transform {
 namespace {
 
-Result<SuccessType> BuiltinPolyfillFuzzer(Module& ir,
-                                          const fuzz::ir::Context&,
-                                          const BuiltinPolyfillConfig& config) {
+diag::Result<SuccessType> BuiltinPolyfillFuzzer(Module& ir,
+                                                const fuzz::ir::Context&,
+                                                const BuiltinPolyfillConfig& config) {
     return BuiltinPolyfill(ir, config);
 }
 
diff --git a/src/tint/lang/core/ir/transform/combine_access_instructions.cc b/src/tint/lang/core/ir/transform/combine_access_instructions.cc
index a65d04d..1e64860 100644
--- a/src/tint/lang/core/ir/transform/combine_access_instructions.cc
+++ b/src/tint/lang/core/ir/transform/combine_access_instructions.cc
@@ -79,7 +79,7 @@
 
 }  // namespace
 
-Result<SuccessType> CombineAccessInstructions(Module& ir) {
+diag::Result<SuccessType> CombineAccessInstructions(Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "core.CombineAccessInstructions");
     if (result != Success) {
         return result;
diff --git a/src/tint/lang/core/ir/transform/combine_access_instructions.h b/src/tint/lang/core/ir/transform/combine_access_instructions.h
index fda70bd..0cd0bc3 100644
--- a/src/tint/lang/core/ir/transform/combine_access_instructions.h
+++ b/src/tint/lang/core/ir/transform/combine_access_instructions.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_CORE_IR_TRANSFORM_COMBINE_ACCESS_INSTRUCTIONS_H_
 #define SRC_TINT_LANG_CORE_IR_TRANSFORM_COMBINE_ACCESS_INSTRUCTIONS_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -40,7 +40,7 @@
 /// CombineAccessInstructions is a transform that combines chains of access instructions.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> CombineAccessInstructions(Module& module);
+diag::Result<SuccessType> CombineAccessInstructions(Module& module);
 
 }  // namespace tint::core::ir::transform
 
diff --git a/src/tint/lang/core/ir/transform/combine_access_instructions_fuzz.cc b/src/tint/lang/core/ir/transform/combine_access_instructions_fuzz.cc
index 03ca62d..1b284ff 100644
--- a/src/tint/lang/core/ir/transform/combine_access_instructions_fuzz.cc
+++ b/src/tint/lang/core/ir/transform/combine_access_instructions_fuzz.cc
@@ -33,7 +33,7 @@
 namespace tint::core::ir::transform {
 namespace {
 
-Result<SuccessType> CombineAccessInstructionsFuzzer(Module& ir, const fuzz::ir::Context&) {
+diag::Result<SuccessType> CombineAccessInstructionsFuzzer(Module& ir, const fuzz::ir::Context&) {
     return CombineAccessInstructions(ir);
 }
 
diff --git a/src/tint/lang/core/ir/transform/conversion_polyfill.cc b/src/tint/lang/core/ir/transform/conversion_polyfill.cc
index becfdf9..3035c7a 100644
--- a/src/tint/lang/core/ir/transform/conversion_polyfill.cc
+++ b/src/tint/lang/core/ir/transform/conversion_polyfill.cc
@@ -188,7 +188,7 @@
 
 }  // namespace
 
-Result<SuccessType> ConversionPolyfill(Module& ir, const ConversionPolyfillConfig& config) {
+diag::Result<SuccessType> ConversionPolyfill(Module& ir, const ConversionPolyfillConfig& config) {
     auto result = ValidateAndDumpIfNeeded(ir, "core.ConversionPolyfill");
     if (result != Success) {
         return result;
diff --git a/src/tint/lang/core/ir/transform/conversion_polyfill.h b/src/tint/lang/core/ir/transform/conversion_polyfill.h
index dc33338..7311998 100644
--- a/src/tint/lang/core/ir/transform/conversion_polyfill.h
+++ b/src/tint/lang/core/ir/transform/conversion_polyfill.h
@@ -28,10 +28,8 @@
 #ifndef SRC_TINT_LANG_CORE_IR_TRANSFORM_CONVERSION_POLYFILL_H_
 #define SRC_TINT_LANG_CORE_IR_TRANSFORM_CONVERSION_POLYFILL_H_
 
-#include <string>
-
+#include "src/tint/utils/diagnostic/diagnostic.h"
 #include "src/tint/utils/reflection.h"
-#include "src/tint/utils/result/result.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -54,7 +52,8 @@
 /// @param module the module to transform
 /// @param config the polyfill configuration
 /// @returns success or failure
-Result<SuccessType> ConversionPolyfill(Module& module, const ConversionPolyfillConfig& config);
+diag::Result<SuccessType> ConversionPolyfill(Module& module,
+                                             const ConversionPolyfillConfig& config);
 
 }  // namespace tint::core::ir::transform
 
diff --git a/src/tint/lang/core/ir/transform/conversion_polyfill_fuzz.cc b/src/tint/lang/core/ir/transform/conversion_polyfill_fuzz.cc
index 0003daf..3777303 100644
--- a/src/tint/lang/core/ir/transform/conversion_polyfill_fuzz.cc
+++ b/src/tint/lang/core/ir/transform/conversion_polyfill_fuzz.cc
@@ -33,9 +33,9 @@
 namespace tint::core::ir::transform {
 namespace {
 
-Result<SuccessType> ConversionPolyfillFuzzer(Module& ir,
-                                             const fuzz::ir::Context&,
-                                             const ConversionPolyfillConfig& config) {
+diag::Result<SuccessType> ConversionPolyfillFuzzer(Module& ir,
+                                                   const fuzz::ir::Context&,
+                                                   const ConversionPolyfillConfig& config) {
     return ConversionPolyfill(ir, config);
 }
 
diff --git a/src/tint/lang/core/ir/transform/demote_to_helper.cc b/src/tint/lang/core/ir/transform/demote_to_helper.cc
index 24e2529..bbb130a 100644
--- a/src/tint/lang/core/ir/transform/demote_to_helper.cc
+++ b/src/tint/lang/core/ir/transform/demote_to_helper.cc
@@ -213,7 +213,7 @@
 
 }  // namespace
 
-Result<SuccessType> DemoteToHelper(Module& ir) {
+diag::Result<SuccessType> DemoteToHelper(Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "core.DemoteToHelper", kDemoteToHelperCapabilities);
     if (result != Success) {
         return result;
diff --git a/src/tint/lang/core/ir/transform/demote_to_helper.h b/src/tint/lang/core/ir/transform/demote_to_helper.h
index 8131d9d..9d71f30 100644
--- a/src/tint/lang/core/ir/transform/demote_to_helper.h
+++ b/src/tint/lang/core/ir/transform/demote_to_helper.h
@@ -28,10 +28,8 @@
 #ifndef SRC_TINT_LANG_CORE_IR_TRANSFORM_DEMOTE_TO_HELPER_H_
 #define SRC_TINT_LANG_CORE_IR_TRANSFORM_DEMOTE_TO_HELPER_H_
 
-#include <string>
-
 #include "src/tint/lang/core/ir/validator.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -54,7 +52,7 @@
 /// buffers and textures.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> DemoteToHelper(Module& module);
+diag::Result<SuccessType> DemoteToHelper(Module& module);
 
 }  // namespace tint::core::ir::transform
 
diff --git a/src/tint/lang/core/ir/transform/demote_to_helper_fuzz.cc b/src/tint/lang/core/ir/transform/demote_to_helper_fuzz.cc
index 98975c9..c4aedc1 100644
--- a/src/tint/lang/core/ir/transform/demote_to_helper_fuzz.cc
+++ b/src/tint/lang/core/ir/transform/demote_to_helper_fuzz.cc
@@ -33,7 +33,7 @@
 namespace tint::core::ir::transform {
 namespace {
 
-Result<SuccessType> DemoteToHelperFuzzer(Module& ir, const fuzz::ir::Context&) {
+diag::Result<SuccessType> DemoteToHelperFuzzer(Module& ir, const fuzz::ir::Context&) {
     return DemoteToHelper(ir);
 }
 
diff --git a/src/tint/lang/core/ir/transform/direct_variable_access.cc b/src/tint/lang/core/ir/transform/direct_variable_access.cc
index b5917e3..41f42ec 100644
--- a/src/tint/lang/core/ir/transform/direct_variable_access.cc
+++ b/src/tint/lang/core/ir/transform/direct_variable_access.cc
@@ -703,7 +703,8 @@
 
 }  // namespace
 
-Result<SuccessType> DirectVariableAccess(Module& ir, const DirectVariableAccessOptions& options) {
+diag::Result<SuccessType> DirectVariableAccess(Module& ir,
+                                               const DirectVariableAccessOptions& options) {
     auto result =
         ValidateAndDumpIfNeeded(ir, "core.DirectVariableAccess", kDirectVariableAccessCapabilities);
     if (result != Success) {
diff --git a/src/tint/lang/core/ir/transform/direct_variable_access.h b/src/tint/lang/core/ir/transform/direct_variable_access.h
index 5447c24..af321cf 100644
--- a/src/tint/lang/core/ir/transform/direct_variable_access.h
+++ b/src/tint/lang/core/ir/transform/direct_variable_access.h
@@ -29,8 +29,8 @@
 #define SRC_TINT_LANG_CORE_IR_TRANSFORM_DIRECT_VARIABLE_ACCESS_H_
 
 #include "src/tint/lang/core/ir/validator.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 #include "src/tint/utils/reflection.h"
-#include "src/tint/utils/result/result.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -71,8 +71,8 @@
 /// @param module the module to transform
 /// @param options the options
 /// @returns error diagnostics on failure
-Result<SuccessType> DirectVariableAccess(Module& module,
-                                         const DirectVariableAccessOptions& options);
+diag::Result<SuccessType> DirectVariableAccess(Module& module,
+                                               const DirectVariableAccessOptions& options);
 
 }  // namespace tint::core::ir::transform
 
diff --git a/src/tint/lang/core/ir/transform/direct_variable_access_fuzz.cc b/src/tint/lang/core/ir/transform/direct_variable_access_fuzz.cc
index 4e53c3b..cb165a7 100644
--- a/src/tint/lang/core/ir/transform/direct_variable_access_fuzz.cc
+++ b/src/tint/lang/core/ir/transform/direct_variable_access_fuzz.cc
@@ -33,9 +33,9 @@
 namespace tint::core::ir::transform {
 namespace {
 
-Result<SuccessType> DirectVariableAccessFuzzer(Module& ir,
-                                               const fuzz::ir::Context&,
-                                               const DirectVariableAccessOptions& options) {
+diag::Result<SuccessType> DirectVariableAccessFuzzer(Module& ir,
+                                                     const fuzz::ir::Context&,
+                                                     const DirectVariableAccessOptions& options) {
     return DirectVariableAccess(ir, options);
 }
 
diff --git a/src/tint/lang/core/ir/transform/helper_test.h b/src/tint/lang/core/ir/transform/helper_test.h
index 1103791..64319de 100644
--- a/src/tint/lang/core/ir/transform/helper_test.h
+++ b/src/tint/lang/core/ir/transform/helper_test.h
@@ -28,16 +28,13 @@
 #ifndef SRC_TINT_LANG_CORE_IR_TRANSFORM_HELPER_TEST_H_
 #define SRC_TINT_LANG_CORE_IR_TRANSFORM_HELPER_TEST_H_
 
-#include <memory>
 #include <string>
 #include <utility>
-#include <vector>
 
 #include "gtest/gtest.h"
 #include "src/tint/lang/core/ir/builder.h"
 #include "src/tint/lang/core/ir/disassembler.h"
 #include "src/tint/lang/core/ir/validator.h"
-#include "src/tint/utils/containers/enum_set.h"
 
 namespace tint::core::ir::transform {
 
@@ -65,7 +62,7 @@
     /// @param transform_func the transform to run
     /// @param args the arguments to the transform function
     template <typename TRANSFORM, typename... ARGS>
-    Result<SuccessType> RunWithFailure(TRANSFORM&& transform_func, ARGS&&... args) {
+    diag::Result<SuccessType> RunWithFailure(TRANSFORM&& transform_func, ARGS&&... args) {
         return transform_func(mod, std::forward<ARGS>(args)...);
     }
 
diff --git a/src/tint/lang/core/ir/transform/multiplanar_external_texture.cc b/src/tint/lang/core/ir/transform/multiplanar_external_texture.cc
index d8fa81c..940875b 100644
--- a/src/tint/lang/core/ir/transform/multiplanar_external_texture.cc
+++ b/src/tint/lang/core/ir/transform/multiplanar_external_texture.cc
@@ -76,7 +76,7 @@
     Function* gamma_correction = nullptr;
 
     /// Process the module.
-    Result<SuccessType> Process() {
+    diag::Result<SuccessType> Process() {
         // Find module-scope variables that need to be replaced.
         if (!ir.root_block->IsEmpty()) {
             Vector<Instruction*, 4> to_remove;
@@ -119,14 +119,14 @@
 
     /// Replace an external texture variable declaration.
     /// @param old_var the variable declaration to replace
-    Result<SuccessType> ReplaceVar(Var* old_var) {
+    diag::Result<SuccessType> ReplaceVar(Var* old_var) {
         auto name = ir.NameOf(old_var);
         auto bp = old_var->BindingPoint();
         auto itr = multiplanar_map.find(bp.value());
         if (DAWN_UNLIKELY(itr == multiplanar_map.end())) {
             std::stringstream err;
             err << "ExternalTextureOptions missing binding entry for " << bp.value();
-            return Failure{err.str()};
+            return diag::Failure{err.str()};
         }
         const auto& new_binding_points = itr->second;
 
@@ -607,7 +607,7 @@
 
 }  // namespace
 
-Result<SuccessType> MultiplanarExternalTexture(
+diag::Result<SuccessType> MultiplanarExternalTexture(
     Module& ir,
     const tint::transform::multiplanar::BindingsMap& multiplanar_map) {
     auto result = ValidateAndDumpIfNeeded(ir, "core.MultiplanarExternalTexture");
diff --git a/src/tint/lang/core/ir/transform/multiplanar_external_texture.h b/src/tint/lang/core/ir/transform/multiplanar_external_texture.h
index da99f8f..5c370b1 100644
--- a/src/tint/lang/core/ir/transform/multiplanar_external_texture.h
+++ b/src/tint/lang/core/ir/transform/multiplanar_external_texture.h
@@ -28,11 +28,8 @@
 #ifndef SRC_TINT_LANG_CORE_IR_TRANSFORM_MULTIPLANAR_EXTERNAL_TEXTURE_H_
 #define SRC_TINT_LANG_CORE_IR_TRANSFORM_MULTIPLANAR_EXTERNAL_TEXTURE_H_
 
-#include <string>
-
-#include "src/tint/api/common/binding_point.h"
 #include "src/tint/lang/core/common/multiplanar_options.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -47,7 +44,7 @@
 /// @param module the module to transform
 /// @param options the external texture options
 /// @returns success or failure
-Result<SuccessType> MultiplanarExternalTexture(
+diag::Result<SuccessType> MultiplanarExternalTexture(
     Module& module,
     const tint::transform::multiplanar::BindingsMap& options);
 
diff --git a/src/tint/lang/core/ir/transform/multiplanar_external_texture_fuzz.cc b/src/tint/lang/core/ir/transform/multiplanar_external_texture_fuzz.cc
index b8e7b0d..2a2f62f 100644
--- a/src/tint/lang/core/ir/transform/multiplanar_external_texture_fuzz.cc
+++ b/src/tint/lang/core/ir/transform/multiplanar_external_texture_fuzz.cc
@@ -33,7 +33,7 @@
 namespace tint::core::ir::transform {
 namespace {
 
-Result<SuccessType> MultiplanarExternalTextureFuzzer(
+diag::Result<SuccessType> MultiplanarExternalTextureFuzzer(
     Module& ir,
     const fuzz::ir::Context&,
     const tint::transform::multiplanar::BindingsMap& multiplanar_map) {
diff --git a/src/tint/lang/core/ir/transform/prepare_push_constants.cc b/src/tint/lang/core/ir/transform/prepare_push_constants.cc
index b3f64b5..3afb6db 100644
--- a/src/tint/lang/core/ir/transform/prepare_push_constants.cc
+++ b/src/tint/lang/core/ir/transform/prepare_push_constants.cc
@@ -53,7 +53,7 @@
     /// The type manager.
     core::type::Manager& ty{ir.Types()};
 
-    Result<PushConstantLayout> Run() {
+    PushConstantLayout Run() {
         if (config.internal_constants.empty()) {
             return PushConstantLayout{};
         }
@@ -127,8 +127,8 @@
 
 }  // namespace
 
-Result<PushConstantLayout> PreparePushConstants(Module& ir,
-                                                const PreparePushConstantsConfig& config) {
+diag::Result<PushConstantLayout> PreparePushConstants(Module& ir,
+                                                      const PreparePushConstantsConfig& config) {
     auto result = ValidateAndDumpIfNeeded(ir, "core.PreparePushConstants");
     if (result != Success) {
         return result.Failure();
diff --git a/src/tint/lang/core/ir/transform/prepare_push_constants.h b/src/tint/lang/core/ir/transform/prepare_push_constants.h
index bf043b5..10e998b 100644
--- a/src/tint/lang/core/ir/transform/prepare_push_constants.h
+++ b/src/tint/lang/core/ir/transform/prepare_push_constants.h
@@ -87,8 +87,8 @@
 /// @param module the module to transform
 /// @param config the transform config
 /// @returns the generated push constant layout or failure
-Result<PushConstantLayout> PreparePushConstants(Module& module,
-                                                const PreparePushConstantsConfig& config);
+diag::Result<PushConstantLayout> PreparePushConstants(Module& module,
+                                                      const PreparePushConstantsConfig& config);
 
 }  // namespace tint::core::ir::transform
 
diff --git a/src/tint/lang/core/ir/transform/prepare_push_constants_test.cc b/src/tint/lang/core/ir/transform/prepare_push_constants_test.cc
index 0bc8974..cf1eca0 100644
--- a/src/tint/lang/core/ir/transform/prepare_push_constants_test.cc
+++ b/src/tint/lang/core/ir/transform/prepare_push_constants_test.cc
@@ -27,8 +27,6 @@
 
 #include "src/tint/lang/core/ir/transform/prepare_push_constants.h"
 
-#include <utility>
-
 #include "src/tint/lang/core/ir/transform/helper_test.h"
 
 namespace tint::core::ir::transform {
@@ -39,7 +37,7 @@
 
 class IR_PreparePushConstantsTests : public TransformTest {
   public:
-    Result<PushConstantLayout> Run(PreparePushConstantsConfig config) {
+    diag::Result<PushConstantLayout> Run(PreparePushConstantsConfig config) {
         // Run the transform.
         auto result = PreparePushConstants(mod, config);
         EXPECT_EQ(result, Success);
diff --git a/src/tint/lang/core/ir/transform/preserve_padding.cc b/src/tint/lang/core/ir/transform/preserve_padding.cc
index 82b5896..9966009 100644
--- a/src/tint/lang/core/ir/transform/preserve_padding.cc
+++ b/src/tint/lang/core/ir/transform/preserve_padding.cc
@@ -27,8 +27,6 @@
 
 #include "src/tint/lang/core/ir/transform/preserve_padding.h"
 
-#include <utility>
-
 #include "src/tint/lang/core/ir/builder.h"
 #include "src/tint/lang/core/ir/module.h"
 #include "src/tint/lang/core/ir/validator.h"
@@ -172,7 +170,7 @@
 
 }  // namespace
 
-Result<SuccessType> PreservePadding(Module& ir) {
+diag::Result<SuccessType> PreservePadding(Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "core.PreservePadding", kPreservePaddingCapabilities);
     if (result != Success) {
         return result;
diff --git a/src/tint/lang/core/ir/transform/preserve_padding.h b/src/tint/lang/core/ir/transform/preserve_padding.h
index ba135cf..3d0d9ad 100644
--- a/src/tint/lang/core/ir/transform/preserve_padding.h
+++ b/src/tint/lang/core/ir/transform/preserve_padding.h
@@ -29,7 +29,7 @@
 #define SRC_TINT_LANG_CORE_IR_TRANSFORM_PRESERVE_PADDING_H_
 
 #include "src/tint/lang/core/ir/validator.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -49,7 +49,7 @@
 /// @note assumes that DirectVariableAccess will be run afterwards for backends that need it.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> PreservePadding(Module& module);
+diag::Result<SuccessType> PreservePadding(Module& module);
 
 }  // namespace tint::core::ir::transform
 
diff --git a/src/tint/lang/core/ir/transform/preserve_padding_fuzz.cc b/src/tint/lang/core/ir/transform/preserve_padding_fuzz.cc
index 741f4f1..7a7b8fc 100644
--- a/src/tint/lang/core/ir/transform/preserve_padding_fuzz.cc
+++ b/src/tint/lang/core/ir/transform/preserve_padding_fuzz.cc
@@ -33,7 +33,7 @@
 namespace tint::core::ir::transform {
 namespace {
 
-Result<SuccessType> PreservePaddingFuzzer(Module& ir, const fuzz::ir::Context&) {
+diag::Result<SuccessType> PreservePaddingFuzzer(Module& ir, const fuzz::ir::Context&) {
     return PreservePadding(ir);
 }
 
diff --git a/src/tint/lang/core/ir/transform/prevent_infinite_loops.cc b/src/tint/lang/core/ir/transform/prevent_infinite_loops.cc
index fb3d62c..539ec1e 100644
--- a/src/tint/lang/core/ir/transform/prevent_infinite_loops.cc
+++ b/src/tint/lang/core/ir/transform/prevent_infinite_loops.cc
@@ -34,7 +34,6 @@
 #include "src/tint/lang/core/ir/module.h"
 #include "src/tint/lang/core/ir/traverse.h"
 #include "src/tint/lang/core/ir/validator.h"
-#include "src/tint/utils/ice/ice.h"
 
 using namespace tint::core::fluent_types;     // NOLINT
 using namespace tint::core::number_suffixes;  // NOLINT
@@ -116,7 +115,7 @@
 
 }  // namespace
 
-Result<SuccessType> PreventInfiniteLoops(Module& ir) {
+diag::Result<SuccessType> PreventInfiniteLoops(Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "core.PreventInfiniteLoops");
     if (result != Success) {
         return result;
diff --git a/src/tint/lang/core/ir/transform/prevent_infinite_loops.h b/src/tint/lang/core/ir/transform/prevent_infinite_loops.h
index 0481439..e69b0e7 100644
--- a/src/tint/lang/core/ir/transform/prevent_infinite_loops.h
+++ b/src/tint/lang/core/ir/transform/prevent_infinite_loops.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_CORE_IR_TRANSFORM_PREVENT_INFINITE_LOOPS_H_
 #define SRC_TINT_LANG_CORE_IR_TRANSFORM_PREVENT_INFINITE_LOOPS_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -43,7 +43,7 @@
 ///
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> PreventInfiniteLoops(Module& module);
+diag::Result<SuccessType> PreventInfiniteLoops(Module& module);
 
 }  // namespace tint::core::ir::transform
 
diff --git a/src/tint/lang/core/ir/transform/remove_continue_in_switch.cc b/src/tint/lang/core/ir/transform/remove_continue_in_switch.cc
index 997a9e1..3d82fc5 100644
--- a/src/tint/lang/core/ir/transform/remove_continue_in_switch.cc
+++ b/src/tint/lang/core/ir/transform/remove_continue_in_switch.cc
@@ -30,7 +30,6 @@
 #include "src/tint/lang/core/ir/builder.h"
 #include "src/tint/lang/core/ir/module.h"
 #include "src/tint/lang/core/ir/validator.h"
-#include "src/tint/utils/ice/ice.h"
 
 using namespace tint::core::fluent_types;     // NOLINT
 using namespace tint::core::number_suffixes;  // NOLINT
@@ -113,7 +112,7 @@
 
 }  // namespace
 
-Result<SuccessType> RemoveContinueInSwitch(Module& ir) {
+diag::Result<SuccessType> RemoveContinueInSwitch(Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "core.RemoveContinueInSwitch",
                                           core::ir::Capabilities{
                                               core::ir::Capability::kAllowVectorElementPointer,
diff --git a/src/tint/lang/core/ir/transform/remove_continue_in_switch.h b/src/tint/lang/core/ir/transform/remove_continue_in_switch.h
index ff12e61..dfa103c 100644
--- a/src/tint/lang/core/ir/transform/remove_continue_in_switch.h
+++ b/src/tint/lang/core/ir/transform/remove_continue_in_switch.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_CORE_IR_TRANSFORM_REMOVE_CONTINUE_IN_SWITCH_H_
 #define SRC_TINT_LANG_CORE_IR_TRANSFORM_REMOVE_CONTINUE_IN_SWITCH_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -45,7 +45,7 @@
 /// the loop.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> RemoveContinueInSwitch(Module& module);
+diag::Result<SuccessType> RemoveContinueInSwitch(Module& module);
 
 }  // namespace tint::core::ir::transform
 
diff --git a/src/tint/lang/core/ir/transform/remove_terminator_args.cc b/src/tint/lang/core/ir/transform/remove_terminator_args.cc
index 2e92362..709568c 100644
--- a/src/tint/lang/core/ir/transform/remove_terminator_args.cc
+++ b/src/tint/lang/core/ir/transform/remove_terminator_args.cc
@@ -27,8 +27,6 @@
 
 #include "src/tint/lang/core/ir/transform/remove_terminator_args.h"
 
-#include <utility>
-
 #include "src/tint/lang/core/ir/builder.h"
 #include "src/tint/lang/core/ir/module.h"
 #include "src/tint/lang/core/ir/validator.h"
@@ -163,7 +161,7 @@
 
 }  // namespace
 
-Result<SuccessType> RemoveTerminatorArgs(Module& ir) {
+diag::Result<SuccessType> RemoveTerminatorArgs(Module& ir) {
     auto result =
         ValidateAndDumpIfNeeded(ir, "core.RemoveTerminatorArgs", kRemoveTerminatorArgsCapabilities);
     if (result != Success) {
diff --git a/src/tint/lang/core/ir/transform/remove_terminator_args.h b/src/tint/lang/core/ir/transform/remove_terminator_args.h
index 77e06ec..e6b1760 100644
--- a/src/tint/lang/core/ir/transform/remove_terminator_args.h
+++ b/src/tint/lang/core/ir/transform/remove_terminator_args.h
@@ -29,7 +29,7 @@
 #define SRC_TINT_LANG_CORE_IR_TRANSFORM_REMOVE_TERMINATOR_ARGS_H_
 
 #include "src/tint/lang/core/ir/validator.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -56,7 +56,7 @@
 /// textual languages.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> RemoveTerminatorArgs(Module& module);
+diag::Result<SuccessType> RemoveTerminatorArgs(Module& module);
 
 }  // namespace tint::core::ir::transform
 
diff --git a/src/tint/lang/core/ir/transform/remove_terminator_args_fuzz.cc b/src/tint/lang/core/ir/transform/remove_terminator_args_fuzz.cc
index 3bb6a7f..6df6ae1 100644
--- a/src/tint/lang/core/ir/transform/remove_terminator_args_fuzz.cc
+++ b/src/tint/lang/core/ir/transform/remove_terminator_args_fuzz.cc
@@ -33,7 +33,7 @@
 namespace tint::core::ir::transform {
 namespace {
 
-Result<SuccessType> RemoveTerminatorArgsFuzzer(Module& ir, const fuzz::ir::Context&) {
+diag::Result<SuccessType> RemoveTerminatorArgsFuzzer(Module& ir, const fuzz::ir::Context&) {
     return RemoveTerminatorArgs(ir);
 }
 
diff --git a/src/tint/lang/core/ir/transform/rename_conflicts.cc b/src/tint/lang/core/ir/transform/rename_conflicts.cc
index bfdca3e..ebb0d66 100644
--- a/src/tint/lang/core/ir/transform/rename_conflicts.cc
+++ b/src/tint/lang/core/ir/transform/rename_conflicts.cc
@@ -26,8 +26,7 @@
 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#include <variant>
-
+#include "src/tint/lang/core/ir/transform/rename_conflicts.h"
 #include "src/tint/lang/core/ir/construct.h"
 #include "src/tint/lang/core/ir/control_instruction.h"
 #include "src/tint/lang/core/ir/core_builtin_call.h"
@@ -37,7 +36,6 @@
 #include "src/tint/lang/core/ir/loop.h"
 #include "src/tint/lang/core/ir/module.h"
 #include "src/tint/lang/core/ir/multi_in_block.h"
-#include "src/tint/lang/core/ir/transform/rename_conflicts.h"
 #include "src/tint/lang/core/ir/validator.h"
 #include "src/tint/lang/core/ir/var.h"
 #include "src/tint/lang/core/type/array.h"
@@ -46,9 +44,8 @@
 #include "src/tint/lang/core/type/scalar.h"
 #include "src/tint/lang/core/type/struct.h"
 #include "src/tint/lang/core/type/vector.h"
-#include "src/tint/utils/containers/hashset.h"
+#include "src/tint/utils/containers/hashmap.h"
 #include "src/tint/utils/containers/reverse.h"
-#include "src/tint/utils/containers/scope_stack.h"
 #include "src/tint/utils/macros/defer.h"
 #include "src/tint/utils/rtti/switch.h"
 #include "src/tint/utils/text/string.h"
@@ -297,7 +294,7 @@
 
 }  // namespace
 
-Result<SuccessType> RenameConflicts(core::ir::Module& ir) {
+diag::Result<SuccessType> RenameConflicts(core::ir::Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "core.RenameConflicts", kRenameConflictsCapabilities);
     if (result != Success) {
         return result;
diff --git a/src/tint/lang/core/ir/transform/rename_conflicts.h b/src/tint/lang/core/ir/transform/rename_conflicts.h
index f4b3337..4eb4f8f 100644
--- a/src/tint/lang/core/ir/transform/rename_conflicts.h
+++ b/src/tint/lang/core/ir/transform/rename_conflicts.h
@@ -29,7 +29,7 @@
 #define SRC_TINT_LANG_CORE_IR_TRANSFORM_RENAME_CONFLICTS_H_
 
 #include "src/tint/lang/core/ir/validator.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -56,7 +56,7 @@
 /// scope or a parent scope.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> RenameConflicts(core::ir::Module& module);
+diag::Result<SuccessType> RenameConflicts(core::ir::Module& module);
 
 }  // namespace tint::core::ir::transform
 
diff --git a/src/tint/lang/core/ir/transform/rename_conflicts_fuzz.cc b/src/tint/lang/core/ir/transform/rename_conflicts_fuzz.cc
index 84a6f70..dbf5132 100644
--- a/src/tint/lang/core/ir/transform/rename_conflicts_fuzz.cc
+++ b/src/tint/lang/core/ir/transform/rename_conflicts_fuzz.cc
@@ -33,7 +33,7 @@
 namespace tint::core::ir::transform {
 namespace {
 
-Result<SuccessType> RenameConflictsFuzzer(Module& ir, const fuzz::ir::Context&) {
+diag::Result<SuccessType> RenameConflictsFuzzer(Module& ir, const fuzz::ir::Context&) {
     return RenameConflicts(ir);
 }
 
diff --git a/src/tint/lang/core/ir/transform/robustness.cc b/src/tint/lang/core/ir/transform/robustness.cc
index b9dd071..678fa43 100644
--- a/src/tint/lang/core/ir/transform/robustness.cc
+++ b/src/tint/lang/core/ir/transform/robustness.cc
@@ -380,7 +380,7 @@
 
 }  // namespace
 
-Result<SuccessType> Robustness(Module& ir, const RobustnessConfig& config) {
+diag::Result<SuccessType> Robustness(Module& ir, const RobustnessConfig& config) {
     auto result = ValidateAndDumpIfNeeded(ir, "core.Robustness");
     if (result != Success) {
         return result;
diff --git a/src/tint/lang/core/ir/transform/robustness.h b/src/tint/lang/core/ir/transform/robustness.h
index 90149a9..02fd488 100644
--- a/src/tint/lang/core/ir/transform/robustness.h
+++ b/src/tint/lang/core/ir/transform/robustness.h
@@ -28,12 +28,11 @@
 #ifndef SRC_TINT_LANG_CORE_IR_TRANSFORM_ROBUSTNESS_H_
 #define SRC_TINT_LANG_CORE_IR_TRANSFORM_ROBUSTNESS_H_
 
-#include <string>
 #include <unordered_set>
 
 #include "src/tint/api/common/binding_point.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 #include "src/tint/utils/reflection.h"
-#include "src/tint/utils/result/result.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -87,7 +86,7 @@
 /// @param module the module to transform
 /// @param config the robustness configuration
 /// @returns success or failure
-Result<SuccessType> Robustness(Module& module, const RobustnessConfig& config);
+diag::Result<SuccessType> Robustness(Module& module, const RobustnessConfig& config);
 
 }  // namespace tint::core::ir::transform
 
diff --git a/src/tint/lang/core/ir/transform/robustness_fuzz.cc b/src/tint/lang/core/ir/transform/robustness_fuzz.cc
index d0f894a..193910c 100644
--- a/src/tint/lang/core/ir/transform/robustness_fuzz.cc
+++ b/src/tint/lang/core/ir/transform/robustness_fuzz.cc
@@ -33,12 +33,12 @@
 namespace tint::core::ir::transform {
 namespace {
 
-Result<SuccessType> RobustnessFuzzer(Module& module,
-                                     const fuzz::ir::Context&,
-                                     RobustnessConfig config) {
+diag::Result<SuccessType> RobustnessFuzzer(Module& module,
+                                           const fuzz::ir::Context&,
+                                           RobustnessConfig config) {
     if (!config.bindings_ignored.empty()) {
         // TODO(jrprice): Handle config.bindings_ignored.
-        return Failure{"config.bindings_ignored is not empty"};
+        return diag::Failure{"config.bindings_ignored is not empty"};
     }
 
     return Robustness(module, config);
diff --git a/src/tint/lang/core/ir/transform/single_entry_point.cc b/src/tint/lang/core/ir/transform/single_entry_point.cc
index a471a9b..e96ac4b 100644
--- a/src/tint/lang/core/ir/transform/single_entry_point.cc
+++ b/src/tint/lang/core/ir/transform/single_entry_point.cc
@@ -27,8 +27,6 @@
 
 #include "src/tint/lang/core/ir/transform/single_entry_point.h"
 
-#include <utility>
-
 #include "src/tint/lang/core/ir/block.h"
 #include "src/tint/lang/core/ir/instruction_result.h"
 #include "src/tint/lang/core/ir/module.h"
@@ -40,7 +38,7 @@
 
 namespace {
 
-Result<SuccessType> Run(ir::Module& ir, std::string_view entry_point_name) {
+void Run(ir::Module& ir, std::string_view entry_point_name) {
     // Find the entry point.
     ir::Function* entry_point = nullptr;
     for (auto& func : ir.functions) {
@@ -92,20 +90,20 @@
         }
         inst = prev;
     }
-
-    return Success;
 }
 
 }  // namespace
 
-Result<SuccessType> SingleEntryPoint(Module& ir, std::string_view entry_point_name) {
+diag::Result<SuccessType> SingleEntryPoint(Module& ir, std::string_view entry_point_name) {
     auto result = ValidateAndDumpIfNeeded(
         ir, "core.SingleEntryPoint", core::ir::Capabilities{core::ir::Capability::kAllowOverrides});
     if (result != Success) {
         return result.Failure();
     }
 
-    return Run(ir, entry_point_name);
+    Run(ir, entry_point_name);
+
+    return Success;
 }
 
 }  // namespace tint::core::ir::transform
diff --git a/src/tint/lang/core/ir/transform/single_entry_point.h b/src/tint/lang/core/ir/transform/single_entry_point.h
index 2ce152b..fbc4999 100644
--- a/src/tint/lang/core/ir/transform/single_entry_point.h
+++ b/src/tint/lang/core/ir/transform/single_entry_point.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_CORE_IR_TRANSFORM_SINGLE_ENTRY_POINT_H_
 #define SRC_TINT_LANG_CORE_IR_TRANSFORM_SINGLE_ENTRY_POINT_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -42,7 +42,7 @@
 /// @param module the module to transform
 /// @param entry_point_name the entry point name
 /// @returns success or failure
-Result<SuccessType> SingleEntryPoint(Module& module, std::string_view entry_point_name);
+diag::Result<SuccessType> SingleEntryPoint(Module& module, std::string_view entry_point_name);
 
 }  // namespace tint::core::ir::transform
 
diff --git a/src/tint/lang/core/ir/transform/std140.cc b/src/tint/lang/core/ir/transform/std140.cc
index ac9a685..f61dc55 100644
--- a/src/tint/lang/core/ir/transform/std140.cc
+++ b/src/tint/lang/core/ir/transform/std140.cc
@@ -449,7 +449,7 @@
 
 }  // namespace
 
-Result<SuccessType> Std140(Module& ir) {
+diag::Result<SuccessType> Std140(Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "core.Std140", kStd140Capabilities);
     if (result != Success) {
         return result;
diff --git a/src/tint/lang/core/ir/transform/std140.h b/src/tint/lang/core/ir/transform/std140.h
index 2f83e04..b4fb98f 100644
--- a/src/tint/lang/core/ir/transform/std140.h
+++ b/src/tint/lang/core/ir/transform/std140.h
@@ -28,10 +28,8 @@
 #ifndef SRC_TINT_LANG_CORE_IR_TRANSFORM_STD140_H_
 #define SRC_TINT_LANG_CORE_IR_TRANSFORM_STD140_H_
 
-#include <string>
-
 #include "src/tint/lang/core/ir/validator.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -51,7 +49,7 @@
 /// pointer parameters.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> Std140(Module& module);
+diag::Result<SuccessType> Std140(Module& module);
 
 }  // namespace tint::core::ir::transform
 
diff --git a/src/tint/lang/core/ir/transform/std140_fuzz.cc b/src/tint/lang/core/ir/transform/std140_fuzz.cc
index 3857902..a664b2c 100644
--- a/src/tint/lang/core/ir/transform/std140_fuzz.cc
+++ b/src/tint/lang/core/ir/transform/std140_fuzz.cc
@@ -48,9 +48,9 @@
     return true;
 }
 
-Result<SuccessType> Std140Fuzzer(Module& module, const fuzz::ir::Context&) {
+diag::Result<SuccessType> Std140Fuzzer(Module& module, const fuzz::ir::Context&) {
     if (!CanRun(module)) {
-        return Failure{"Cannot run module"};
+        return diag::Failure{"Cannot run module"};
     }
 
     return Std140(module);
diff --git a/src/tint/lang/core/ir/transform/substitute_overrides.cc b/src/tint/lang/core/ir/transform/substitute_overrides.cc
index 7834a52..65aa48e 100644
--- a/src/tint/lang/core/ir/transform/substitute_overrides.cc
+++ b/src/tint/lang/core/ir/transform/substitute_overrides.cc
@@ -69,8 +69,9 @@
 
     /// The type manager.
     core::type::Manager& ty{ir.Types()};
+
     /// Process the module.
-    Result<SuccessType> Process() {
+    diag::Result<SuccessType> Process() {
         Vector<Instruction*, 8> to_remove;
         Vector<Constant*, 8> values_to_propagate;
         Vector<core::ir::Var*, 4> vars_with_value_array_count;
@@ -129,7 +130,7 @@
                               << " with value (" << iter->second
                               << ")  is not representable in type ("
                               << override->Result(0)->Type()->FriendlyName() << ")";
-                        return Failure(error);
+                        return diag::Failure(error);
                     }
 
                     auto* replacement = CreateConstant(override->Result(0)->Type(), iter->second);
@@ -142,7 +143,7 @@
                 error.severity = diag::Severity::Error;
                 error.source = ir.SourceOf(override);
                 error << "Initializer not provided for override, and override not overridden.";
-                return Failure(error);
+                return diag::Failure(error);
             }
 
             if (auto* replacement = override->Initializer()->As<core::ir::Constant>()) {
@@ -255,7 +256,7 @@
         return Success;
     }
 
-    Result<SuccessType> EvalConstExprIf() {
+    diag::Result<SuccessType> EvalConstExprIf() {
         Vector<core::ir::ConstExprIf*, 32> ordered_constexpr_if;
         core::ir::Traverse(ir.root_block, [&ordered_constexpr_if](ConstExprIf* inst) {
             ordered_constexpr_if.Push(inst);
@@ -299,7 +300,7 @@
         return Success;
     }
 
-    Result<core::ir::Constant*> CalculateOverride(core::ir::Value* val) {
+    diag::Result<core::ir::Constant*> CalculateOverride(core::ir::Value* val) {
         auto r = eval::Eval(b, val);
         if (r != Success) {
             return r.Failure();
@@ -310,7 +311,7 @@
         return r;
     }
 
-    Result<SuccessType> Propagate(Vector<core::ir::Constant*, 8>& values_to_propagate) {
+    diag::Result<SuccessType> Propagate(Vector<core::ir::Constant*, 8>& values_to_propagate) {
         while (!values_to_propagate.IsEmpty()) {
             auto* value = values_to_propagate.Pop();
             for (auto usage : value->UsagesSorted()) {
@@ -376,7 +377,7 @@
 
 SubstituteOverridesConfig::SubstituteOverridesConfig() = default;
 
-Result<SuccessType> SubstituteOverrides(Module& ir, const SubstituteOverridesConfig& cfg) {
+diag::Result<SuccessType> SubstituteOverrides(Module& ir, const SubstituteOverridesConfig& cfg) {
     auto result =
         ValidateAndDumpIfNeeded(ir, "core.SubstituteOverrides", kSubstituteOverridesCapabilities);
     if (result != Success) {
diff --git a/src/tint/lang/core/ir/transform/substitute_overrides.h b/src/tint/lang/core/ir/transform/substitute_overrides.h
index 35e0c7f..df234aa 100644
--- a/src/tint/lang/core/ir/transform/substitute_overrides.h
+++ b/src/tint/lang/core/ir/transform/substitute_overrides.h
@@ -32,8 +32,8 @@
 
 #include "src/tint/api/common/override_id.h"
 #include "src/tint/lang/core/ir/validator.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 #include "src/tint/utils/reflection.h"
-#include "src/tint/utils/result/result.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -74,7 +74,7 @@
 /// Substitute overrides to their constant values.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> SubstituteOverrides(Module& module, const SubstituteOverridesConfig& cfg);
+diag::Result<SuccessType> SubstituteOverrides(Module& module, const SubstituteOverridesConfig& cfg);
 
 }  // namespace tint::core::ir::transform
 
diff --git a/src/tint/lang/core/ir/transform/substitute_overrides_fuzz.cc b/src/tint/lang/core/ir/transform/substitute_overrides_fuzz.cc
index 5e67e06..1505222 100644
--- a/src/tint/lang/core/ir/transform/substitute_overrides_fuzz.cc
+++ b/src/tint/lang/core/ir/transform/substitute_overrides_fuzz.cc
@@ -34,9 +34,9 @@
 namespace tint::core::ir::transform {
 namespace {
 
-Result<SuccessType> SubstituteOverridesFuzzer(Module& ir,
-                                              const fuzz::ir::Context&,
-                                              const SubstituteOverridesConfig& cfg) {
+diag::Result<SuccessType> SubstituteOverridesFuzzer(Module& ir,
+                                                    const fuzz::ir::Context&,
+                                                    const SubstituteOverridesConfig& cfg) {
     return SubstituteOverrides(ir, cfg);
 }
 
diff --git a/src/tint/lang/core/ir/transform/value_to_let.cc b/src/tint/lang/core/ir/transform/value_to_let.cc
index 1c193bf..03dfc02 100644
--- a/src/tint/lang/core/ir/transform/value_to_let.cc
+++ b/src/tint/lang/core/ir/transform/value_to_let.cc
@@ -229,7 +229,7 @@
 
 }  // namespace
 
-Result<SuccessType> ValueToLet(Module& ir, const ValueToLetConfig& cfg) {
+diag::Result<SuccessType> ValueToLet(Module& ir, const ValueToLetConfig& cfg) {
     auto result = ValidateAndDumpIfNeeded(ir, "core.ValueToLet", kValueToLetCapabilities);
     if (result != Success) {
         return result;
diff --git a/src/tint/lang/core/ir/transform/value_to_let.h b/src/tint/lang/core/ir/transform/value_to_let.h
index 5127597..56a983c 100644
--- a/src/tint/lang/core/ir/transform/value_to_let.h
+++ b/src/tint/lang/core/ir/transform/value_to_let.h
@@ -29,8 +29,8 @@
 #define SRC_TINT_LANG_CORE_IR_TRANSFORM_VALUE_TO_LET_H_
 
 #include "src/tint/lang/core/ir/validator.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 #include "src/tint/utils/reflection.h"
-#include "src/tint/utils/result/result.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -71,7 +71,7 @@
 /// @param module the module to transform
 /// @param cfg the configuration
 /// @returns error diagnostics on failure
-Result<SuccessType> ValueToLet(Module& module, const ValueToLetConfig& cfg);
+diag::Result<SuccessType> ValueToLet(Module& module, const ValueToLetConfig& cfg);
 
 }  // namespace tint::core::ir::transform
 
diff --git a/src/tint/lang/core/ir/transform/value_to_let_fuzz.cc b/src/tint/lang/core/ir/transform/value_to_let_fuzz.cc
index 91c430e..031dfb6 100644
--- a/src/tint/lang/core/ir/transform/value_to_let_fuzz.cc
+++ b/src/tint/lang/core/ir/transform/value_to_let_fuzz.cc
@@ -44,11 +44,11 @@
     return true;
 }
 
-Result<SuccessType> ValueToLetFuzzer(Module& module,
-                                     const fuzz::ir::Context&,
-                                     ValueToLetConfig config) {
+diag::Result<SuccessType> ValueToLetFuzzer(Module& module,
+                                           const fuzz::ir::Context&,
+                                           ValueToLetConfig config) {
     if (!CanRun(module)) {
-        return Failure{"Cannot run module"};
+        return diag::Failure{"Cannot run module"};
     }
 
     return ValueToLet(module, config);
diff --git a/src/tint/lang/core/ir/transform/value_to_let_test.cc b/src/tint/lang/core/ir/transform/value_to_let_test.cc
index 6de9e22..db1ed2b 100644
--- a/src/tint/lang/core/ir/transform/value_to_let_test.cc
+++ b/src/tint/lang/core/ir/transform/value_to_let_test.cc
@@ -27,8 +27,6 @@
 
 #include "src/tint/lang/core/ir/transform/value_to_let.h"
 
-#include <utility>
-
 #include "gtest/gtest.h"
 #include "src/tint/lang/core/ir/transform/helper_test.h"
 #include "src/tint/lang/core/type/depth_texture.h"
diff --git a/src/tint/lang/core/ir/transform/vectorize_scalar_matrix_constructors.cc b/src/tint/lang/core/ir/transform/vectorize_scalar_matrix_constructors.cc
index 96996bf..2cdc519 100644
--- a/src/tint/lang/core/ir/transform/vectorize_scalar_matrix_constructors.cc
+++ b/src/tint/lang/core/ir/transform/vectorize_scalar_matrix_constructors.cc
@@ -93,7 +93,7 @@
 
 }  // namespace
 
-Result<SuccessType> VectorizeScalarMatrixConstructors(Module& ir) {
+diag::Result<SuccessType> VectorizeScalarMatrixConstructors(Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "core.VectorizeScalarMatrixConstructors",
                                           kVectorizeScalarMatrixConstructorsCapabilities);
     if (result != Success) {
diff --git a/src/tint/lang/core/ir/transform/vectorize_scalar_matrix_constructors.h b/src/tint/lang/core/ir/transform/vectorize_scalar_matrix_constructors.h
index a57bf66..4a3307a 100644
--- a/src/tint/lang/core/ir/transform/vectorize_scalar_matrix_constructors.h
+++ b/src/tint/lang/core/ir/transform/vectorize_scalar_matrix_constructors.h
@@ -29,7 +29,7 @@
 #define SRC_TINT_LANG_CORE_IR_TRANSFORM_VECTORIZE_SCALAR_MATRIX_CONSTRUCTORS_H_
 
 #include "src/tint/lang/core/ir/validator.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -50,7 +50,7 @@
 ///
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> VectorizeScalarMatrixConstructors(Module& module);
+diag::Result<SuccessType> VectorizeScalarMatrixConstructors(Module& module);
 
 }  // namespace tint::core::ir::transform
 
diff --git a/src/tint/lang/core/ir/transform/vectorize_scalar_matrix_constructors_fuzz.cc b/src/tint/lang/core/ir/transform/vectorize_scalar_matrix_constructors_fuzz.cc
index 86e0916..9c58a27 100644
--- a/src/tint/lang/core/ir/transform/vectorize_scalar_matrix_constructors_fuzz.cc
+++ b/src/tint/lang/core/ir/transform/vectorize_scalar_matrix_constructors_fuzz.cc
@@ -33,7 +33,8 @@
 namespace tint::core::ir::transform {
 namespace {
 
-Result<SuccessType> VectorizeScalarMatrixConstructorsFuzzer(Module& ir, const fuzz::ir::Context&) {
+diag::Result<SuccessType> VectorizeScalarMatrixConstructorsFuzzer(Module& ir,
+                                                                  const fuzz::ir::Context&) {
     return VectorizeScalarMatrixConstructors(ir);
 }
 
diff --git a/src/tint/lang/core/ir/transform/vertex_pulling.cc b/src/tint/lang/core/ir/transform/vertex_pulling.cc
index 009fbb2..b58940e 100644
--- a/src/tint/lang/core/ir/transform/vertex_pulling.cc
+++ b/src/tint/lang/core/ir/transform/vertex_pulling.cc
@@ -687,7 +687,7 @@
 
 }  // namespace
 
-Result<SuccessType> VertexPulling(core::ir::Module& ir, const VertexPullingConfig& config) {
+diag::Result<SuccessType> VertexPulling(core::ir::Module& ir, const VertexPullingConfig& config) {
     auto result = ValidateAndDumpIfNeeded(ir, "core.VertexPulling");
     if (result != Success) {
         return result.Failure();
diff --git a/src/tint/lang/core/ir/transform/vertex_pulling.h b/src/tint/lang/core/ir/transform/vertex_pulling.h
index 89ce8cf..b993e1d 100644
--- a/src/tint/lang/core/ir/transform/vertex_pulling.h
+++ b/src/tint/lang/core/ir/transform/vertex_pulling.h
@@ -29,7 +29,7 @@
 #define SRC_TINT_LANG_CORE_IR_TRANSFORM_VERTEX_PULLING_H_
 
 #include "src/tint/api/common/vertex_pulling_config.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -53,7 +53,8 @@
 /// @param module the module to transform
 /// @param config the vertex pulling configuration
 /// @returns success or failure
-Result<SuccessType> VertexPulling(core::ir::Module& module, const VertexPullingConfig& config);
+diag::Result<SuccessType> VertexPulling(core::ir::Module& module,
+                                        const VertexPullingConfig& config);
 
 }  // namespace tint::core::ir::transform
 
diff --git a/src/tint/lang/core/ir/transform/zero_init_workgroup_memory.cc b/src/tint/lang/core/ir/transform/zero_init_workgroup_memory.cc
index 65e5a29..02f32bb 100644
--- a/src/tint/lang/core/ir/transform/zero_init_workgroup_memory.cc
+++ b/src/tint/lang/core/ir/transform/zero_init_workgroup_memory.cc
@@ -27,9 +27,6 @@
 
 #include "src/tint/lang/core/ir/transform/zero_init_workgroup_memory.h"
 
-#include <map>
-#include <utility>
-
 #include "src/tint/lang/core/ir/builder.h"
 #include "src/tint/lang/core/ir/module.h"
 #include "src/tint/lang/core/ir/referenced_module_vars.h"
@@ -308,7 +305,7 @@
 
 }  // namespace
 
-Result<SuccessType> ZeroInitWorkgroupMemory(Module& ir) {
+diag::Result<SuccessType> ZeroInitWorkgroupMemory(Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "core.ZeroInitWorkgroupMemory");
     if (result != Success) {
         return result;
diff --git a/src/tint/lang/core/ir/transform/zero_init_workgroup_memory.h b/src/tint/lang/core/ir/transform/zero_init_workgroup_memory.h
index 9be056c..8df5aa1 100644
--- a/src/tint/lang/core/ir/transform/zero_init_workgroup_memory.h
+++ b/src/tint/lang/core/ir/transform/zero_init_workgroup_memory.h
@@ -28,9 +28,7 @@
 #ifndef SRC_TINT_LANG_CORE_IR_TRANSFORM_ZERO_INIT_WORKGROUP_MEMORY_H_
 #define SRC_TINT_LANG_CORE_IR_TRANSFORM_ZERO_INIT_WORKGROUP_MEMORY_H_
 
-#include <string>
-
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -43,7 +41,7 @@
 /// zero-initialize workgroup memory used by that entry point.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> ZeroInitWorkgroupMemory(Module& module);
+diag::Result<SuccessType> ZeroInitWorkgroupMemory(Module& module);
 
 }  // namespace tint::core::ir::transform
 
diff --git a/src/tint/lang/core/ir/transform/zero_init_workgroup_memory_fuzz.cc b/src/tint/lang/core/ir/transform/zero_init_workgroup_memory_fuzz.cc
index 970217d..d4fa2ba 100644
--- a/src/tint/lang/core/ir/transform/zero_init_workgroup_memory_fuzz.cc
+++ b/src/tint/lang/core/ir/transform/zero_init_workgroup_memory_fuzz.cc
@@ -33,7 +33,7 @@
 namespace tint::core::ir::transform {
 namespace {
 
-Result<SuccessType> ZeroInitWorkgroupMemoryFuzzer(Module& ir, const fuzz::ir::Context&) {
+diag::Result<SuccessType> ZeroInitWorkgroupMemoryFuzzer(Module& ir, const fuzz::ir::Context&) {
     return ZeroInitWorkgroupMemory(ir);
 }
 
diff --git a/src/tint/lang/core/ir/validator.cc b/src/tint/lang/core/ir/validator.cc
index 11687f9..7e2b1da 100644
--- a/src/tint/lang/core/ir/validator.cc
+++ b/src/tint/lang/core/ir/validator.cc
@@ -751,7 +751,7 @@
 
     /// Runs the validator over the module provided during construction
     /// @returns success or failure
-    Result<SuccessType> Run();
+    diag::Result<SuccessType> Run();
 
   private:
     /// Runs validation to confirm the structural soundness of the module.
@@ -1369,7 +1369,7 @@
     return *disassembler_;
 }
 
-Result<SuccessType> Validator::Run() {
+diag::Result<SuccessType> Validator::Run() {
     RunStructuralSoundnessChecks();
 
     if (!diagnostics_.ContainsErrors()) {
@@ -1382,7 +1382,7 @@
 
     if (diagnostics_.ContainsErrors()) {
         diagnostics_.AddNote(Source{}) << "# Disassembly\n" << Disassemble().Text();
-        return Failure{std::move(diagnostics_)};
+        return diag::Failure{std::move(diagnostics_)};
     }
     return Success;
 }
@@ -3691,14 +3691,14 @@
 
 }  // namespace
 
-Result<SuccessType> Validate(const Module& mod, Capabilities capabilities) {
+diag::Result<SuccessType> Validate(const Module& mod, Capabilities capabilities) {
     Validator v(mod, capabilities);
     return v.Run();
 }
 
-Result<SuccessType> ValidateAndDumpIfNeeded([[maybe_unused]] const Module& ir,
-                                            [[maybe_unused]] const char* msg,
-                                            [[maybe_unused]] Capabilities capabilities) {
+diag::Result<SuccessType> ValidateAndDumpIfNeeded([[maybe_unused]] const Module& ir,
+                                                  [[maybe_unused]] const char* msg,
+                                                  [[maybe_unused]] Capabilities capabilities) {
 #if TINT_DUMP_IR_WHEN_VALIDATING
     auto printer = StyledTextPrinter::Create(stdout);
     std::cout << "=========================================================\n";
diff --git a/src/tint/lang/core/ir/validator.h b/src/tint/lang/core/ir/validator.h
index fa2a373..9bfef76 100644
--- a/src/tint/lang/core/ir/validator.h
+++ b/src/tint/lang/core/ir/validator.h
@@ -28,10 +28,8 @@
 #ifndef SRC_TINT_LANG_CORE_IR_VALIDATOR_H_
 #define SRC_TINT_LANG_CORE_IR_VALIDATOR_H_
 
-#include <string>
-
 #include "src/tint/utils/containers/enum_set.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations
 namespace tint::core::ir {
@@ -75,16 +73,16 @@
 /// @param mod the module to validate
 /// @param capabilities the optional capabilities that are allowed
 /// @returns success or failure
-Result<SuccessType> Validate(const Module& mod, Capabilities capabilities = {});
+diag::Result<SuccessType> Validate(const Module& mod, Capabilities capabilities = {});
 
 /// Validates the module @p ir and dumps its contents if required by the build configuration.
 /// @param ir the module to transform
 /// @param msg the msg to accompany the output
 /// @param capabilities the optional capabilities that are allowed
 /// @returns success or failure
-Result<SuccessType> ValidateAndDumpIfNeeded(const Module& ir,
-                                            const char* msg,
-                                            Capabilities capabilities = {});
+diag::Result<SuccessType> ValidateAndDumpIfNeeded(const Module& ir,
+                                                  const char* msg,
+                                                  Capabilities capabilities = {});
 
 }  // namespace tint::core::ir
 
diff --git a/src/tint/lang/glsl/validate/BUILD.bazel b/src/tint/lang/glsl/validate/BUILD.bazel
index 40e389a..9a7d3cf 100644
--- a/src/tint/lang/glsl/validate/BUILD.bazel
+++ b/src/tint/lang/glsl/validate/BUILD.bazel
@@ -46,12 +46,8 @@
   ],
   deps = [
     "//src/tint/lang/wgsl/ast",
-    "//src/tint/utils/containers",
-    "//src/tint/utils/diagnostic",
     "//src/tint/utils/ice",
     "//src/tint/utils/macros",
-    "//src/tint/utils/math",
-    "//src/tint/utils/memory",
     "//src/tint/utils/result",
     "//src/tint/utils/rtti",
     "//src/tint/utils/text",
diff --git a/src/tint/lang/glsl/validate/BUILD.cmake b/src/tint/lang/glsl/validate/BUILD.cmake
index d9713c1..4745fd9 100644
--- a/src/tint/lang/glsl/validate/BUILD.cmake
+++ b/src/tint/lang/glsl/validate/BUILD.cmake
@@ -47,12 +47,8 @@
 
 tint_target_add_dependencies(tint_lang_glsl_validate lib
   tint_lang_wgsl_ast
-  tint_utils_containers
-  tint_utils_diagnostic
   tint_utils_ice
   tint_utils_macros
-  tint_utils_math
-  tint_utils_memory
   tint_utils_result
   tint_utils_rtti
   tint_utils_text
diff --git a/src/tint/lang/glsl/validate/BUILD.gn b/src/tint/lang/glsl/validate/BUILD.gn
index 2557de3..e44ad36 100644
--- a/src/tint/lang/glsl/validate/BUILD.gn
+++ b/src/tint/lang/glsl/validate/BUILD.gn
@@ -47,12 +47,8 @@
     deps = [
       "${dawn_root}/src/utils:utils",
       "${tint_src_dir}/lang/wgsl/ast",
-      "${tint_src_dir}/utils/containers",
-      "${tint_src_dir}/utils/diagnostic",
       "${tint_src_dir}/utils/ice",
       "${tint_src_dir}/utils/macros",
-      "${tint_src_dir}/utils/math",
-      "${tint_src_dir}/utils/memory",
       "${tint_src_dir}/utils/result",
       "${tint_src_dir}/utils/rtti",
       "${tint_src_dir}/utils/text",
diff --git a/src/tint/lang/glsl/writer/common/option_helpers.cc b/src/tint/lang/glsl/writer/common/option_helpers.cc
index b7becc3..50b2a20 100644
--- a/src/tint/lang/glsl/writer/common/option_helpers.cc
+++ b/src/tint/lang/glsl/writer/common/option_helpers.cc
@@ -27,14 +27,13 @@
 
 #include "src/tint/lang/glsl/writer/common/option_helpers.h"
 
-#include <iostream>
 #include <utility>
 
 #include "src/tint/utils/containers/hashmap.h"
 
 namespace tint::glsl::writer {
 
-Result<SuccessType> ValidateBindingOptions(const Options& options) {
+diag::Result<SuccessType> ValidateBindingOptions(const Options& options) {
     diag::List diagnostics;
 
     tint::Hashmap<tint::BindingPoint, binding::BindingInfo, 8> seen_wgsl_bindings{};
@@ -87,25 +86,25 @@
 
     if (!valid(options.bindings.uniform)) {
         diagnostics.AddNote(Source{}) << "when processing uniform";
-        return Failure{std::move(diagnostics)};
+        return diag::Failure{std::move(diagnostics)};
     }
     if (!valid(options.bindings.storage)) {
         diagnostics.AddNote(Source{}) << "when processing storage";
-        return Failure{std::move(diagnostics)};
+        return diag::Failure{std::move(diagnostics)};
     }
 
     if (!valid(options.bindings.sampler)) {
         diagnostics.AddNote(Source{}) << "when processing sampler";
-        return Failure{std::move(diagnostics)};
+        return diag::Failure{std::move(diagnostics)};
     }
 
     if (!valid(options.bindings.texture)) {
         diagnostics.AddNote(Source{}) << "when processing texture";
-        return Failure{std::move(diagnostics)};
+        return diag::Failure{std::move(diagnostics)};
     }
     if (!valid(options.bindings.storage_texture)) {
         diagnostics.AddNote(Source{}) << "when processing storage_texture";
-        return Failure{std::move(diagnostics)};
+        return diag::Failure{std::move(diagnostics)};
     }
 
     for (const auto& it : options.bindings.external_texture) {
@@ -117,20 +116,20 @@
         // Validate with the actual source regardless of what the remapper will do
         if (wgsl_seen(src_binding, plane0)) {
             diagnostics.AddNote(Source{}) << "when processing external_texture";
-            return Failure{std::move(diagnostics)};
+            return diag::Failure{std::move(diagnostics)};
         }
 
         if (glsl_seen(plane0, src_binding)) {
             diagnostics.AddNote(Source{}) << "when processing external_texture";
-            return Failure{std::move(diagnostics)};
+            return diag::Failure{std::move(diagnostics)};
         }
         if (glsl_seen(plane1, src_binding)) {
             diagnostics.AddNote(Source{}) << "when processing external_texture";
-            return Failure{std::move(diagnostics)};
+            return diag::Failure{std::move(diagnostics)};
         }
         if (glsl_seen(metadata, src_binding)) {
             diagnostics.AddNote(Source{}) << "when processing external_texture";
-            return Failure{std::move(diagnostics)};
+            return diag::Failure{std::move(diagnostics)};
         }
     }
 
diff --git a/src/tint/lang/glsl/writer/common/option_helpers.h b/src/tint/lang/glsl/writer/common/option_helpers.h
index d0f118c..d3388bc 100644
--- a/src/tint/lang/glsl/writer/common/option_helpers.h
+++ b/src/tint/lang/glsl/writer/common/option_helpers.h
@@ -34,7 +34,6 @@
 #include "src/tint/lang/core/common/multiplanar_options.h"
 #include "src/tint/lang/glsl/writer/common/options.h"
 #include "src/tint/utils/diagnostic/diagnostic.h"
-#include "src/tint/utils/result/result.h"
 
 namespace tint::glsl::writer {
 /// The remapper data
@@ -42,7 +41,7 @@
 
 /// @param options the options
 /// @returns success or failure
-Result<SuccessType> ValidateBindingOptions(const Options& options);
+diag::Result<SuccessType> ValidateBindingOptions(const Options& options);
 
 /// Populates data from the writer options for the remapper and external texture.
 /// @param options the writer options
diff --git a/src/tint/lang/glsl/writer/printer/printer.cc b/src/tint/lang/glsl/writer/printer/printer.cc
index d4965d9..f9020a7 100644
--- a/src/tint/lang/glsl/writer/printer/printer.cc
+++ b/src/tint/lang/glsl/writer/printer/printer.cc
@@ -125,7 +125,7 @@
     Printer(core::ir::Module& module, const Options& options) : ir_(module), options_(options) {}
 
     /// @returns the generated GLSL shader
-    tint::Result<Output> Generate() {
+    diag::Result<Output> Generate() {
         auto valid = core::ir::ValidateAndDumpIfNeeded(
             ir_, "glsl.Printer",
             core::ir::Capabilities{core::ir::Capability::kAllowHandleVarsWithoutBindings});
@@ -2276,7 +2276,7 @@
 
 }  // namespace
 
-Result<Output> Print(core::ir::Module& module, const Options& options) {
+diag::Result<Output> Print(core::ir::Module& module, const Options& options) {
     return Printer{module, options}.Generate();
 }
 
diff --git a/src/tint/lang/glsl/writer/printer/printer.h b/src/tint/lang/glsl/writer/printer/printer.h
index 7114424..c7ab503 100644
--- a/src/tint/lang/glsl/writer/printer/printer.h
+++ b/src/tint/lang/glsl/writer/printer/printer.h
@@ -29,7 +29,7 @@
 #define SRC_TINT_LANG_GLSL_WRITER_PRINTER_PRINTER_H_
 
 #include "src/tint/lang/glsl/writer/common/output.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations
 namespace tint::core::ir {
@@ -44,7 +44,7 @@
 /// @returns the generated GLSL shader on success, or failure
 /// @param module the Tint IR module to generate
 /// @param options the options to use
-Result<Output> Print(core::ir::Module& module, const Options& options);
+diag::Result<Output> Print(core::ir::Module& module, const Options& options);
 
 }  // namespace tint::glsl::writer
 
diff --git a/src/tint/lang/glsl/writer/raise/binary_polyfill.cc b/src/tint/lang/glsl/writer/raise/binary_polyfill.cc
index 7a295c2..f6aff36 100644
--- a/src/tint/lang/glsl/writer/raise/binary_polyfill.cc
+++ b/src/tint/lang/glsl/writer/raise/binary_polyfill.cc
@@ -215,7 +215,7 @@
 
 }  // namespace
 
-Result<SuccessType> BinaryPolyfill(core::ir::Module& ir) {
+diag::Result<SuccessType> BinaryPolyfill(core::ir::Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "glsl.BinaryPolyfill");
     if (result != Success) {
         return result.Failure();
diff --git a/src/tint/lang/glsl/writer/raise/binary_polyfill.h b/src/tint/lang/glsl/writer/raise/binary_polyfill.h
index e4ce1c9..b196e57 100644
--- a/src/tint/lang/glsl/writer/raise/binary_polyfill.h
+++ b/src/tint/lang/glsl/writer/raise/binary_polyfill.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_GLSL_WRITER_RAISE_BINARY_POLYFILL_H_
 #define SRC_TINT_LANG_GLSL_WRITER_RAISE_BINARY_POLYFILL_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -43,7 +43,7 @@
 ///
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> BinaryPolyfill(core::ir::Module& module);
+diag::Result<SuccessType> BinaryPolyfill(core::ir::Module& module);
 
 }  // namespace tint::glsl::writer::raise
 
diff --git a/src/tint/lang/glsl/writer/raise/bitcast_polyfill.cc b/src/tint/lang/glsl/writer/raise/bitcast_polyfill.cc
index 11f67c5..cd82fac 100644
--- a/src/tint/lang/glsl/writer/raise/bitcast_polyfill.cc
+++ b/src/tint/lang/glsl/writer/raise/bitcast_polyfill.cc
@@ -27,7 +27,6 @@
 
 #include "src/tint/lang/glsl/writer/raise/bitcast_polyfill.h"
 
-#include <string>
 #include <tuple>
 
 #include "src/tint/lang/core/fluent_types.h"  // IWYU pragma: export
@@ -277,7 +276,7 @@
 
 }  // namespace
 
-Result<SuccessType> BitcastPolyfill(core::ir::Module& ir) {
+diag::Result<SuccessType> BitcastPolyfill(core::ir::Module& ir) {
     auto result = ValidateAndDumpIfNeeded(
         ir, "glsl.BitcastPolyfill",
         core::ir::Capabilities{core::ir::Capability::kAllowHandleVarsWithoutBindings});
diff --git a/src/tint/lang/glsl/writer/raise/bitcast_polyfill.h b/src/tint/lang/glsl/writer/raise/bitcast_polyfill.h
index 6941fbd..4f2e813 100644
--- a/src/tint/lang/glsl/writer/raise/bitcast_polyfill.h
+++ b/src/tint/lang/glsl/writer/raise/bitcast_polyfill.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_GLSL_WRITER_RAISE_BITCAST_POLYFILL_H_
 #define SRC_TINT_LANG_GLSL_WRITER_RAISE_BITCAST_POLYFILL_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -41,7 +41,7 @@
 /// BitcastPolyfill is a transform that replaces calls to bitcasts with polyfills
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> BitcastPolyfill(core::ir::Module& module);
+diag::Result<SuccessType> BitcastPolyfill(core::ir::Module& module);
 
 }  // namespace tint::glsl::writer::raise
 
diff --git a/src/tint/lang/glsl/writer/raise/builtin_polyfill.cc b/src/tint/lang/glsl/writer/raise/builtin_polyfill.cc
index 503e762..6dcb02b 100644
--- a/src/tint/lang/glsl/writer/raise/builtin_polyfill.cc
+++ b/src/tint/lang/glsl/writer/raise/builtin_polyfill.cc
@@ -27,8 +27,6 @@
 
 #include "src/tint/lang/glsl/writer/raise/builtin_polyfill.h"
 
-#include <string>
-#include <tuple>
 #include <utility>
 
 #include "src/tint/lang/core/fluent_types.h"  // IWYU pragma: export
@@ -527,7 +525,7 @@
 
 }  // namespace
 
-Result<SuccessType> BuiltinPolyfill(core::ir::Module& ir) {
+diag::Result<SuccessType> BuiltinPolyfill(core::ir::Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "glsl.BuiltinPolyfill");
     if (result != Success) {
         return result.Failure();
diff --git a/src/tint/lang/glsl/writer/raise/builtin_polyfill.h b/src/tint/lang/glsl/writer/raise/builtin_polyfill.h
index 6dca17c..01ee6e9 100644
--- a/src/tint/lang/glsl/writer/raise/builtin_polyfill.h
+++ b/src/tint/lang/glsl/writer/raise/builtin_polyfill.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_GLSL_WRITER_RAISE_BUILTIN_POLYFILL_H_
 #define SRC_TINT_LANG_GLSL_WRITER_RAISE_BUILTIN_POLYFILL_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -42,7 +42,7 @@
 /// GLSL polyfilled or backend intrinsic functions.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> BuiltinPolyfill(core::ir::Module& module);
+diag::Result<SuccessType> BuiltinPolyfill(core::ir::Module& module);
 
 }  // namespace tint::glsl::writer::raise
 
diff --git a/src/tint/lang/glsl/writer/raise/offset_first_index.cc b/src/tint/lang/glsl/writer/raise/offset_first_index.cc
index 4226a02..b731e73 100644
--- a/src/tint/lang/glsl/writer/raise/offset_first_index.cc
+++ b/src/tint/lang/glsl/writer/raise/offset_first_index.cc
@@ -111,7 +111,8 @@
 
 }  // namespace
 
-Result<SuccessType> OffsetFirstIndex(core::ir::Module& ir, const OffsetFirstIndexConfig& config) {
+diag::Result<SuccessType> OffsetFirstIndex(core::ir::Module& ir,
+                                           const OffsetFirstIndexConfig& config) {
     auto result = ValidateAndDumpIfNeeded(ir, "glsl.OffsetFirstIndex",
                                           core::ir::Capabilities{
                                               core::ir::Capability::kAllowHandleVarsWithoutBindings,
diff --git a/src/tint/lang/glsl/writer/raise/offset_first_index.h b/src/tint/lang/glsl/writer/raise/offset_first_index.h
index d1a8433..57ef01a 100644
--- a/src/tint/lang/glsl/writer/raise/offset_first_index.h
+++ b/src/tint/lang/glsl/writer/raise/offset_first_index.h
@@ -29,7 +29,7 @@
 #define SRC_TINT_LANG_GLSL_WRITER_RAISE_OFFSET_FIRST_INDEX_H_
 
 #include "src/tint/lang/core/ir/transform/prepare_push_constants.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -55,8 +55,8 @@
 ///
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> OffsetFirstIndex(core::ir::Module& module,
-                                     const OffsetFirstIndexConfig& config);
+diag::Result<SuccessType> OffsetFirstIndex(core::ir::Module& module,
+                                           const OffsetFirstIndexConfig& config);
 
 }  // namespace tint::glsl::writer::raise
 
diff --git a/src/tint/lang/glsl/writer/raise/raise.cc b/src/tint/lang/glsl/writer/raise/raise.cc
index d94ebfa..20f4cea 100644
--- a/src/tint/lang/glsl/writer/raise/raise.cc
+++ b/src/tint/lang/glsl/writer/raise/raise.cc
@@ -63,7 +63,7 @@
 
 namespace tint::glsl::writer {
 
-Result<SuccessType> Raise(core::ir::Module& module, const Options& options) {
+diag::Result<SuccessType> Raise(core::ir::Module& module, const Options& options) {
 #define RUN_TRANSFORM(name, ...)         \
     do {                                 \
         auto result = name(__VA_ARGS__); \
diff --git a/src/tint/lang/glsl/writer/raise/raise.h b/src/tint/lang/glsl/writer/raise/raise.h
index 7b48911..e21e35f 100644
--- a/src/tint/lang/glsl/writer/raise/raise.h
+++ b/src/tint/lang/glsl/writer/raise/raise.h
@@ -29,7 +29,7 @@
 #define SRC_TINT_LANG_GLSL_WRITER_RAISE_RAISE_H_
 
 #include "src/tint/lang/glsl/writer/common/options.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations
 namespace tint::core::ir {
@@ -42,7 +42,7 @@
 /// @param module the core IR module to raise to MSL dialect
 /// @param options the writer options
 /// @returns success or failure
-Result<SuccessType> Raise(core::ir::Module& module, const Options& options);
+diag::Result<SuccessType> Raise(core::ir::Module& module, const Options& options);
 
 }  // namespace tint::glsl::writer
 
diff --git a/src/tint/lang/glsl/writer/raise/shader_io.cc b/src/tint/lang/glsl/writer/raise/shader_io.cc
index ee34919..1bbb711 100644
--- a/src/tint/lang/glsl/writer/raise/shader_io.cc
+++ b/src/tint/lang/glsl/writer/raise/shader_io.cc
@@ -235,7 +235,7 @@
 
 }  // namespace
 
-Result<SuccessType> ShaderIO(core::ir::Module& ir, const ShaderIOConfig& config) {
+diag::Result<SuccessType> ShaderIO(core::ir::Module& ir, const ShaderIOConfig& config) {
     auto result = ValidateAndDumpIfNeeded(
         ir, "glsl.ShaderIO",
         core::ir::Capabilities{core::ir::Capability::kAllowHandleVarsWithoutBindings});
diff --git a/src/tint/lang/glsl/writer/raise/shader_io.h b/src/tint/lang/glsl/writer/raise/shader_io.h
index 0390211..9c30b63 100644
--- a/src/tint/lang/glsl/writer/raise/shader_io.h
+++ b/src/tint/lang/glsl/writer/raise/shader_io.h
@@ -28,13 +28,11 @@
 #ifndef SRC_TINT_LANG_GLSL_WRITER_RAISE_SHADER_IO_H_
 #define SRC_TINT_LANG_GLSL_WRITER_RAISE_SHADER_IO_H_
 
-#include <string>
 #include <unordered_set>
 
 #include "src/tint/lang/core/ir/transform/prepare_push_constants.h"
 #include "src/tint/lang/glsl/writer/common/options.h"
 #include "src/tint/utils/diagnostic/diagnostic.h"
-#include "src/tint/utils/result/result.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -60,7 +58,7 @@
 /// @param module the module to transform
 /// @param config the configuration
 /// @returns success or failure
-Result<SuccessType> ShaderIO(core::ir::Module& module, const ShaderIOConfig& config);
+diag::Result<SuccessType> ShaderIO(core::ir::Module& module, const ShaderIOConfig& config);
 
 }  // namespace tint::glsl::writer::raise
 
diff --git a/src/tint/lang/glsl/writer/raise/texture_builtins_from_uniform.cc b/src/tint/lang/glsl/writer/raise/texture_builtins_from_uniform.cc
index 3db84fd..c8a6e41 100644
--- a/src/tint/lang/glsl/writer/raise/texture_builtins_from_uniform.cc
+++ b/src/tint/lang/glsl/writer/raise/texture_builtins_from_uniform.cc
@@ -215,8 +215,8 @@
 
 }  // namespace
 
-Result<SuccessType> TextureBuiltinsFromUniform(core::ir::Module& ir,
-                                               const TextureBuiltinsFromUniformOptions& cfg) {
+diag::Result<SuccessType> TextureBuiltinsFromUniform(core::ir::Module& ir,
+                                                     const TextureBuiltinsFromUniformOptions& cfg) {
     auto result = ValidateAndDumpIfNeeded(ir, "glsl.TextureBuiltinsFromUniform");
     if (result != Success) {
         return result.Failure();
diff --git a/src/tint/lang/glsl/writer/raise/texture_builtins_from_uniform.h b/src/tint/lang/glsl/writer/raise/texture_builtins_from_uniform.h
index 15c2c3a..7b2029c 100644
--- a/src/tint/lang/glsl/writer/raise/texture_builtins_from_uniform.h
+++ b/src/tint/lang/glsl/writer/raise/texture_builtins_from_uniform.h
@@ -29,7 +29,7 @@
 #define SRC_TINT_LANG_GLSL_WRITER_RAISE_TEXTURE_BUILTINS_FROM_UNIFORM_H_
 
 #include "src/tint/lang/glsl/writer/common/options.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -45,8 +45,8 @@
 /// @param module the module to transform
 /// @param cfg the configuration
 /// @returns success or failure
-Result<SuccessType> TextureBuiltinsFromUniform(core::ir::Module& module,
-                                               const TextureBuiltinsFromUniformOptions& cfg);
+diag::Result<SuccessType> TextureBuiltinsFromUniform(core::ir::Module& module,
+                                                     const TextureBuiltinsFromUniformOptions& cfg);
 
 }  // namespace tint::glsl::writer::raise
 
diff --git a/src/tint/lang/glsl/writer/raise/texture_polyfill.cc b/src/tint/lang/glsl/writer/raise/texture_polyfill.cc
index 731f3be..664d187 100644
--- a/src/tint/lang/glsl/writer/raise/texture_polyfill.cc
+++ b/src/tint/lang/glsl/writer/raise/texture_polyfill.cc
@@ -27,9 +27,7 @@
 
 #include "src/tint/lang/glsl/writer/raise/texture_polyfill.h"
 
-#include <string>
 #include <utility>
-#include <vector>
 
 #include "src/tint/lang/core/fluent_types.h"  // IWYU pragma: export
 #include "src/tint/lang/core/ir/builder.h"
@@ -1230,7 +1228,7 @@
 
 }  // namespace
 
-Result<SuccessType> TexturePolyfill(core::ir::Module& ir, const TexturePolyfillConfig& cfg) {
+diag::Result<SuccessType> TexturePolyfill(core::ir::Module& ir, const TexturePolyfillConfig& cfg) {
     auto result = ValidateAndDumpIfNeeded(ir, "glsl.TexturePolyfill");
     if (result != Success) {
         return result.Failure();
diff --git a/src/tint/lang/glsl/writer/raise/texture_polyfill.h b/src/tint/lang/glsl/writer/raise/texture_polyfill.h
index a52a727..ea02636e 100644
--- a/src/tint/lang/glsl/writer/raise/texture_polyfill.h
+++ b/src/tint/lang/glsl/writer/raise/texture_polyfill.h
@@ -29,7 +29,7 @@
 #define SRC_TINT_LANG_GLSL_WRITER_RAISE_TEXTURE_POLYFILL_H_
 
 #include "src/tint/lang/glsl/writer/common/options.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -59,7 +59,8 @@
 /// @param module the module to transform
 /// @param cfg the configuration
 /// @returns success or failure
-Result<SuccessType> TexturePolyfill(core::ir::Module& module, const TexturePolyfillConfig& cfg);
+diag::Result<SuccessType> TexturePolyfill(core::ir::Module& module,
+                                          const TexturePolyfillConfig& cfg);
 
 }  // namespace tint::glsl::writer::raise
 
diff --git a/src/tint/lang/glsl/writer/writer.cc b/src/tint/lang/glsl/writer/writer.cc
index fd245b8..e6f2d8d 100644
--- a/src/tint/lang/glsl/writer/writer.cc
+++ b/src/tint/lang/glsl/writer/writer.cc
@@ -27,9 +27,6 @@
 
 #include "src/tint/lang/glsl/writer/writer.h"
 
-#include <memory>
-#include <utility>
-
 #include "src/tint/lang/core/ir/core_builtin_call.h"
 #include "src/tint/lang/core/ir/module.h"
 #include "src/tint/lang/core/ir/var.h"
@@ -40,11 +37,11 @@
 
 namespace tint::glsl::writer {
 
-Result<SuccessType> CanGenerate(const core::ir::Module& ir, const Options& options) {
+diag::Result<SuccessType> CanGenerate(const core::ir::Module& ir, const Options& options) {
     // Check for unsupported types.
     for (auto* ty : ir.Types()) {
         if (ty->Is<core::type::SubgroupMatrix>()) {
-            return Failure("subgroup matrices are not supported by the GLSL backend");
+            return diag::Failure("subgroup matrices are not supported by the GLSL backend");
         }
     }
 
@@ -62,7 +59,7 @@
 
         // The pixel_local extension is not supported by the GLSL backend.
         if (ptr->AddressSpace() == core::AddressSpace::kPixelLocal) {
-            return Failure("pixel_local address space is not supported by the GLSL backend");
+            return diag::Failure("pixel_local address space is not supported by the GLSL backend");
         }
 
         if (ptr->StoreType()->Is<core::type::Texture>()) {
@@ -76,7 +73,7 @@
                 }
             }
             if (!found) {
-                return Failure("texture missing from texture_builtins_from_uniform list");
+                return diag::Failure("texture missing from texture_builtins_from_uniform list");
             }
 
             // Check texel formats for read-write storage textures when targeting ES.
@@ -89,7 +86,8 @@
                             case core::TexelFormat::kR32Uint:
                                 break;
                             default:
-                                return Failure("unsupported read-write storage texture format");
+                                return diag::Failure(
+                                    "unsupported read-write storage texture format");
                         }
                     }
                 }
@@ -99,7 +97,7 @@
         if (ptr->AddressSpace() == core::AddressSpace::kPushConstant) {
             if (user_push_constant_size > 0) {
                 // We've already seen a user-declared push constant.
-                return Failure("multiple user-declared push constants");
+                return diag::Failure("multiple user-declared push constants");
             }
             user_push_constant_size = tint::RoundUp(4u, ptr->StoreType()->Size());
         }
@@ -113,10 +111,10 @@
         }
 
         if (core::IsSubgroup(call->Func())) {
-            return Failure("subgroups are not supported by the GLSL backend");
+            return diag::Failure("subgroups are not supported by the GLSL backend");
         }
         if (call->Func() == core::BuiltinFn::kInputAttachmentLoad) {
-            return Failure("input attachments are not supported by the GLSL backend");
+            return diag::Failure("input attachments are not supported by the GLSL backend");
         }
     }
 
@@ -132,13 +130,13 @@
                 for (auto* member : str->Members()) {
                     if (member->Attributes().builtin == core::BuiltinValue::kSubgroupInvocationId ||
                         member->Attributes().builtin == core::BuiltinValue::kSubgroupSize) {
-                        return Failure("subgroups are not supported by the GLSL backend");
+                        return diag::Failure("subgroups are not supported by the GLSL backend");
                     }
                 }
             } else {
                 if (param->Builtin() == core::BuiltinValue::kSubgroupInvocationId ||
                     param->Builtin() == core::BuiltinValue::kSubgroupSize) {
-                    return Failure("subgroups are not supported by the GLSL backend");
+                    return diag::Failure("subgroups are not supported by the GLSL backend");
                 }
             }
         }
@@ -147,7 +145,7 @@
         if (auto* str = func->ReturnType()->As<core::type::Struct>()) {
             for (auto* member : str->Members()) {
                 if (member->Attributes().builtin == core::BuiltinValue::kClipDistances) {
-                    return Failure("clip_distances is not supported by the GLSL backend");
+                    return diag::Failure("clip_distances is not supported by the GLSL backend");
                 }
             }
         }
@@ -177,24 +175,24 @@
 
     if (options.first_instance_offset &&
         !check_push_constant_offset(*options.first_instance_offset)) {
-        return Failure("invalid offset for first_instance_offset push constant");
+        return diag::Failure("invalid offset for first_instance_offset push constant");
     }
 
     if (options.first_vertex_offset && !check_push_constant_offset(*options.first_vertex_offset)) {
-        return Failure("invalid offset for first_vertex_offset push constant");
+        return diag::Failure("invalid offset for first_vertex_offset push constant");
     }
 
     if (options.depth_range_offsets) {
         if (!check_push_constant_offset(options.depth_range_offsets->max) ||
             !check_push_constant_offset(options.depth_range_offsets->min)) {
-            return Failure("invalid offsets for depth range push constants");
+            return diag::Failure("invalid offsets for depth range push constants");
         }
     }
 
     return Success;
 }
 
-Result<Output> Generate(core::ir::Module& ir, const Options& options, const std::string&) {
+diag::Result<Output> Generate(core::ir::Module& ir, const Options& options, const std::string&) {
     // Raise from core-dialect to GLSL-dialect.
     if (auto res = Raise(ir, options); res != Success) {
         return res.Failure();
diff --git a/src/tint/lang/glsl/writer/writer.h b/src/tint/lang/glsl/writer/writer.h
index 73b298a..c2572f4 100644
--- a/src/tint/lang/glsl/writer/writer.h
+++ b/src/tint/lang/glsl/writer/writer.h
@@ -33,7 +33,6 @@
 #include "src/tint/lang/glsl/writer/common/options.h"
 #include "src/tint/lang/glsl/writer/common/output.h"
 #include "src/tint/utils/diagnostic/diagnostic.h"
-#include "src/tint/utils/result/result.h"
 
 // Forward declarations
 namespace tint {
@@ -49,7 +48,7 @@
 /// @param ir the module
 /// @param options the writer options
 /// @returns Success or a failure message indicating why GLSL generation would fail
-Result<SuccessType> CanGenerate(const core::ir::Module& ir, const Options& options);
+diag::Result<SuccessType> CanGenerate(const core::ir::Module& ir, const Options& options);
 
 /// Generate GLSL for a program, according to a set of configuration options.
 /// The result will contain the GLSL and supplementary information, or failure.
@@ -58,9 +57,9 @@
 /// @param options the configuration options to use when generating GLSL
 /// @param entry_point the entry point to generate GLSL for
 /// @returns the resulting GLSL and supplementary information, or failure
-Result<Output> Generate(core::ir::Module& ir,
-                        const Options& options,
-                        const std::string& entry_point);
+diag::Result<Output> Generate(core::ir::Module& ir,
+                              const Options& options,
+                              const std::string& entry_point);
 
 }  // namespace tint::glsl::writer
 
diff --git a/src/tint/lang/glsl/writer/writer_fuzz.cc b/src/tint/lang/glsl/writer/writer_fuzz.cc
index 88e04a1..6804c70 100644
--- a/src/tint/lang/glsl/writer/writer_fuzz.cc
+++ b/src/tint/lang/glsl/writer/writer_fuzz.cc
@@ -105,7 +105,7 @@
     return options;
 }
 
-Result<SuccessType> IRFuzzer(core::ir::Module& module, const fuzz::ir::Context& context) {
+diag::Result<SuccessType> IRFuzzer(core::ir::Module& module, const fuzz::ir::Context& context) {
     // TODO(375388101): We cannot run the backend for every entry point in the module unless we
     // clone the whole module each time, so for now we just generate the first entry point.
 
diff --git a/src/tint/lang/hlsl/writer/ast_raise/pixel_local.cc b/src/tint/lang/hlsl/writer/ast_raise/pixel_local.cc
index eebce4e..1af2c25 100644
--- a/src/tint/lang/hlsl/writer/ast_raise/pixel_local.cc
+++ b/src/tint/lang/hlsl/writer/ast_raise/pixel_local.cc
@@ -31,7 +31,6 @@
 #include <utility>
 
 #include "src/tint/lang/core/fluent_types.h"
-#include "src/tint/lang/core/number.h"
 #include "src/tint/lang/wgsl/program/clone_context.h"
 #include "src/tint/lang/wgsl/resolver/resolve.h"
 #include "src/tint/lang/wgsl/sem/function.h"
@@ -42,7 +41,6 @@
 #include "src/tint/utils/diagnostic/diagnostic.h"
 #include "src/tint/utils/result/result.h"
 #include "src/tint/utils/rtti/switch.h"
-#include "src/tint/utils/text/text_style.h"
 
 TINT_INSTANTIATE_TYPEINFO(tint::hlsl::writer::PixelLocal);
 TINT_INSTANTIATE_TYPEINFO(tint::hlsl::writer::PixelLocal::RasterizerOrderedView);
@@ -146,9 +144,9 @@
     /// @param entry_point the entry point
     /// @param pixel_local_var the `var<pixel_local>`
     /// @param pixel_local_str the struct type of the var
-    Result<SuccessType> TransformEntryPoint(const sem::Function* entry_point,
-                                            const sem::GlobalVariable* pixel_local_var,
-                                            const sem::Struct* pixel_local_str) {
+    diag::Result<SuccessType> TransformEntryPoint(const sem::Function* entry_point,
+                                                  const sem::GlobalVariable* pixel_local_var,
+                                                  const sem::Struct* pixel_local_str) {
         // Wrap the old entry point "fn" into a new entry point where functions to load and store
         // ROV data are called.
         auto* original_entry_point_fn = entry_point->Declaration();
@@ -296,7 +294,7 @@
     /// @param store_rov_function_name the name of the function that stores the data into the ROVs
     /// @param pixel_local_variable_name the name of the pixel local variable
     /// @param pixel_local_str the struct type of the pixel local variable
-    Result<SuccessType> DeclareROVsAndLoadStoreFunctions(
+    diag::Result<SuccessType> DeclareROVsAndLoadStoreFunctions(
         const Symbol& load_rov_function_name,
         const Symbol& store_rov_function_name,
         const std::string& pixel_local_variable_name,
@@ -474,14 +472,14 @@
 
     /// @returns the texel format for the pixel local field with the given index
     /// @param field_index the pixel local field index
-    Result<core::TexelFormat> ROVTexelFormat(uint32_t field_index) {
+    diag::Result<core::TexelFormat> ROVTexelFormat(uint32_t field_index) {
         auto format = cfg.pls_member_to_rov_format.Get(field_index);
         if (DAWN_UNLIKELY(!format)) {
             diag::Diagnostic err;
             err.severity = diag::Severity::Error;
             err.message << "PixelLocal::Config::attachments missing entry for field "
                         << field_index;
-            return Failure{std::move(err)};
+            return diag::Failure{std::move(err)};
         }
         return *format;
     }
diff --git a/src/tint/lang/hlsl/writer/common/option_helpers.cc b/src/tint/lang/hlsl/writer/common/option_helpers.cc
index dcb4fe1..19bd319 100644
--- a/src/tint/lang/hlsl/writer/common/option_helpers.cc
+++ b/src/tint/lang/hlsl/writer/common/option_helpers.cc
@@ -29,14 +29,14 @@
 
 #include <utility>
 
-#include "src/tint/utils/containers/hashset.h"
+#include "src/tint/utils/containers/hashmap.h"
 
 namespace tint::hlsl::writer {
 
 /// binding::BindingInfo to tint::BindingPoint map
 using InfoToPointMap = tint::Hashmap<binding::BindingInfo, tint::BindingPoint, 8>;
 
-Result<SuccessType> ValidateBindingOptions(const Options& options) {
+diag::Result<SuccessType> ValidateBindingOptions(const Options& options) {
     diag::List diagnostics;
 
     tint::Hashmap<tint::BindingPoint, binding::BindingInfo, 8> seen_wgsl_bindings{};
@@ -94,27 +94,27 @@
     // Storage and uniform are both [[buffer()]]
     if (!valid(seen_hlsl_buffer_bindings, options.bindings.uniform)) {
         diagnostics.AddNote(Source{}) << "when processing uniform";
-        return Failure{std::move(diagnostics)};
+        return diag::Failure{std::move(diagnostics)};
     }
     if (!valid(seen_hlsl_buffer_bindings, options.bindings.storage)) {
         diagnostics.AddNote(Source{}) << "when processing storage";
-        return Failure{std::move(diagnostics)};
+        return diag::Failure{std::move(diagnostics)};
     }
 
     // Sampler is [[sampler()]]
     if (!valid(seen_hlsl_sampler_bindings, options.bindings.sampler)) {
         diagnostics.AddNote(Source{}) << "when processing sampler";
-        return Failure{std::move(diagnostics)};
+        return diag::Failure{std::move(diagnostics)};
     }
 
     // Texture and storage texture are [[texture()]]
     if (!valid(seen_hlsl_texture_bindings, options.bindings.texture)) {
         diagnostics.AddNote(Source{}) << "when processing texture";
-        return Failure{std::move(diagnostics)};
+        return diag::Failure{std::move(diagnostics)};
     }
     if (!valid(seen_hlsl_texture_bindings, options.bindings.storage_texture)) {
         diagnostics.AddNote(Source{}) << "when processing storage_texture";
-        return Failure{std::move(diagnostics)};
+        return diag::Failure{std::move(diagnostics)};
     }
 
     for (const auto& it : options.bindings.external_texture) {
@@ -126,22 +126,22 @@
         // Validate with the actual source regardless of what the remapper will do
         if (wgsl_seen(src_binding, plane0)) {
             diagnostics.AddNote(Source{}) << "when processing external_texture";
-            return Failure{std::move(diagnostics)};
+            return diag::Failure{std::move(diagnostics)};
         }
 
         // Plane0 & Plane1 are [[texture()]]
         if (hlsl_seen(seen_hlsl_texture_bindings, plane0, src_binding)) {
             diagnostics.AddNote(Source{}) << "when processing external_texture";
-            return Failure{std::move(diagnostics)};
+            return diag::Failure{std::move(diagnostics)};
         }
         if (hlsl_seen(seen_hlsl_texture_bindings, plane1, src_binding)) {
             diagnostics.AddNote(Source{}) << "when processing external_texture";
-            return Failure{std::move(diagnostics)};
+            return diag::Failure{std::move(diagnostics)};
         }
         // Metadata is [[buffer()]]
         if (hlsl_seen(seen_hlsl_buffer_bindings, metadata, src_binding)) {
             diagnostics.AddNote(Source{}) << "when processing external_texture";
-            return Failure{std::move(diagnostics)};
+            return diag::Failure{std::move(diagnostics)};
         }
     }
 
diff --git a/src/tint/lang/hlsl/writer/common/option_helpers.h b/src/tint/lang/hlsl/writer/common/option_helpers.h
index 0dfd764..df52ab7 100644
--- a/src/tint/lang/hlsl/writer/common/option_helpers.h
+++ b/src/tint/lang/hlsl/writer/common/option_helpers.h
@@ -34,7 +34,6 @@
 #include "src/tint/lang/core/common/multiplanar_options.h"
 #include "src/tint/lang/hlsl/writer/common/options.h"
 #include "src/tint/utils/diagnostic/diagnostic.h"
-#include "src/tint/utils/result/result.h"
 
 namespace tint::hlsl::writer {
 
@@ -43,7 +42,7 @@
 
 /// @param options the options
 /// @returns success or failure
-Result<SuccessType> ValidateBindingOptions(const Options& options);
+diag::Result<SuccessType> ValidateBindingOptions(const Options& options);
 
 /// Populates binding-related option from the writer options
 /// @param options the writer options
diff --git a/src/tint/lang/hlsl/writer/printer/printer.cc b/src/tint/lang/hlsl/writer/printer/printer.cc
index 8f8ad4c..91855eb 100644
--- a/src/tint/lang/hlsl/writer/printer/printer.cc
+++ b/src/tint/lang/hlsl/writer/printer/printer.cc
@@ -172,7 +172,7 @@
         : ir_(module), options_(options) {}
 
     /// @returns the generated HLSL shader
-    tint::Result<Output> Generate() {
+    diag::Result<Output> Generate() {
         core::ir::Capabilities capabilities{
             core::ir::Capability::kAllowModuleScopeLets,
             core::ir::Capability::kAllowVectorElementPointer,
@@ -2372,7 +2372,7 @@
 
 }  // namespace
 
-Result<Output> Print(core::ir::Module& module, const Options& options) {
+diag::Result<Output> Print(core::ir::Module& module, const Options& options) {
     return Printer{module, options}.Generate();
 }
 
diff --git a/src/tint/lang/hlsl/writer/printer/printer.h b/src/tint/lang/hlsl/writer/printer/printer.h
index e0013f1..c57023b 100644
--- a/src/tint/lang/hlsl/writer/printer/printer.h
+++ b/src/tint/lang/hlsl/writer/printer/printer.h
@@ -28,11 +28,9 @@
 #ifndef SRC_TINT_LANG_HLSL_WRITER_PRINTER_PRINTER_H_
 #define SRC_TINT_LANG_HLSL_WRITER_PRINTER_PRINTER_H_
 
-#include <string>
-
 #include "src/tint/lang/hlsl/writer/common/options.h"
 #include "src/tint/lang/hlsl/writer/common/output.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations
 namespace tint::core::ir {
@@ -44,7 +42,7 @@
 /// @param module the Tint IR module to generate
 /// @param options the printer options
 /// @returns the result of printing the HLSL shader on success, or failure
-Result<Output> Print(core::ir::Module& module, const Options& options);
+diag::Result<Output> Print(core::ir::Module& module, const Options& options);
 
 }  // namespace tint::hlsl::writer
 
diff --git a/src/tint/lang/hlsl/writer/raise/binary_polyfill.cc b/src/tint/lang/hlsl/writer/raise/binary_polyfill.cc
index 542f5fb..e67927c 100644
--- a/src/tint/lang/hlsl/writer/raise/binary_polyfill.cc
+++ b/src/tint/lang/hlsl/writer/raise/binary_polyfill.cc
@@ -136,7 +136,7 @@
 
 }  // namespace
 
-Result<SuccessType> BinaryPolyfill(core::ir::Module& ir) {
+diag::Result<SuccessType> BinaryPolyfill(core::ir::Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "hlsl.BinaryPolyfill",
                                           core::ir::Capabilities{
                                               core::ir::Capability::kAllowClipDistancesOnF32,
diff --git a/src/tint/lang/hlsl/writer/raise/binary_polyfill.h b/src/tint/lang/hlsl/writer/raise/binary_polyfill.h
index 8939802..716bd02 100644
--- a/src/tint/lang/hlsl/writer/raise/binary_polyfill.h
+++ b/src/tint/lang/hlsl/writer/raise/binary_polyfill.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_HLSL_WRITER_RAISE_BINARY_POLYFILL_H_
 #define SRC_TINT_LANG_HLSL_WRITER_RAISE_BINARY_POLYFILL_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -43,7 +43,7 @@
 ///
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> BinaryPolyfill(core::ir::Module& module);
+diag::Result<SuccessType> BinaryPolyfill(core::ir::Module& module);
 
 }  // namespace tint::hlsl::writer::raise
 
diff --git a/src/tint/lang/hlsl/writer/raise/builtin_polyfill.cc b/src/tint/lang/hlsl/writer/raise/builtin_polyfill.cc
index 180c1e6..d978dcb 100644
--- a/src/tint/lang/hlsl/writer/raise/builtin_polyfill.cc
+++ b/src/tint/lang/hlsl/writer/raise/builtin_polyfill.cc
@@ -1934,7 +1934,7 @@
 
 }  // namespace
 
-Result<SuccessType> BuiltinPolyfill(core::ir::Module& ir) {
+diag::Result<SuccessType> BuiltinPolyfill(core::ir::Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "hlsl.BuiltinPolyfill",
                                           core::ir::Capabilities{
                                               core::ir::Capability::kAllowClipDistancesOnF32,
diff --git a/src/tint/lang/hlsl/writer/raise/builtin_polyfill.h b/src/tint/lang/hlsl/writer/raise/builtin_polyfill.h
index c161f05..c2863ac 100644
--- a/src/tint/lang/hlsl/writer/raise/builtin_polyfill.h
+++ b/src/tint/lang/hlsl/writer/raise/builtin_polyfill.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_HLSL_WRITER_RAISE_BUILTIN_POLYFILL_H_
 #define SRC_TINT_LANG_HLSL_WRITER_RAISE_BUILTIN_POLYFILL_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -42,7 +42,7 @@
 /// HLSL polyfilled or backend intrinsic functions.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> BuiltinPolyfill(core::ir::Module& module);
+diag::Result<SuccessType> BuiltinPolyfill(core::ir::Module& module);
 
 }  // namespace tint::hlsl::writer::raise
 
diff --git a/src/tint/lang/hlsl/writer/raise/decompose_storage_access.cc b/src/tint/lang/hlsl/writer/raise/decompose_storage_access.cc
index 3337ade..66417f2 100644
--- a/src/tint/lang/hlsl/writer/raise/decompose_storage_access.cc
+++ b/src/tint/lang/hlsl/writer/raise/decompose_storage_access.cc
@@ -899,7 +899,7 @@
 
 }  // namespace
 
-Result<SuccessType> DecomposeStorageAccess(core::ir::Module& ir) {
+diag::Result<SuccessType> DecomposeStorageAccess(core::ir::Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "hlsl.DecomposeStorageAccess",
                                           core::ir::Capabilities{
                                               core::ir::Capability::kAllowClipDistancesOnF32,
diff --git a/src/tint/lang/hlsl/writer/raise/decompose_storage_access.h b/src/tint/lang/hlsl/writer/raise/decompose_storage_access.h
index 6952593..3c5c657 100644
--- a/src/tint/lang/hlsl/writer/raise/decompose_storage_access.h
+++ b/src/tint/lang/hlsl/writer/raise/decompose_storage_access.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_HLSL_WRITER_RAISE_DECOMPOSE_STORAGE_ACCESS_H_
 #define SRC_TINT_LANG_HLSL_WRITER_RAISE_DECOMPOSE_STORAGE_ACCESS_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -42,7 +42,7 @@
 ///
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> DecomposeStorageAccess(core::ir::Module& module);
+diag::Result<SuccessType> DecomposeStorageAccess(core::ir::Module& module);
 
 }  // namespace tint::hlsl::writer::raise
 
diff --git a/src/tint/lang/hlsl/writer/raise/decompose_uniform_access.cc b/src/tint/lang/hlsl/writer/raise/decompose_uniform_access.cc
index 406d6ad..fb4a528 100644
--- a/src/tint/lang/hlsl/writer/raise/decompose_uniform_access.cc
+++ b/src/tint/lang/hlsl/writer/raise/decompose_uniform_access.cc
@@ -617,7 +617,7 @@
 
 }  // namespace
 
-Result<SuccessType> DecomposeUniformAccess(core::ir::Module& ir) {
+diag::Result<SuccessType> DecomposeUniformAccess(core::ir::Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "hlsl.DecomposeUniformAccess",
                                           core::ir::Capabilities{
                                               core::ir::Capability::kAllowClipDistancesOnF32,
diff --git a/src/tint/lang/hlsl/writer/raise/decompose_uniform_access.h b/src/tint/lang/hlsl/writer/raise/decompose_uniform_access.h
index f242dc6..9473206 100644
--- a/src/tint/lang/hlsl/writer/raise/decompose_uniform_access.h
+++ b/src/tint/lang/hlsl/writer/raise/decompose_uniform_access.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_HLSL_WRITER_RAISE_DECOMPOSE_UNIFORM_ACCESS_H_
 #define SRC_TINT_LANG_HLSL_WRITER_RAISE_DECOMPOSE_UNIFORM_ACCESS_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -42,7 +42,7 @@
 ///
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> DecomposeUniformAccess(core::ir::Module& module);
+diag::Result<SuccessType> DecomposeUniformAccess(core::ir::Module& module);
 
 }  // namespace tint::hlsl::writer::raise
 
diff --git a/src/tint/lang/hlsl/writer/raise/localize_struct_array_assignment.cc b/src/tint/lang/hlsl/writer/raise/localize_struct_array_assignment.cc
index c5d08d7..0530423 100644
--- a/src/tint/lang/hlsl/writer/raise/localize_struct_array_assignment.cc
+++ b/src/tint/lang/hlsl/writer/raise/localize_struct_array_assignment.cc
@@ -157,7 +157,7 @@
 
 }  // namespace
 
-Result<SuccessType> LocalizeStructArrayAssignment(core::ir::Module& ir) {
+diag::Result<SuccessType> LocalizeStructArrayAssignment(core::ir::Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "hlsl.LocalizeStructArrayAssignment");
     if (result != Success) {
         return result.Failure();
diff --git a/src/tint/lang/hlsl/writer/raise/localize_struct_array_assignment.h b/src/tint/lang/hlsl/writer/raise/localize_struct_array_assignment.h
index 1e775d6..87587ef 100644
--- a/src/tint/lang/hlsl/writer/raise/localize_struct_array_assignment.h
+++ b/src/tint/lang/hlsl/writer/raise/localize_struct_array_assignment.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_HLSL_WRITER_RAISE_LOCALIZE_STRUCT_ARRAY_ASSIGNMENT_H_
 #define SRC_TINT_LANG_HLSL_WRITER_RAISE_LOCALIZE_STRUCT_ARRAY_ASSIGNMENT_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -52,7 +52,7 @@
 
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> LocalizeStructArrayAssignment(core::ir::Module& module);
+diag::Result<SuccessType> LocalizeStructArrayAssignment(core::ir::Module& module);
 
 }  // namespace tint::hlsl::writer::raise
 
diff --git a/src/tint/lang/hlsl/writer/raise/pixel_local.cc b/src/tint/lang/hlsl/writer/raise/pixel_local.cc
index 55cb522..bc34a24 100644
--- a/src/tint/lang/hlsl/writer/raise/pixel_local.cc
+++ b/src/tint/lang/hlsl/writer/raise/pixel_local.cc
@@ -242,7 +242,7 @@
 
 }  // namespace
 
-Result<SuccessType> PixelLocal(core::ir::Module& ir, const PixelLocalConfig& config) {
+diag::Result<SuccessType> PixelLocal(core::ir::Module& ir, const PixelLocalConfig& config) {
     auto result = ValidateAndDumpIfNeeded(ir, "hlsl.PixelLocal",
                                           core::ir::Capabilities{
                                               core::ir::Capability::kAllowClipDistancesOnF32,
diff --git a/src/tint/lang/hlsl/writer/raise/pixel_local.h b/src/tint/lang/hlsl/writer/raise/pixel_local.h
index c889d5c..4f8e204 100644
--- a/src/tint/lang/hlsl/writer/raise/pixel_local.h
+++ b/src/tint/lang/hlsl/writer/raise/pixel_local.h
@@ -29,7 +29,7 @@
 #define SRC_TINT_LANG_HLSL_WRITER_RAISE_PIXEL_LOCAL_H_
 
 #include "src/tint/lang/hlsl/writer/common/options.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -46,7 +46,7 @@
 /// PixelLocal is a transform that implements the PixelLocal feature for HLSL.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> PixelLocal(core::ir::Module& module, const PixelLocalConfig& config);
+diag::Result<SuccessType> PixelLocal(core::ir::Module& module, const PixelLocalConfig& config);
 
 }  // namespace tint::hlsl::writer::raise
 
diff --git a/src/tint/lang/hlsl/writer/raise/promote_initializers.cc b/src/tint/lang/hlsl/writer/raise/promote_initializers.cc
index b5f5132..631ca1f 100644
--- a/src/tint/lang/hlsl/writer/raise/promote_initializers.cc
+++ b/src/tint/lang/hlsl/writer/raise/promote_initializers.cc
@@ -237,7 +237,7 @@
 
 }  // namespace
 
-Result<SuccessType> PromoteInitializers(core::ir::Module& ir) {
+diag::Result<SuccessType> PromoteInitializers(core::ir::Module& ir) {
     auto result =
         ValidateAndDumpIfNeeded(ir, "hlsl.PromoteInitializers", kPromoteInitializersCapabilities);
     if (result != Success) {
diff --git a/src/tint/lang/hlsl/writer/raise/promote_initializers.h b/src/tint/lang/hlsl/writer/raise/promote_initializers.h
index 8c80001..d1845a1 100644
--- a/src/tint/lang/hlsl/writer/raise/promote_initializers.h
+++ b/src/tint/lang/hlsl/writer/raise/promote_initializers.h
@@ -29,7 +29,7 @@
 #define SRC_TINT_LANG_HLSL_WRITER_RAISE_PROMOTE_INITIALIZERS_H_
 
 #include "src/tint/lang/core/ir/validator.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -79,7 +79,7 @@
 ///
 /// @param module the module to transform
 /// @returns error diagnostics on failure
-Result<SuccessType> PromoteInitializers(core::ir::Module& module);
+diag::Result<SuccessType> PromoteInitializers(core::ir::Module& module);
 
 }  // namespace tint::hlsl::writer::raise
 
diff --git a/src/tint/lang/hlsl/writer/raise/promote_initializers_fuzz.cc b/src/tint/lang/hlsl/writer/raise/promote_initializers_fuzz.cc
index 59d7a28..db191ae 100644
--- a/src/tint/lang/hlsl/writer/raise/promote_initializers_fuzz.cc
+++ b/src/tint/lang/hlsl/writer/raise/promote_initializers_fuzz.cc
@@ -34,7 +34,8 @@
 namespace tint::hlsl::writer::raise {
 namespace {
 
-Result<SuccessType> PromoteInitializersFuzzer(core::ir::Module& ir, const fuzz::ir::Context&) {
+diag::Result<SuccessType> PromoteInitializersFuzzer(core::ir::Module& ir,
+                                                    const fuzz::ir::Context&) {
     return PromoteInitializers(ir);
 }
 
diff --git a/src/tint/lang/hlsl/writer/raise/raise.cc b/src/tint/lang/hlsl/writer/raise/raise.cc
index 62c9945..fea6c8b 100644
--- a/src/tint/lang/hlsl/writer/raise/raise.cc
+++ b/src/tint/lang/hlsl/writer/raise/raise.cc
@@ -63,7 +63,7 @@
 
 namespace tint::hlsl::writer {
 
-Result<SuccessType> Raise(core::ir::Module& module, const Options& options) {
+diag::Result<SuccessType> Raise(core::ir::Module& module, const Options& options) {
 #define RUN_TRANSFORM(name, ...)         \
     do {                                 \
         auto result = name(__VA_ARGS__); \
diff --git a/src/tint/lang/hlsl/writer/raise/raise.h b/src/tint/lang/hlsl/writer/raise/raise.h
index 8b9c04e..ab9cc8b 100644
--- a/src/tint/lang/hlsl/writer/raise/raise.h
+++ b/src/tint/lang/hlsl/writer/raise/raise.h
@@ -29,7 +29,7 @@
 #define SRC_TINT_LANG_HLSL_WRITER_RAISE_RAISE_H_
 
 #include "src/tint/lang/hlsl/writer/common/options.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations
 namespace tint::core::ir {
@@ -42,7 +42,7 @@
 /// @param module the core IR module to raise to HLSL dialect
 /// @param options the printer options
 /// @returns success or failure
-Result<SuccessType> Raise(core::ir::Module& module, const Options& options);
+diag::Result<SuccessType> Raise(core::ir::Module& module, const Options& options);
 
 }  // namespace tint::hlsl::writer
 
diff --git a/src/tint/lang/hlsl/writer/raise/replace_default_only_switch.cc b/src/tint/lang/hlsl/writer/raise/replace_default_only_switch.cc
index 10a44b1..3c78234 100644
--- a/src/tint/lang/hlsl/writer/raise/replace_default_only_switch.cc
+++ b/src/tint/lang/hlsl/writer/raise/replace_default_only_switch.cc
@@ -35,7 +35,6 @@
 #include "src/tint/lang/core/ir/validator.h"
 #include "src/tint/lang/core/type/manager.h"
 #include "src/tint/utils/containers/vector.h"
-#include "src/tint/utils/ice/ice.h"
 #include "src/tint/utils/result/result.h"
 
 namespace tint::hlsl::writer::raise {
@@ -99,7 +98,7 @@
 
 }  // namespace
 
-Result<SuccessType> ReplaceDefaultOnlySwitch(core::ir::Module& ir) {
+diag::Result<SuccessType> ReplaceDefaultOnlySwitch(core::ir::Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "hlsl.ReplaceDefaultOnlySwitch");
     if (result != Success) {
         return result.Failure();
diff --git a/src/tint/lang/hlsl/writer/raise/replace_default_only_switch.h b/src/tint/lang/hlsl/writer/raise/replace_default_only_switch.h
index b11d052..33db4b3 100644
--- a/src/tint/lang/hlsl/writer/raise/replace_default_only_switch.h
+++ b/src/tint/lang/hlsl/writer/raise/replace_default_only_switch.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_HLSL_WRITER_RAISE_REPLACE_DEFAULT_ONLY_SWITCH_H_
 #define SRC_TINT_LANG_HLSL_WRITER_RAISE_REPLACE_DEFAULT_ONLY_SWITCH_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -42,7 +42,7 @@
 /// it to miscompile default-only-switch statements. See crbug.com/tint/1188.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> ReplaceDefaultOnlySwitch(core::ir::Module& module);
+diag::Result<SuccessType> ReplaceDefaultOnlySwitch(core::ir::Module& module);
 
 }  // namespace tint::hlsl::writer::raise
 
diff --git a/src/tint/lang/hlsl/writer/raise/replace_non_indexable_mat_vec_stores.cc b/src/tint/lang/hlsl/writer/raise/replace_non_indexable_mat_vec_stores.cc
index c6250c9..fba1e6b 100644
--- a/src/tint/lang/hlsl/writer/raise/replace_non_indexable_mat_vec_stores.cc
+++ b/src/tint/lang/hlsl/writer/raise/replace_non_indexable_mat_vec_stores.cc
@@ -286,7 +286,7 @@
 
 }  // namespace
 
-Result<SuccessType> ReplaceNonIndexableMatVecStores(core::ir::Module& ir) {
+diag::Result<SuccessType> ReplaceNonIndexableMatVecStores(core::ir::Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "hlsl.ReplaceNonIndexableMatVecStores");
     if (result != Success) {
         return result.Failure();
diff --git a/src/tint/lang/hlsl/writer/raise/replace_non_indexable_mat_vec_stores.h b/src/tint/lang/hlsl/writer/raise/replace_non_indexable_mat_vec_stores.h
index d109116..4a9bd5e 100644
--- a/src/tint/lang/hlsl/writer/raise/replace_non_indexable_mat_vec_stores.h
+++ b/src/tint/lang/hlsl/writer/raise/replace_non_indexable_mat_vec_stores.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_HLSL_WRITER_RAISE_REPLACE_NON_INDEXABLE_MAT_VEC_STORES_H_
 #define SRC_TINT_LANG_HLSL_WRITER_RAISE_REPLACE_NON_INDEXABLE_MAT_VEC_STORES_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -50,7 +50,7 @@
 
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> ReplaceNonIndexableMatVecStores(core::ir::Module& module);
+diag::Result<SuccessType> ReplaceNonIndexableMatVecStores(core::ir::Module& module);
 
 }  // namespace tint::hlsl::writer::raise
 
diff --git a/src/tint/lang/hlsl/writer/raise/shader_io.cc b/src/tint/lang/hlsl/writer/raise/shader_io.cc
index 82ba776..9b94cc7 100644
--- a/src/tint/lang/hlsl/writer/raise/shader_io.cc
+++ b/src/tint/lang/hlsl/writer/raise/shader_io.cc
@@ -523,7 +523,7 @@
 };
 }  // namespace
 
-Result<SuccessType> ShaderIO(core::ir::Module& ir, const ShaderIOConfig& config) {
+diag::Result<SuccessType> ShaderIO(core::ir::Module& ir, const ShaderIOConfig& config) {
     auto result = ValidateAndDumpIfNeeded(ir, "hlsl.ShaderIO");
     if (result != Success) {
         return result;
diff --git a/src/tint/lang/hlsl/writer/raise/shader_io.h b/src/tint/lang/hlsl/writer/raise/shader_io.h
index 9053377..fc21687 100644
--- a/src/tint/lang/hlsl/writer/raise/shader_io.h
+++ b/src/tint/lang/hlsl/writer/raise/shader_io.h
@@ -32,7 +32,7 @@
 #include <optional>
 
 #include "src/tint/api/common/binding_point.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -70,7 +70,7 @@
 /// entry point parameter, and all outputs are wrapped in a struct and returned by the entry point.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> ShaderIO(core::ir::Module& module, const ShaderIOConfig& config);
+diag::Result<SuccessType> ShaderIO(core::ir::Module& module, const ShaderIOConfig& config);
 
 }  // namespace tint::hlsl::writer::raise
 
diff --git a/src/tint/lang/hlsl/writer/writer.cc b/src/tint/lang/hlsl/writer/writer.cc
index 7a723df..6e219b8 100644
--- a/src/tint/lang/hlsl/writer/writer.cc
+++ b/src/tint/lang/hlsl/writer/writer.cc
@@ -38,15 +38,14 @@
 #include "src/tint/lang/hlsl/writer/printer/printer.h"
 #include "src/tint/lang/hlsl/writer/raise/raise.h"
 #include "src/tint/lang/wgsl/ast/pipeline_stage.h"
-#include "src/tint/utils/ice/ice.h"
 
 namespace tint::hlsl::writer {
 
-Result<SuccessType> CanGenerate(const core::ir::Module& ir, const Options& options) {
+diag::Result<SuccessType> CanGenerate(const core::ir::Module& ir, const Options& options) {
     // Check for unsupported types.
     for (auto* ty : ir.Types()) {
         if (ty->Is<core::type::SubgroupMatrix>()) {
-            return Failure("subgroup matrices are not supported by the HLSL backend");
+            return diag::Failure("subgroup matrices are not supported by the HLSL backend");
         }
     }
 
@@ -55,26 +54,26 @@
         auto* var = inst->As<core::ir::Var>();
         auto* ptr = var->Result(0)->Type()->As<core::type::Pointer>();
         if (ptr->AddressSpace() == core::AddressSpace::kPushConstant) {
-            return Failure("push constants are not supported by the HLSL backend");
+            return diag::Failure("push constants are not supported by the HLSL backend");
         }
         if (ptr->AddressSpace() == core::AddressSpace::kPixelLocal) {
             // Check the pixel_local variables have corresponding entries in the PLS attachment map.
             auto* str = ptr->StoreType()->As<core::type::Struct>();
             for (uint32_t i = 0; i < str->Members().Length(); i++) {
                 if (options.pixel_local.attachments.count(i) == 0) {
-                    return Failure("missing pixel local attachment for member index " +
-                                   std::to_string(i));
+                    return diag::Failure("missing pixel local attachment for member index " +
+                                         std::to_string(i));
                 }
             }
         }
         if (ptr->StoreType()->Is<core::type::InputAttachment>()) {
-            return Failure("input attachments are not supported by the HLSL backend");
+            return diag::Failure("input attachments are not supported by the HLSL backend");
         }
     }
     return Success;
 }
 
-Result<Output> Generate(core::ir::Module& ir, const Options& options) {
+diag::Result<Output> Generate(core::ir::Module& ir, const Options& options) {
     // Raise the core-dialect to HLSL-dialect
     auto res = Raise(ir, options);
     if (res != Success) {
@@ -84,21 +83,21 @@
     return Print(ir, options);
 }
 
-Result<Output> Generate(const Program& program, const Options& options) {
+diag::Result<Output> Generate(const Program& program, const Options& options) {
     if (!program.IsValid()) {
-        return Failure{program.Diagnostics()};
+        return diag::Failure{program.Diagnostics()};
     }
 
     // Sanitize the program.
     auto sanitized_result = Sanitize(program, options);
     if (!sanitized_result.program.IsValid()) {
-        return Failure{sanitized_result.program.Diagnostics()};
+        return diag::Failure{sanitized_result.program.Diagnostics()};
     }
 
     // Generate the HLSL code.
     auto impl = std::make_unique<ASTPrinter>(sanitized_result.program);
     if (!impl->Generate()) {
-        return Failure{impl->Diagnostics()};
+        return diag::Failure{impl->Diagnostics()};
     }
 
     Output output;
diff --git a/src/tint/lang/hlsl/writer/writer.h b/src/tint/lang/hlsl/writer/writer.h
index be08a15..706a493 100644
--- a/src/tint/lang/hlsl/writer/writer.h
+++ b/src/tint/lang/hlsl/writer/writer.h
@@ -28,12 +28,9 @@
 #ifndef SRC_TINT_LANG_HLSL_WRITER_WRITER_H_
 #define SRC_TINT_LANG_HLSL_WRITER_WRITER_H_
 
-#include <string>
-
 #include "src/tint/lang/hlsl/writer/common/options.h"
 #include "src/tint/lang/hlsl/writer/common/output.h"
 #include "src/tint/utils/diagnostic/diagnostic.h"
-#include "src/tint/utils/result/result.h"
 
 // Forward declarations
 namespace tint {
@@ -49,21 +46,21 @@
 /// @param ir the module
 /// @param options the writer options
 /// @returns Success or a failure message indicating why HLSL generation would fail
-Result<SuccessType> CanGenerate(const core::ir::Module& ir, const Options& options);
+diag::Result<SuccessType> CanGenerate(const core::ir::Module& ir, const Options& options);
 
 /// Generate HLSL for a program, according to a set of configuration options.
 /// The result will contain the HLSL and supplementary information, or failure.
 /// @param ir the IR module to translate to HLSL
 /// @param options the configuration options to use when generating HLSL
 /// @returns the resulting HLSL and supplementary information, or failure
-Result<Output> Generate(core::ir::Module& ir, const Options& options);
+diag::Result<Output> Generate(core::ir::Module& ir, const Options& options);
 
 /// Generate HLSL for a program, according to a set of configuration options.
 /// The result will contain the HLSL and supplementary information, or failure.
 /// @param program the program to translate to HLSL
 /// @param options the configuration options to use when generating HLSL
 /// @returns the resulting HLSL and supplementary information, or failure
-Result<Output> Generate(const Program& program, const Options& options);
+diag::Result<Output> Generate(const Program& program, const Options& options);
 
 }  // namespace tint::hlsl::writer
 
diff --git a/src/tint/lang/hlsl/writer/writer_ast_fuzz.cc b/src/tint/lang/hlsl/writer/writer_ast_fuzz.cc
index 222c64e..4c8579d 100644
--- a/src/tint/lang/hlsl/writer/writer_ast_fuzz.cc
+++ b/src/tint/lang/hlsl/writer/writer_ast_fuzz.cc
@@ -85,7 +85,7 @@
     }
     auto dxc = tint::Command::LookPath(dxc_path);
 
-    Result<tint::hlsl::writer::Output> res;
+    diag::Result<tint::hlsl::writer::Output> res;
     if (dxc.Found()) {
         // If validating with DXC, run renamer transform first to avoid DXC validation failures.
         ast::transform::DataMap inputs, outputs;
diff --git a/src/tint/lang/hlsl/writer/writer_fuzz.cc b/src/tint/lang/hlsl/writer/writer_fuzz.cc
index 954a856..1b31514 100644
--- a/src/tint/lang/hlsl/writer/writer_fuzz.cc
+++ b/src/tint/lang/hlsl/writer/writer_fuzz.cc
@@ -61,9 +61,9 @@
                  compiler_is_dxc);
 };
 
-Result<SuccessType> IRFuzzer(core::ir::Module& module,
-                             const fuzz::ir::Context& context,
-                             FuzzedOptions fuzzed_options) {
+diag::Result<SuccessType> IRFuzzer(core::ir::Module& module,
+                                   const fuzz::ir::Context& context,
+                                   FuzzedOptions fuzzed_options) {
     Options options;
     options.strip_all_names = fuzzed_options.strip_all_names;
     options.disable_robustness = fuzzed_options.disable_robustness;
diff --git a/src/tint/lang/msl/writer/common/option_helpers.cc b/src/tint/lang/msl/writer/common/option_helpers.cc
index 002b32a..d4d184d 100644
--- a/src/tint/lang/msl/writer/common/option_helpers.cc
+++ b/src/tint/lang/msl/writer/common/option_helpers.cc
@@ -29,14 +29,14 @@
 
 #include <utility>
 
-#include "src/tint/utils/containers/hashset.h"
+#include "src/tint/utils/containers/hashmap.h"
 
 namespace tint::msl::writer {
 
 /// binding::BindingInfo to tint::BindingPoint map
 using InfoToPointMap = tint::Hashmap<binding::BindingInfo, tint::BindingPoint, 8>;
 
-Result<SuccessType> ValidateBindingOptions(const Options& options) {
+diag::Result<SuccessType> ValidateBindingOptions(const Options& options) {
     diag::List diagnostics;
 
     tint::Hashmap<tint::BindingPoint, binding::BindingInfo, 8> seen_wgsl_bindings{};
@@ -88,27 +88,27 @@
     // Storage and uniform are both [[buffer()]]
     if (!valid(seen_msl_buffer_bindings, options.bindings.uniform)) {
         diagnostics.AddNote(Source{}) << "when processing uniform";
-        return Failure{std::move(diagnostics)};
+        return diag::Failure{std::move(diagnostics)};
     }
     if (!valid(seen_msl_buffer_bindings, options.bindings.storage)) {
         diagnostics.AddNote(Source{}) << "when processing storage";
-        return Failure{std::move(diagnostics)};
+        return diag::Failure{std::move(diagnostics)};
     }
 
     // Sampler is [[sampler()]]
     if (!valid(seen_msl_sampler_bindings, options.bindings.sampler)) {
         diagnostics.AddNote(Source{}) << "when processing sampler";
-        return Failure{std::move(diagnostics)};
+        return diag::Failure{std::move(diagnostics)};
     }
 
     // Texture and storage texture are [[texture()]]
     if (!valid(seen_msl_texture_bindings, options.bindings.texture)) {
         diagnostics.AddNote(Source{}) << "when processing texture";
-        return Failure{std::move(diagnostics)};
+        return diag::Failure{std::move(diagnostics)};
     }
     if (!valid(seen_msl_texture_bindings, options.bindings.storage_texture)) {
         diagnostics.AddNote(Source{}) << "when processing storage_texture";
-        return Failure{std::move(diagnostics)};
+        return diag::Failure{std::move(diagnostics)};
     }
 
     for (const auto& it : options.bindings.external_texture) {
@@ -120,22 +120,22 @@
         // Validate with the actual source regardless of what the remapper will do
         if (wgsl_seen(src_binding, plane0)) {
             diagnostics.AddNote(Source{}) << "when processing external_texture";
-            return Failure{std::move(diagnostics)};
+            return diag::Failure{std::move(diagnostics)};
         }
 
         // Plane0 & Plane1 are [[texture()]]
         if (msl_seen(seen_msl_texture_bindings, plane0, src_binding)) {
             diagnostics.AddNote(Source{}) << "when processing external_texture";
-            return Failure{std::move(diagnostics)};
+            return diag::Failure{std::move(diagnostics)};
         }
         if (msl_seen(seen_msl_texture_bindings, plane1, src_binding)) {
             diagnostics.AddNote(Source{}) << "when processing external_texture";
-            return Failure{std::move(diagnostics)};
+            return diag::Failure{std::move(diagnostics)};
         }
         // Metadata is [[buffer()]]
         if (msl_seen(seen_msl_buffer_bindings, metadata, src_binding)) {
             diagnostics.AddNote(Source{}) << "when processing external_texture";
-            return Failure{std::move(diagnostics)};
+            return diag::Failure{std::move(diagnostics)};
         }
     }
 
diff --git a/src/tint/lang/msl/writer/common/option_helpers.h b/src/tint/lang/msl/writer/common/option_helpers.h
index 3cc4b8f..570915e 100644
--- a/src/tint/lang/msl/writer/common/option_helpers.h
+++ b/src/tint/lang/msl/writer/common/option_helpers.h
@@ -34,7 +34,6 @@
 #include "src/tint/lang/core/common/multiplanar_options.h"
 #include "src/tint/lang/msl/writer/common/options.h"
 #include "src/tint/utils/diagnostic/diagnostic.h"
-#include "src/tint/utils/result/result.h"
 
 namespace tint::msl::writer {
 
@@ -43,7 +42,7 @@
 
 /// @param options the options
 /// @returns success or failure
-Result<SuccessType> ValidateBindingOptions(const Options& options);
+diag::Result<SuccessType> ValidateBindingOptions(const Options& options);
 
 /// Populates binding-related option from the writer options
 /// @param options the writer options
diff --git a/src/tint/lang/msl/writer/printer/printer.cc b/src/tint/lang/msl/writer/printer/printer.cc
index 496d789..5114b99 100644
--- a/src/tint/lang/msl/writer/printer/printer.cc
+++ b/src/tint/lang/msl/writer/printer/printer.cc
@@ -29,7 +29,7 @@
 
 #include <atomic>
 #include <cstdint>
-#include <memory>
+#include <string>
 #include <utility>
 
 #include "src/tint/lang/core/constant/composite.h"
@@ -123,7 +123,7 @@
         : ir_(module), options_(options) {}
 
     /// @returns the generated MSL shader
-    tint::Result<Output> Generate() {
+    diag::Result<Output> Generate() {
         auto valid = core::ir::ValidateAndDumpIfNeeded(
             ir_, "msl.Printer",
             core::ir::Capabilities{
@@ -2114,7 +2114,7 @@
 
 }  // namespace
 
-Result<Output> Print(core::ir::Module& module, const Options& options) {
+diag::Result<Output> Print(core::ir::Module& module, const Options& options) {
     return Printer{module, options}.Generate();
 }
 
diff --git a/src/tint/lang/msl/writer/printer/printer.h b/src/tint/lang/msl/writer/printer/printer.h
index 4cbdbd5..9d89a948 100644
--- a/src/tint/lang/msl/writer/printer/printer.h
+++ b/src/tint/lang/msl/writer/printer/printer.h
@@ -28,13 +28,9 @@
 #ifndef SRC_TINT_LANG_MSL_WRITER_PRINTER_PRINTER_H_
 #define SRC_TINT_LANG_MSL_WRITER_PRINTER_PRINTER_H_
 
-#include <string>
-#include <unordered_map>
-#include <vector>
-
 #include "src/tint/lang/msl/writer/common/options.h"
 #include "src/tint/lang/msl/writer/common/output.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations
 namespace tint::core::ir {
@@ -45,7 +41,7 @@
 
 /// @param module the Tint IR module to generate
 /// @returns the result of printing the MSL shader on success, or failure
-Result<Output> Print(core::ir::Module& module, const Options& options);
+diag::Result<Output> Print(core::ir::Module& module, const Options& options);
 
 }  // namespace tint::msl::writer
 
diff --git a/src/tint/lang/msl/writer/raise/binary_polyfill.cc b/src/tint/lang/msl/writer/raise/binary_polyfill.cc
index 6ed02d6..d555e93 100644
--- a/src/tint/lang/msl/writer/raise/binary_polyfill.cc
+++ b/src/tint/lang/msl/writer/raise/binary_polyfill.cc
@@ -27,8 +27,6 @@
 
 #include "src/tint/lang/msl/writer/raise/binary_polyfill.h"
 
-#include <utility>
-
 #include "src/tint/lang/core/ir/builder.h"
 #include "src/tint/lang/core/ir/validator.h"
 #include "src/tint/lang/msl/ir/builtin_call.h"
@@ -156,7 +154,7 @@
 
 }  // namespace
 
-Result<SuccessType> BinaryPolyfill(core::ir::Module& ir) {
+diag::Result<SuccessType> BinaryPolyfill(core::ir::Module& ir) {
     auto result =
         ValidateAndDumpIfNeeded(ir, "msl.BinaryPolyfill",
                                 core::ir::Capabilities{
diff --git a/src/tint/lang/msl/writer/raise/binary_polyfill.h b/src/tint/lang/msl/writer/raise/binary_polyfill.h
index 72ec078..7aac7cf 100644
--- a/src/tint/lang/msl/writer/raise/binary_polyfill.h
+++ b/src/tint/lang/msl/writer/raise/binary_polyfill.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_MSL_WRITER_RAISE_BINARY_POLYFILL_H_
 #define SRC_TINT_LANG_MSL_WRITER_RAISE_BINARY_POLYFILL_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -41,7 +41,7 @@
 /// MSL backend intrinsic functions.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> BinaryPolyfill(core::ir::Module& module);
+diag::Result<SuccessType> BinaryPolyfill(core::ir::Module& module);
 
 }  // namespace tint::msl::writer::raise
 
diff --git a/src/tint/lang/msl/writer/raise/builtin_polyfill.cc b/src/tint/lang/msl/writer/raise/builtin_polyfill.cc
index a61b20a..c40e988 100644
--- a/src/tint/lang/msl/writer/raise/builtin_polyfill.cc
+++ b/src/tint/lang/msl/writer/raise/builtin_polyfill.cc
@@ -1058,7 +1058,7 @@
 
 }  // namespace
 
-Result<SuccessType> BuiltinPolyfill(core::ir::Module& ir) {
+diag::Result<SuccessType> BuiltinPolyfill(core::ir::Module& ir) {
     auto result =
         ValidateAndDumpIfNeeded(ir, "msl.BuiltinPolyfill",
                                 core::ir::Capabilities{
diff --git a/src/tint/lang/msl/writer/raise/builtin_polyfill.h b/src/tint/lang/msl/writer/raise/builtin_polyfill.h
index 556bad2..9748d97 100644
--- a/src/tint/lang/msl/writer/raise/builtin_polyfill.h
+++ b/src/tint/lang/msl/writer/raise/builtin_polyfill.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_MSL_WRITER_RAISE_BUILTIN_POLYFILL_H_
 #define SRC_TINT_LANG_MSL_WRITER_RAISE_BUILTIN_POLYFILL_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -41,7 +41,7 @@
 /// MSL backend intrinsic functions.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> BuiltinPolyfill(core::ir::Module& module);
+diag::Result<SuccessType> BuiltinPolyfill(core::ir::Module& module);
 
 }  // namespace tint::msl::writer::raise
 
diff --git a/src/tint/lang/msl/writer/raise/module_scope_vars.cc b/src/tint/lang/msl/writer/raise/module_scope_vars.cc
index c79eaea..a76faf3 100644
--- a/src/tint/lang/msl/writer/raise/module_scope_vars.cc
+++ b/src/tint/lang/msl/writer/raise/module_scope_vars.cc
@@ -341,7 +341,7 @@
 
 }  // namespace
 
-Result<SuccessType> ModuleScopeVars(core::ir::Module& ir) {
+diag::Result<SuccessType> ModuleScopeVars(core::ir::Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "msl.ModuleScopeVars");
     if (result != Success) {
         return result.Failure();
diff --git a/src/tint/lang/msl/writer/raise/module_scope_vars.h b/src/tint/lang/msl/writer/raise/module_scope_vars.h
index f9570e7..c422141 100644
--- a/src/tint/lang/msl/writer/raise/module_scope_vars.h
+++ b/src/tint/lang/msl/writer/raise/module_scope_vars.h
@@ -28,10 +28,8 @@
 #ifndef SRC_TINT_LANG_MSL_WRITER_RAISE_MODULE_SCOPE_VARS_H_
 #define SRC_TINT_LANG_MSL_WRITER_RAISE_MODULE_SCOPE_VARS_H_
 
-#include <string>
-
 #include "src/tint/lang/core/ir/validator.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -44,7 +42,7 @@
 /// declarations that are wrapped in a structure and passed to functions that need them.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> ModuleScopeVars(core::ir::Module& module);
+diag::Result<SuccessType> ModuleScopeVars(core::ir::Module& module);
 
 }  // namespace tint::msl::writer::raise
 
diff --git a/src/tint/lang/msl/writer/raise/packed_vec3.cc b/src/tint/lang/msl/writer/raise/packed_vec3.cc
index 9e1fc3f..cb34b06 100644
--- a/src/tint/lang/msl/writer/raise/packed_vec3.cc
+++ b/src/tint/lang/msl/writer/raise/packed_vec3.cc
@@ -639,7 +639,7 @@
 
 }  // namespace
 
-Result<SuccessType> PackedVec3(core::ir::Module& ir) {
+diag::Result<SuccessType> PackedVec3(core::ir::Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "msl.PackedVec3");
     if (result != Success) {
         return result.Failure();
diff --git a/src/tint/lang/msl/writer/raise/packed_vec3.h b/src/tint/lang/msl/writer/raise/packed_vec3.h
index d6cda8c..2a980ed 100644
--- a/src/tint/lang/msl/writer/raise/packed_vec3.h
+++ b/src/tint/lang/msl/writer/raise/packed_vec3.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_MSL_WRITER_RAISE_PACKED_VEC3_H_
 #define SRC_TINT_LANG_MSL_WRITER_RAISE_PACKED_VEC3_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -52,7 +52,7 @@
 ///
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> PackedVec3(core::ir::Module& module);
+diag::Result<SuccessType> PackedVec3(core::ir::Module& module);
 
 }  // namespace tint::msl::writer::raise
 
diff --git a/src/tint/lang/msl/writer/raise/raise.cc b/src/tint/lang/msl/writer/raise/raise.cc
index 3e94640..88145d6 100644
--- a/src/tint/lang/msl/writer/raise/raise.cc
+++ b/src/tint/lang/msl/writer/raise/raise.cc
@@ -27,8 +27,6 @@
 
 #include "src/tint/lang/msl/writer/raise/raise.h"
 
-#include <utility>
-
 #include "src/tint/api/common/binding_point.h"
 #include "src/tint/lang/core/ir/transform/array_length_from_uniform.h"
 #include "src/tint/lang/core/ir/transform/binary_polyfill.h"
@@ -58,7 +56,7 @@
 
 namespace tint::msl::writer {
 
-Result<RaiseResult> Raise(core::ir::Module& module, const Options& options) {
+diag::Result<RaiseResult> Raise(core::ir::Module& module, const Options& options) {
 #define RUN_TRANSFORM(name, ...)         \
     do {                                 \
         auto result = name(__VA_ARGS__); \
diff --git a/src/tint/lang/msl/writer/raise/raise.h b/src/tint/lang/msl/writer/raise/raise.h
index 6b3b7f8..97a24e5 100644
--- a/src/tint/lang/msl/writer/raise/raise.h
+++ b/src/tint/lang/msl/writer/raise/raise.h
@@ -28,11 +28,8 @@
 #ifndef SRC_TINT_LANG_MSL_WRITER_RAISE_RAISE_H_
 #define SRC_TINT_LANG_MSL_WRITER_RAISE_RAISE_H_
 
-#include <string>
-
 #include "src/tint/lang/msl/writer/common/options.h"
 #include "src/tint/utils/diagnostic/diagnostic.h"
-#include "src/tint/utils/result/result.h"
 
 // Forward declarations
 namespace tint::core::ir {
@@ -51,7 +48,7 @@
 /// @param module the core IR module to raise to MSL dialect
 /// @param options the printer options
 /// @returns success or failure
-Result<RaiseResult> Raise(core::ir::Module& module, const Options& options);
+diag::Result<RaiseResult> Raise(core::ir::Module& module, const Options& options);
 
 }  // namespace tint::msl::writer
 
diff --git a/src/tint/lang/msl/writer/raise/shader_io.cc b/src/tint/lang/msl/writer/raise/shader_io.cc
index 80d6a83..6aa2fcf 100644
--- a/src/tint/lang/msl/writer/raise/shader_io.cc
+++ b/src/tint/lang/msl/writer/raise/shader_io.cc
@@ -28,7 +28,6 @@
 #include "src/tint/lang/msl/writer/raise/shader_io.h"
 
 #include <memory>
-#include <utility>
 
 #include "src/tint/lang/core/ir/builder.h"
 #include "src/tint/lang/core/ir/module.h"
@@ -242,7 +241,7 @@
 };
 }  // namespace
 
-Result<SuccessType> ShaderIO(core::ir::Module& ir, const ShaderIOConfig& config) {
+diag::Result<SuccessType> ShaderIO(core::ir::Module& ir, const ShaderIOConfig& config) {
     auto result = ValidateAndDumpIfNeeded(ir, "msl.ShaderIO");
     if (result != Success) {
         return result;
diff --git a/src/tint/lang/msl/writer/raise/shader_io.h b/src/tint/lang/msl/writer/raise/shader_io.h
index 326019d..24a6071 100644
--- a/src/tint/lang/msl/writer/raise/shader_io.h
+++ b/src/tint/lang/msl/writer/raise/shader_io.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_MSL_WRITER_RAISE_SHADER_IO_H_
 #define SRC_TINT_LANG_MSL_WRITER_RAISE_SHADER_IO_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -49,7 +49,7 @@
 /// @param module the module to transform
 /// @param config the configuration
 /// @returns success or failure
-Result<SuccessType> ShaderIO(core::ir::Module& module, const ShaderIOConfig& config);
+diag::Result<SuccessType> ShaderIO(core::ir::Module& module, const ShaderIOConfig& config);
 
 }  // namespace tint::msl::writer::raise
 
diff --git a/src/tint/lang/msl/writer/raise/simd_ballot.cc b/src/tint/lang/msl/writer/raise/simd_ballot.cc
index b650ae1..1f13ecf 100644
--- a/src/tint/lang/msl/writer/raise/simd_ballot.cc
+++ b/src/tint/lang/msl/writer/raise/simd_ballot.cc
@@ -27,8 +27,6 @@
 
 #include "src/tint/lang/msl/writer/raise/simd_ballot.h"
 
-#include <utility>
-
 #include "src/tint/lang/core/ir/builder.h"
 #include "src/tint/lang/core/ir/referenced_module_vars.h"
 #include "src/tint/lang/core/ir/validator.h"
@@ -159,7 +157,7 @@
 
 }  // namespace
 
-Result<SuccessType> SimdBallot(core::ir::Module& ir) {
+diag::Result<SuccessType> SimdBallot(core::ir::Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "msl.SimdBallot");
     if (result != Success) {
         return result.Failure();
diff --git a/src/tint/lang/msl/writer/raise/simd_ballot.h b/src/tint/lang/msl/writer/raise/simd_ballot.h
index d34519d..7db9b2d 100644
--- a/src/tint/lang/msl/writer/raise/simd_ballot.h
+++ b/src/tint/lang/msl/writer/raise/simd_ballot.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_MSL_WRITER_RAISE_SIMD_BALLOT_H_
 #define SRC_TINT_LANG_MSL_WRITER_RAISE_SIMD_BALLOT_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -41,7 +41,7 @@
 /// adding conversion and masking operations to produce the correct result.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> SimdBallot(core::ir::Module& module);
+diag::Result<SuccessType> SimdBallot(core::ir::Module& module);
 
 }  // namespace tint::msl::writer::raise
 
diff --git a/src/tint/lang/msl/writer/raise/unary_polyfill.cc b/src/tint/lang/msl/writer/raise/unary_polyfill.cc
index e116942..b012394 100644
--- a/src/tint/lang/msl/writer/raise/unary_polyfill.cc
+++ b/src/tint/lang/msl/writer/raise/unary_polyfill.cc
@@ -27,8 +27,6 @@
 
 #include "src/tint/lang/msl/writer/raise/unary_polyfill.h"
 
-#include <utility>
-
 #include "src/tint/lang/core/ir/builder.h"
 #include "src/tint/lang/core/ir/validator.h"
 
@@ -87,7 +85,7 @@
 
 }  // namespace
 
-Result<SuccessType> UnaryPolyfill(core::ir::Module& ir) {
+diag::Result<SuccessType> UnaryPolyfill(core::ir::Module& ir) {
     auto result =
         ValidateAndDumpIfNeeded(ir, "msl.UnaryPolyfill",
                                 core::ir::Capabilities{
diff --git a/src/tint/lang/msl/writer/raise/unary_polyfill.h b/src/tint/lang/msl/writer/raise/unary_polyfill.h
index 60382c6..29f3d32 100644
--- a/src/tint/lang/msl/writer/raise/unary_polyfill.h
+++ b/src/tint/lang/msl/writer/raise/unary_polyfill.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_MSL_WRITER_RAISE_UNARY_POLYFILL_H_
 #define SRC_TINT_LANG_MSL_WRITER_RAISE_UNARY_POLYFILL_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -41,7 +41,7 @@
 /// backend intrinsic functions.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> UnaryPolyfill(core::ir::Module& module);
+diag::Result<SuccessType> UnaryPolyfill(core::ir::Module& module);
 
 }  // namespace tint::msl::writer::raise
 
diff --git a/src/tint/lang/msl/writer/writer.cc b/src/tint/lang/msl/writer/writer.cc
index df320c3..8901448 100644
--- a/src/tint/lang/msl/writer/writer.cc
+++ b/src/tint/lang/msl/writer/writer.cc
@@ -27,9 +27,6 @@
 
 #include "src/tint/lang/msl/writer/writer.h"
 
-#include <memory>
-#include <utility>
-
 #include "src/tint/lang/core/ir/module.h"
 #include "src/tint/lang/core/ir/var.h"
 #include "src/tint/lang/core/type/f16.h"
@@ -42,12 +39,13 @@
 
 namespace tint::msl::writer {
 
-Result<SuccessType> CanGenerate(const core::ir::Module& ir, const Options& options) {
+diag::Result<SuccessType> CanGenerate(const core::ir::Module& ir, const Options& options) {
     // Check for unsupported types.
     for (auto* ty : ir.Types()) {
         if (auto* m = ty->As<core::type::SubgroupMatrix>()) {
             if (!m->Type()->IsAnyOf<core::type::F16, core::type::F32>()) {
-                return Failure("non-float subgroup matrices are not supported by the MSL backend");
+                return diag::Failure(
+                    "non-float subgroup matrices are not supported by the MSL backend");
             }
         }
     }
@@ -57,13 +55,13 @@
         auto* var = inst->As<core::ir::Var>();
         auto* ptr = var->Result(0)->Type()->As<core::type::Pointer>();
         if (ptr->AddressSpace() == core::AddressSpace::kPushConstant) {
-            return Failure("push constants are not supported by the MSL backend");
+            return diag::Failure("push constants are not supported by the MSL backend");
         }
         if (ptr->AddressSpace() == core::AddressSpace::kPixelLocal) {
-            return Failure("pixel_local address space is not supported by the MSL backend");
+            return diag::Failure("pixel_local address space is not supported by the MSL backend");
         }
         if (ptr->StoreType()->Is<core::type::InputAttachment>()) {
-            return Failure("input attachments are not supported by the MSL backend");
+            return diag::Failure("input attachments are not supported by the MSL backend");
         }
     }
 
@@ -74,25 +72,27 @@
         for (auto& func : ir.functions) {
             if (func->IsVertex()) {
                 if (ep) {
-                    return Failure("vertex pulling config provided with multiple vertex shaders");
+                    return diag::Failure(
+                        "vertex pulling config provided with multiple vertex shaders");
                 }
                 ep = func;
             }
         }
         if (!ep) {
-            return Failure("vertex pulling config provided without a vertex shader");
+            return diag::Failure("vertex pulling config provided without a vertex shader");
         }
 
         // Gather all of the vertex attribute locations in the config.
         Hashset<uint32_t, 4> locations;
         for (auto& buffer : options.vertex_pulling_config->vertex_state) {
             if (buffer.array_stride & 3) {
-                return Failure(
+                return diag::Failure(
                     "vertex pulling config contains array stride that is not a multiple of 4");
             }
             for (auto& attr : buffer.attributes) {
                 if (!locations.Add(attr.shader_location)) {
-                    return Failure("vertex pulling config contains duplicate shader locations");
+                    return diag::Failure(
+                        "vertex pulling config contains duplicate shader locations");
                 }
             }
         }
@@ -103,15 +103,15 @@
                 for (auto* member : str->Members()) {
                     if (auto loc = member->Attributes().location) {
                         if (!locations.Contains(*loc)) {
-                            return Failure("shader location " + std::to_string(*loc) +
-                                           " missing from vertex pulling map");
+                            return diag::Failure("shader location " + std::to_string(*loc) +
+                                                 " missing from vertex pulling map");
                         }
                     }
                 }
             } else if (auto loc = param->Location()) {
                 if (!locations.Contains(*loc)) {
-                    return Failure("shader location " + std::to_string(*loc) +
-                                   " missing from vertex pulling map");
+                    return diag::Failure("shader location " + std::to_string(*loc) +
+                                         " missing from vertex pulling map");
                 }
             }
         }
@@ -120,7 +120,7 @@
     return Success;
 }
 
-Result<Output> Generate(core::ir::Module& ir, const Options& options) {
+diag::Result<Output> Generate(core::ir::Module& ir, const Options& options) {
     {
         auto res = ValidateBindingOptions(options);
         if (res != Success) {
diff --git a/src/tint/lang/msl/writer/writer.h b/src/tint/lang/msl/writer/writer.h
index 020e11d..c1f4c49 100644
--- a/src/tint/lang/msl/writer/writer.h
+++ b/src/tint/lang/msl/writer/writer.h
@@ -44,14 +44,14 @@
 /// @param ir the module
 /// @param options the writer options
 /// @returns Success or a failure message indicating why MSL generation would fail
-Result<SuccessType> CanGenerate(const core::ir::Module& ir, const Options& options);
+diag::Result<SuccessType> CanGenerate(const core::ir::Module& ir, const Options& options);
 
 /// Generate MSL for a program, according to a set of configuration options.
 /// The result will contain the MSL and supplementary information, or failure.
 /// @param ir the IR module to translate to MSL
 /// @param options the configuration options to use when generating MSL
 /// @returns the resulting MSL and supplementary information, or failure
-Result<Output> Generate(core::ir::Module& ir, const Options& options);
+diag::Result<Output> Generate(core::ir::Module& ir, const Options& options);
 
 }  // namespace tint::msl::writer
 
diff --git a/src/tint/lang/msl/writer/writer_fuzz.cc b/src/tint/lang/msl/writer/writer_fuzz.cc
index 1be3150..6aad633 100644
--- a/src/tint/lang/msl/writer/writer_fuzz.cc
+++ b/src/tint/lang/msl/writer/writer_fuzz.cc
@@ -37,9 +37,9 @@
 namespace tint::msl::writer {
 namespace {
 
-Result<SuccessType> IRFuzzer(core::ir::Module& module,
-                             const fuzz::ir::Context& context,
-                             Options options) {
+diag::Result<SuccessType> IRFuzzer(core::ir::Module& module,
+                                   const fuzz::ir::Context& context,
+                                   Options options) {
     options.bindings = GenerateBindings(module);
     options.array_length_from_uniform.ubo_binding = 30;
 
diff --git a/src/tint/lang/spirv/reader/common/BUILD.bazel b/src/tint/lang/spirv/reader/common/BUILD.bazel
index 43272fb..7ce0971 100644
--- a/src/tint/lang/spirv/reader/common/BUILD.bazel
+++ b/src/tint/lang/spirv/reader/common/BUILD.bazel
@@ -70,15 +70,10 @@
     "helper_test.h",
   ],
   deps = [
-    "//src/tint/utils/containers",
-    "//src/tint/utils/diagnostic",
     "//src/tint/utils/ice",
     "//src/tint/utils/macros",
-    "//src/tint/utils/math",
-    "//src/tint/utils/memory",
     "//src/tint/utils/result",
     "//src/tint/utils/rtti",
-    "//src/tint/utils/text",
     "//src/utils",
   ] + select({
     ":tint_build_spv_reader_or_tint_build_spv_writer": [
diff --git a/src/tint/lang/spirv/reader/common/BUILD.cmake b/src/tint/lang/spirv/reader/common/BUILD.cmake
index e90c54e5..6184f26 100644
--- a/src/tint/lang/spirv/reader/common/BUILD.cmake
+++ b/src/tint/lang/spirv/reader/common/BUILD.cmake
@@ -77,15 +77,10 @@
 )
 
 tint_target_add_dependencies(tint_lang_spirv_reader_common_test test
-  tint_utils_containers
-  tint_utils_diagnostic
   tint_utils_ice
   tint_utils_macros
-  tint_utils_math
-  tint_utils_memory
   tint_utils_result
   tint_utils_rtti
-  tint_utils_text
 )
 
 tint_target_add_external_dependencies(tint_lang_spirv_reader_common_test test
diff --git a/src/tint/lang/spirv/reader/common/BUILD.gn b/src/tint/lang/spirv/reader/common/BUILD.gn
index a59ece7..9eef56b 100644
--- a/src/tint/lang/spirv/reader/common/BUILD.gn
+++ b/src/tint/lang/spirv/reader/common/BUILD.gn
@@ -72,15 +72,10 @@
       sources = [ "helper_test.h" ]
       deps = [
         "${dawn_root}/src/utils:utils",
-        "${tint_src_dir}/utils/containers",
-        "${tint_src_dir}/utils/diagnostic",
         "${tint_src_dir}/utils/ice",
         "${tint_src_dir}/utils/macros",
-        "${tint_src_dir}/utils/math",
-        "${tint_src_dir}/utils/memory",
         "${tint_src_dir}/utils/result",
         "${tint_src_dir}/utils/rtti",
-        "${tint_src_dir}/utils/text",
       ]
 
       if (tint_build_spv_reader || tint_build_spv_writer) {
diff --git a/src/tint/lang/spirv/reader/helper_test.h b/src/tint/lang/spirv/reader/helper_test.h
index 0d14aca..6997a61 100644
--- a/src/tint/lang/spirv/reader/helper_test.h
+++ b/src/tint/lang/spirv/reader/helper_test.h
@@ -57,7 +57,7 @@
     /// Run the parser on a SPIR-V module and return the Tint IR or an error string.
     /// @param spirv_asm the SPIR-V assembly to parse
     /// @returns the disassembled Tint IR or an error
-    Result<std::string> Run(std::string spirv_asm) {
+    diag::Result<std::string> Run(std::string spirv_asm) {
         // Assemble the SPIR-V input.
         auto binary = Assemble(spirv_asm);
         if (binary != Success) {
diff --git a/src/tint/lang/spirv/reader/lower/builtins.cc b/src/tint/lang/spirv/reader/lower/builtins.cc
index 5fe41de..81cba14 100644
--- a/src/tint/lang/spirv/reader/lower/builtins.cc
+++ b/src/tint/lang/spirv/reader/lower/builtins.cc
@@ -1098,7 +1098,7 @@
 
 }  // namespace
 
-Result<SuccessType> Builtins(core::ir::Module& ir) {
+diag::Result<SuccessType> Builtins(core::ir::Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "spirv.Builtins",
                                           core::ir::Capabilities{
                                               core::ir::Capability::kAllowOverrides,
diff --git a/src/tint/lang/spirv/reader/lower/builtins.h b/src/tint/lang/spirv/reader/lower/builtins.h
index f3b8009..d56556f 100644
--- a/src/tint/lang/spirv/reader/lower/builtins.h
+++ b/src/tint/lang/spirv/reader/lower/builtins.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_SPIRV_READER_LOWER_BUILTINS_H_
 #define SRC_TINT_LANG_SPIRV_READER_LOWER_BUILTINS_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -41,7 +41,7 @@
 /// core IR.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> Builtins(core::ir::Module& module);
+diag::Result<SuccessType> Builtins(core::ir::Module& module);
 
 }  // namespace tint::spirv::reader::lower
 
diff --git a/src/tint/lang/spirv/reader/lower/lower.cc b/src/tint/lang/spirv/reader/lower/lower.cc
index 86d7241..bcff629 100644
--- a/src/tint/lang/spirv/reader/lower/lower.cc
+++ b/src/tint/lang/spirv/reader/lower/lower.cc
@@ -35,7 +35,7 @@
 
 namespace tint::spirv::reader {
 
-Result<SuccessType> Lower(core::ir::Module& mod) {
+diag::Result<SuccessType> Lower(core::ir::Module& mod) {
 #define RUN_TRANSFORM(name, ...)         \
     do {                                 \
         auto result = name(__VA_ARGS__); \
diff --git a/src/tint/lang/spirv/reader/lower/lower.h b/src/tint/lang/spirv/reader/lower/lower.h
index 0d8e3b2..dfb21ee 100644
--- a/src/tint/lang/spirv/reader/lower/lower.h
+++ b/src/tint/lang/spirv/reader/lower/lower.h
@@ -29,14 +29,14 @@
 #define SRC_TINT_LANG_SPIRV_READER_LOWER_LOWER_H_
 
 #include "src/tint/lang/core/ir/module.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 namespace tint::spirv::reader {
 
 /// Lower converts a SPIR-V-dialect IR module to a core-dialect IR module
 /// @param  mod the IR module
 /// @return the result of the operation
-Result<SuccessType> Lower(core::ir::Module& mod);
+diag::Result<SuccessType> Lower(core::ir::Module& mod);
 
 }  // namespace tint::spirv::reader
 
diff --git a/src/tint/lang/spirv/reader/lower/shader_io.cc b/src/tint/lang/spirv/reader/lower/shader_io.cc
index 38faf72..73f54cd 100644
--- a/src/tint/lang/spirv/reader/lower/shader_io.cc
+++ b/src/tint/lang/spirv/reader/lower/shader_io.cc
@@ -463,7 +463,7 @@
 
 }  // namespace
 
-Result<SuccessType> ShaderIO(core::ir::Module& ir) {
+diag::Result<SuccessType> ShaderIO(core::ir::Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "spirv.ShaderIO",
                                           core::ir::Capabilities{
                                               core::ir::Capability::kAllowOverrides,
diff --git a/src/tint/lang/spirv/reader/lower/shader_io.h b/src/tint/lang/spirv/reader/lower/shader_io.h
index 8347585..1b028ab 100644
--- a/src/tint/lang/spirv/reader/lower/shader_io.h
+++ b/src/tint/lang/spirv/reader/lower/shader_io.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_SPIRV_READER_LOWER_SHADER_IO_H_
 #define SRC_TINT_LANG_SPIRV_READER_LOWER_SHADER_IO_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -41,7 +41,7 @@
 /// the form expected by Tint's core IR (using function parameters and return values).
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> ShaderIO(core::ir::Module& module);
+diag::Result<SuccessType> ShaderIO(core::ir::Module& module);
 
 }  // namespace tint::spirv::reader::lower
 
diff --git a/src/tint/lang/spirv/reader/lower/vector_element_pointer.cc b/src/tint/lang/spirv/reader/lower/vector_element_pointer.cc
index 8db8634..339ddcd 100644
--- a/src/tint/lang/spirv/reader/lower/vector_element_pointer.cc
+++ b/src/tint/lang/spirv/reader/lower/vector_element_pointer.cc
@@ -27,8 +27,6 @@
 
 #include "src/tint/lang/spirv/reader/lower/vector_element_pointer.h"
 
-#include <utility>
-
 #include "src/tint/lang/core/ir/builder.h"
 #include "src/tint/lang/core/ir/module.h"
 #include "src/tint/lang/core/ir/validator.h"
@@ -152,7 +150,7 @@
 
 }  // namespace
 
-Result<SuccessType> VectorElementPointer(core::ir::Module& ir) {
+diag::Result<SuccessType> VectorElementPointer(core::ir::Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "spirv.VectorElementPointer",
                                           core::ir::Capabilities{
                                               core::ir::Capability::kAllowOverrides,
diff --git a/src/tint/lang/spirv/reader/lower/vector_element_pointer.h b/src/tint/lang/spirv/reader/lower/vector_element_pointer.h
index e07a30c..538a600 100644
--- a/src/tint/lang/spirv/reader/lower/vector_element_pointer.h
+++ b/src/tint/lang/spirv/reader/lower/vector_element_pointer.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_SPIRV_READER_LOWER_VECTOR_ELEMENT_POINTER_H_
 #define SRC_TINT_LANG_SPIRV_READER_LOWER_VECTOR_ELEMENT_POINTER_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -41,7 +41,7 @@
 /// instructions and their uses.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> VectorElementPointer(core::ir::Module& module);
+diag::Result<SuccessType> VectorElementPointer(core::ir::Module& module);
 
 }  // namespace tint::spirv::reader::lower
 
diff --git a/src/tint/lang/spirv/reader/parser/helper_test.h b/src/tint/lang/spirv/reader/parser/helper_test.h
index a3da582..98bc003 100644
--- a/src/tint/lang/spirv/reader/parser/helper_test.h
+++ b/src/tint/lang/spirv/reader/parser/helper_test.h
@@ -28,7 +28,6 @@
 #ifndef SRC_TINT_LANG_SPIRV_READER_PARSER_HELPER_TEST_H_
 #define SRC_TINT_LANG_SPIRV_READER_PARSER_HELPER_TEST_H_
 
-#include <iostream>
 #include <string>
 #include <vector>
 
@@ -59,7 +58,7 @@
     /// Run the parser on a SPIR-V module and return the Tint IR or an error string.
     /// @param spirv_asm the SPIR-V assembly to parse
     /// @returns the disassembled Tint IR or an error
-    Result<std::string> Run(std::string spirv_asm) {
+    diag::Result<std::string> Run(std::string spirv_asm) {
         // Assemble the SPIR-V input.
         auto binary = Assemble(spirv_asm);
         if (binary != Success) {
diff --git a/src/tint/lang/spirv/reader/parser/parser.cc b/src/tint/lang/spirv/reader/parser/parser.cc
index 8fcf4f6..295de91 100644
--- a/src/tint/lang/spirv/reader/parser/parser.cc
+++ b/src/tint/lang/spirv/reader/parser/parser.cc
@@ -71,7 +71,7 @@
   public:
     /// @param spirv the SPIR-V binary data
     /// @returns the generated SPIR-V IR module on success, or failure
-    Result<core::ir::Module> Run(Slice<const uint32_t> spirv) {
+    diag::Result<core::ir::Module> Run(Slice<const uint32_t> spirv) {
         // Validate the incoming SPIR-V binary.
         auto result = validate::Validate(spirv, kTargetEnv);
         if (result != Success) {
@@ -83,7 +83,7 @@
         spirv_context_ =
             spvtools::BuildModule(kTargetEnv, context.CContext()->consumer, spirv.data, spirv.len);
         if (!spirv_context_) {
-            return Failure("failed to build the internal representation of the module");
+            return diag::Failure("failed to build the internal representation of the module");
         }
 
         // Check for unsupported extensions.
@@ -91,7 +91,7 @@
             auto name = ext.GetOperand(0).AsString();
             if (name != "SPV_KHR_storage_buffer_storage_class" &&
                 name != "SPV_KHR_non_semantic_info") {
-                return Failure("SPIR-V extension '" + name + "' is not supported");
+                return diag::Failure("SPIR-V extension '" + name + "' is not supported");
             }
         }
 
@@ -105,7 +105,7 @@
             } else if (name.find("NonSemantic.") == 0) {
                 ignored_imports_.insert(import.result_id());
             } else {
-                return Failure("Unrecognized extended instruction set: " + name);
+                return diag::Failure("Unrecognized extended instruction set: " + name);
             }
         }
 
@@ -2117,7 +2117,7 @@
 
 }  // namespace
 
-Result<core::ir::Module> Parse(Slice<const uint32_t> spirv) {
+diag::Result<core::ir::Module> Parse(Slice<const uint32_t> spirv) {
     return Parser{}.Run(spirv);
 }
 
diff --git a/src/tint/lang/spirv/reader/parser/parser.h b/src/tint/lang/spirv/reader/parser/parser.h
index 17612cf..99ce561 100644
--- a/src/tint/lang/spirv/reader/parser/parser.h
+++ b/src/tint/lang/spirv/reader/parser/parser.h
@@ -28,9 +28,7 @@
 #ifndef SRC_TINT_LANG_SPIRV_READER_PARSER_PARSER_H_
 #define SRC_TINT_LANG_SPIRV_READER_PARSER_PARSER_H_
 
-#include <vector>
-
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations
 namespace tint::core::ir {
@@ -42,7 +40,7 @@
 /// Parse a SPIR-V binary to produce a SPIR-V IR module.
 /// @param spirv the SPIR-V binary data
 /// @returns the SPIR-V IR module on success, or failure
-Result<core::ir::Module> Parse(Slice<const uint32_t> spirv);
+diag::Result<core::ir::Module> Parse(Slice<const uint32_t> spirv);
 
 }  // namespace tint::spirv::reader
 
diff --git a/src/tint/lang/spirv/reader/reader.cc b/src/tint/lang/spirv/reader/reader.cc
index d70c16c..8038d4e 100644
--- a/src/tint/lang/spirv/reader/reader.cc
+++ b/src/tint/lang/spirv/reader/reader.cc
@@ -36,7 +36,7 @@
 
 namespace tint::spirv::reader {
 
-Result<core::ir::Module> ReadIR(const std::vector<uint32_t>& input) {
+diag::Result<core::ir::Module> ReadIR(const std::vector<uint32_t>& input) {
     // Parse the input SPIR-V to the SPIR-V dialect of the IR.
     auto mod = Parse(Slice(input.data(), input.size()));
     if (mod != Success) {
diff --git a/src/tint/lang/spirv/reader/reader.h b/src/tint/lang/spirv/reader/reader.h
index e67f6a7..b74f503 100644
--- a/src/tint/lang/spirv/reader/reader.h
+++ b/src/tint/lang/spirv/reader/reader.h
@@ -45,7 +45,7 @@
 /// TODO(crbug.com/tint/1907): Rename when we remove the AST path.
 /// @param input the SPIR-V binary data
 /// @returns the Tint IR module
-Result<core::ir::Module> ReadIR(const std::vector<uint32_t>& input);
+diag::Result<core::ir::Module> ReadIR(const std::vector<uint32_t>& input);
 
 /// Reads the SPIR-V source data, returning the parsed program.
 /// If the source data fails to parse then the returned
diff --git a/src/tint/lang/spirv/validate/validate.cc b/src/tint/lang/spirv/validate/validate.cc
index 2010c8b..516d729 100644
--- a/src/tint/lang/spirv/validate/validate.cc
+++ b/src/tint/lang/spirv/validate/validate.cc
@@ -35,7 +35,7 @@
 
 namespace tint::spirv::validate {
 
-Result<SuccessType> Validate(Slice<const uint32_t> spirv, spv_target_env target_env) {
+diag::Result<SuccessType> Validate(Slice<const uint32_t> spirv, spv_target_env target_env) {
     Vector<diag::Diagnostic, 4> diags;
     diags.Push(diag::Diagnostic{});  // Filled in on error
 
@@ -90,7 +90,7 @@
         diag.source.file = file.get();
         diag.owned_file = file;
     }
-    return Failure{diag::List{std::move(diags)}};
+    return diag::Failure{diag::List{std::move(diags)}};
 }
 
 }  // namespace tint::spirv::validate
diff --git a/src/tint/lang/spirv/validate/validate.h b/src/tint/lang/spirv/validate/validate.h
index 9dab618..1983298 100644
--- a/src/tint/lang/spirv/validate/validate.h
+++ b/src/tint/lang/spirv/validate/validate.h
@@ -29,7 +29,7 @@
 #define SRC_TINT_LANG_SPIRV_VALIDATE_VALIDATE_H_
 
 #include "spirv-tools/libspirv.hpp"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 namespace tint::spirv::validate {
 
@@ -37,7 +37,7 @@
 /// @param spirv the SPIR-V binary data
 /// @param target_env the target environment to validate against
 /// @return success or failure(s)
-Result<SuccessType> Validate(Slice<const uint32_t> spirv, spv_target_env target_env);
+diag::Result<SuccessType> Validate(Slice<const uint32_t> spirv, spv_target_env target_env);
 
 }  // namespace tint::spirv::validate
 
diff --git a/src/tint/lang/spirv/writer/common/option_helper.cc b/src/tint/lang/spirv/writer/common/option_helper.cc
index c3ffcc2..0380ecb 100644
--- a/src/tint/lang/spirv/writer/common/option_helper.cc
+++ b/src/tint/lang/spirv/writer/common/option_helper.cc
@@ -29,11 +29,11 @@
 
 #include <utility>
 
-#include "src/tint/utils/containers/hashset.h"
+#include "src/tint/utils/containers/hashmap.h"
 
 namespace tint::spirv::writer {
 
-Result<SuccessType> ValidateBindingOptions(const Options& options) {
+diag::Result<SuccessType> ValidateBindingOptions(const Options& options) {
     diag::List diagnostics;
 
     tint::Hashmap<tint::BindingPoint, binding::BindingInfo, 8> seen_wgsl_bindings{};
@@ -92,27 +92,27 @@
 
     if (!valid(options.bindings.uniform)) {
         diagnostics.AddNote(Source{}) << "when processing uniform";
-        return Failure{std::move(diagnostics)};
+        return diag::Failure{std::move(diagnostics)};
     }
     if (!valid(options.bindings.storage)) {
         diagnostics.AddNote(Source{}) << "when processing storage";
-        return Failure{std::move(diagnostics)};
+        return diag::Failure{std::move(diagnostics)};
     }
     if (!valid(options.bindings.texture)) {
         diagnostics.AddNote(Source{}) << "when processing texture";
-        return Failure{std::move(diagnostics)};
+        return diag::Failure{std::move(diagnostics)};
     }
     if (!valid(options.bindings.storage_texture)) {
         diagnostics.AddNote(Source{}) << "when processing storage_texture";
-        return Failure{std::move(diagnostics)};
+        return diag::Failure{std::move(diagnostics)};
     }
     if (!valid(options.bindings.sampler)) {
         diagnostics.AddNote(Source{}) << "when processing sampler";
-        return Failure{std::move(diagnostics)};
+        return diag::Failure{std::move(diagnostics)};
     }
     if (!valid(options.bindings.input_attachment)) {
         diagnostics.AddNote(Source{}) << "when processing input_attachment";
-        return Failure{std::move(diagnostics)};
+        return diag::Failure{std::move(diagnostics)};
     }
 
     for (const auto& it : options.bindings.external_texture) {
@@ -124,20 +124,20 @@
         // Validate with the actual source regardless of what the remapper will do
         if (wgsl_seen(src_binding, plane0)) {
             diagnostics.AddNote(Source{}) << "when processing external_texture";
-            return Failure{std::move(diagnostics)};
+            return diag::Failure{std::move(diagnostics)};
         }
 
         if (spirv_seen(plane0, src_binding)) {
             diagnostics.AddNote(Source{}) << "when processing external_texture";
-            return Failure{std::move(diagnostics)};
+            return diag::Failure{std::move(diagnostics)};
         }
         if (spirv_seen(plane1, src_binding)) {
             diagnostics.AddNote(Source{}) << "when processing external_texture";
-            return Failure{std::move(diagnostics)};
+            return diag::Failure{std::move(diagnostics)};
         }
         if (spirv_seen(metadata, src_binding)) {
             diagnostics.AddNote(Source{}) << "when processing external_texture";
-            return Failure{std::move(diagnostics)};
+            return diag::Failure{std::move(diagnostics)};
         }
     }
 
diff --git a/src/tint/lang/spirv/writer/common/option_helpers.h b/src/tint/lang/spirv/writer/common/option_helpers.h
index 896ef0a..4eb2768 100644
--- a/src/tint/lang/spirv/writer/common/option_helpers.h
+++ b/src/tint/lang/spirv/writer/common/option_helpers.h
@@ -34,7 +34,6 @@
 #include "src/tint/lang/core/common/multiplanar_options.h"
 #include "src/tint/lang/spirv/writer/common/options.h"
 #include "src/tint/utils/diagnostic/diagnostic.h"
-#include "src/tint/utils/result/result.h"
 
 namespace tint::spirv::writer {
 
@@ -42,7 +41,7 @@
 
 /// @param options the options
 /// @return success or failure
-Result<SuccessType> ValidateBindingOptions(const Options& options);
+diag::Result<SuccessType> ValidateBindingOptions(const Options& options);
 
 /// Populates data from the writer options for the remapper and external texture.
 /// @param options the writer options
diff --git a/src/tint/lang/spirv/writer/printer/printer.cc b/src/tint/lang/spirv/writer/printer/printer.cc
index 9e1feea..c2d50da 100644
--- a/src/tint/lang/spirv/writer/printer/printer.cc
+++ b/src/tint/lang/spirv/writer/printer/printer.cc
@@ -197,7 +197,7 @@
     }
 
     /// @returns the generated SPIR-V code on success, or failure
-    Result<Output> Code() {
+    diag::Result<Output> Code() {
         if (auto res = Generate(); res != Success) {
             return res.Failure();
         }
@@ -286,7 +286,7 @@
     bool zero_init_workgroup_memory_ = false;
 
     /// Builds the SPIR-V from the IR
-    Result<SuccessType> Generate() {
+    diag::Result<SuccessType> Generate() {
         auto valid = core::ir::ValidateAndDumpIfNeeded(ir_, "spirv.Printer");
         if (valid != Success) {
             return valid.Failure();
@@ -735,7 +735,7 @@
 
     /// Emit a function.
     /// @param func the function to emit
-    Result<SuccessType> EmitFunction(core::ir::Function* func) {
+    diag::Result<SuccessType> EmitFunction(core::ir::Function* func) {
         if (func->Params().Length() > 255) {
             // Tint transforms may add additional function parameters which can cause a valid input
             // shader to exceed SPIR-V's function parameter limit. There isn't much we can do about
@@ -743,7 +743,7 @@
             StringStream ss;
             ss << "Function '" << ir_.NameOf(func).Name()
                << "' has more than 255 parameters after running Tint transforms";
-            return Failure{ss.str()};
+            return diag::Failure{ss.str()};
         }
 
         auto id = Value(func);
@@ -2796,7 +2796,7 @@
 
 }  // namespace
 
-tint::Result<Output> Print(core::ir::Module& module, const Options& options) {
+diag::Result<Output> Print(core::ir::Module& module, const Options& options) {
     return Printer{module, options}.Code();
 }
 
diff --git a/src/tint/lang/spirv/writer/printer/printer.h b/src/tint/lang/spirv/writer/printer/printer.h
index 12c66c2..b63251e 100644
--- a/src/tint/lang/spirv/writer/printer/printer.h
+++ b/src/tint/lang/spirv/writer/printer/printer.h
@@ -30,7 +30,7 @@
 
 #include "src/tint/lang/spirv/writer/common/options.h"
 #include "src/tint/lang/spirv/writer/common/output.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations
 namespace tint::core::ir {
@@ -42,7 +42,7 @@
 /// @returns the generated SPIR-V instructions on success, or failure
 /// @param module the Tint IR module to generate
 /// @param options the printer options
-tint::Result<Output> Print(core::ir::Module& module, const Options& options);
+diag::Result<Output> Print(core::ir::Module& module, const Options& options);
 
 }  // namespace tint::spirv::writer
 
diff --git a/src/tint/lang/spirv/writer/raise/builtin_polyfill.cc b/src/tint/lang/spirv/writer/raise/builtin_polyfill.cc
index d803f59..c18c04f 100644
--- a/src/tint/lang/spirv/writer/raise/builtin_polyfill.cc
+++ b/src/tint/lang/spirv/writer/raise/builtin_polyfill.cc
@@ -1087,7 +1087,7 @@
 
 }  // namespace
 
-Result<SuccessType> BuiltinPolyfill(core::ir::Module& ir, bool use_vulkan_memory_model) {
+diag::Result<SuccessType> BuiltinPolyfill(core::ir::Module& ir, bool use_vulkan_memory_model) {
     auto result = ValidateAndDumpIfNeeded(ir, "spirv.BuiltinPolyfill");
     if (result != Success) {
         return result.Failure();
diff --git a/src/tint/lang/spirv/writer/raise/builtin_polyfill.h b/src/tint/lang/spirv/writer/raise/builtin_polyfill.h
index c17b5e7..084f023 100644
--- a/src/tint/lang/spirv/writer/raise/builtin_polyfill.h
+++ b/src/tint/lang/spirv/writer/raise/builtin_polyfill.h
@@ -28,12 +28,7 @@
 #ifndef SRC_TINT_LANG_SPIRV_WRITER_RAISE_BUILTIN_POLYFILL_H_
 #define SRC_TINT_LANG_SPIRV_WRITER_RAISE_BUILTIN_POLYFILL_H_
 
-#include <string>
-
-#include "src/tint/lang/core/ir/constant.h"
-#include "src/tint/lang/core/type/type.h"
 #include "src/tint/utils/diagnostic/diagnostic.h"
-#include "src/tint/utils/result/result.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -48,7 +43,7 @@
 /// @param module the module to transform
 /// @param use_vulkan_memory_model set `true` to use the vulkan memory model
 /// @returns success or failure
-Result<SuccessType> BuiltinPolyfill(core::ir::Module& module, bool use_vulkan_memory_model);
+diag::Result<SuccessType> BuiltinPolyfill(core::ir::Module& module, bool use_vulkan_memory_model);
 
 }  // namespace tint::spirv::writer::raise
 
diff --git a/src/tint/lang/spirv/writer/raise/expand_implicit_splats.cc b/src/tint/lang/spirv/writer/raise/expand_implicit_splats.cc
index c0d2f34..97fa861 100644
--- a/src/tint/lang/spirv/writer/raise/expand_implicit_splats.cc
+++ b/src/tint/lang/spirv/writer/raise/expand_implicit_splats.cc
@@ -134,7 +134,7 @@
 
 }  // namespace
 
-Result<SuccessType> ExpandImplicitSplats(core::ir::Module& ir) {
+diag::Result<SuccessType> ExpandImplicitSplats(core::ir::Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "spirv.ExpandImplicitSplats");
     if (result != Success) {
         return result.Failure();
diff --git a/src/tint/lang/spirv/writer/raise/expand_implicit_splats.h b/src/tint/lang/spirv/writer/raise/expand_implicit_splats.h
index a349326..7694e84 100644
--- a/src/tint/lang/spirv/writer/raise/expand_implicit_splats.h
+++ b/src/tint/lang/spirv/writer/raise/expand_implicit_splats.h
@@ -28,10 +28,7 @@
 #ifndef SRC_TINT_LANG_SPIRV_WRITER_RAISE_EXPAND_IMPLICIT_SPLATS_H_
 #define SRC_TINT_LANG_SPIRV_WRITER_RAISE_EXPAND_IMPLICIT_SPLATS_H_
 
-#include <string>
-
 #include "src/tint/utils/diagnostic/diagnostic.h"
-#include "src/tint/utils/result/result.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -44,7 +41,7 @@
 /// instructions and binary instructions where not supported by SPIR-V.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> ExpandImplicitSplats(core::ir::Module& module);
+diag::Result<SuccessType> ExpandImplicitSplats(core::ir::Module& module);
 
 }  // namespace tint::spirv::writer::raise
 
diff --git a/src/tint/lang/spirv/writer/raise/fork_explicit_layout_types.cc b/src/tint/lang/spirv/writer/raise/fork_explicit_layout_types.cc
index e3f084b..18f0eb3 100644
--- a/src/tint/lang/spirv/writer/raise/fork_explicit_layout_types.cc
+++ b/src/tint/lang/spirv/writer/raise/fork_explicit_layout_types.cc
@@ -356,7 +356,7 @@
 
 }  // namespace
 
-Result<SuccessType> ForkExplicitLayoutTypes(core::ir::Module& ir) {
+diag::Result<SuccessType> ForkExplicitLayoutTypes(core::ir::Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "spirv.ForkExplicitLayoutTypes");
     if (result != Success) {
         return result;
diff --git a/src/tint/lang/spirv/writer/raise/fork_explicit_layout_types.h b/src/tint/lang/spirv/writer/raise/fork_explicit_layout_types.h
index 4db9557..3d1b363 100644
--- a/src/tint/lang/spirv/writer/raise/fork_explicit_layout_types.h
+++ b/src/tint/lang/spirv/writer/raise/fork_explicit_layout_types.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_SPIRV_WRITER_RAISE_FORK_EXPLICIT_LAYOUT_TYPES_H_
 #define SRC_TINT_LANG_SPIRV_WRITER_RAISE_FORK_EXPLICIT_LAYOUT_TYPES_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -42,7 +42,7 @@
 ///
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> ForkExplicitLayoutTypes(core::ir::Module& module);
+diag::Result<SuccessType> ForkExplicitLayoutTypes(core::ir::Module& module);
 
 }  // namespace tint::spirv::writer::raise
 
diff --git a/src/tint/lang/spirv/writer/raise/handle_matrix_arithmetic.cc b/src/tint/lang/spirv/writer/raise/handle_matrix_arithmetic.cc
index 679f4e0..20c9ac5 100644
--- a/src/tint/lang/spirv/writer/raise/handle_matrix_arithmetic.cc
+++ b/src/tint/lang/spirv/writer/raise/handle_matrix_arithmetic.cc
@@ -162,7 +162,7 @@
 
 }  // namespace
 
-Result<SuccessType> HandleMatrixArithmetic(core::ir::Module& ir) {
+diag::Result<SuccessType> HandleMatrixArithmetic(core::ir::Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "spirv.HandleMatrixArithmetic");
     if (result != Success) {
         return result.Failure();
diff --git a/src/tint/lang/spirv/writer/raise/handle_matrix_arithmetic.h b/src/tint/lang/spirv/writer/raise/handle_matrix_arithmetic.h
index a0ca327..09a1abc 100644
--- a/src/tint/lang/spirv/writer/raise/handle_matrix_arithmetic.h
+++ b/src/tint/lang/spirv/writer/raise/handle_matrix_arithmetic.h
@@ -28,10 +28,7 @@
 #ifndef SRC_TINT_LANG_SPIRV_WRITER_RAISE_HANDLE_MATRIX_ARITHMETIC_H_
 #define SRC_TINT_LANG_SPIRV_WRITER_RAISE_HANDLE_MATRIX_ARITHMETIC_H_
 
-#include <string>
-
 #include "src/tint/utils/diagnostic/diagnostic.h"
-#include "src/tint/utils/result/result.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -44,7 +41,7 @@
 /// SPIR-V intrinsics or polyfills.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> HandleMatrixArithmetic(core::ir::Module& module);
+diag::Result<SuccessType> HandleMatrixArithmetic(core::ir::Module& module);
 
 }  // namespace tint::spirv::writer::raise
 
diff --git a/src/tint/lang/spirv/writer/raise/merge_return.cc b/src/tint/lang/spirv/writer/raise/merge_return.cc
index 359e149..a969bd5 100644
--- a/src/tint/lang/spirv/writer/raise/merge_return.cc
+++ b/src/tint/lang/spirv/writer/raise/merge_return.cc
@@ -321,7 +321,7 @@
 
 }  // namespace
 
-Result<SuccessType> MergeReturn(core::ir::Module& ir) {
+diag::Result<SuccessType> MergeReturn(core::ir::Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "spirv.MergeReturn");
     if (result != Success) {
         return result;
diff --git a/src/tint/lang/spirv/writer/raise/merge_return.h b/src/tint/lang/spirv/writer/raise/merge_return.h
index eff0dc7..fcc1dcd 100644
--- a/src/tint/lang/spirv/writer/raise/merge_return.h
+++ b/src/tint/lang/spirv/writer/raise/merge_return.h
@@ -28,10 +28,7 @@
 #ifndef SRC_TINT_LANG_SPIRV_WRITER_RAISE_MERGE_RETURN_H_
 #define SRC_TINT_LANG_SPIRV_WRITER_RAISE_MERGE_RETURN_H_
 
-#include <string>
-
 #include "src/tint/utils/diagnostic/diagnostic.h"
-#include "src/tint/utils/result/result.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -44,7 +41,7 @@
 /// at the end of the function.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> MergeReturn(core::ir::Module& module);
+diag::Result<SuccessType> MergeReturn(core::ir::Module& module);
 
 }  // namespace tint::spirv::writer::raise
 
diff --git a/src/tint/lang/spirv/writer/raise/pass_matrix_by_pointer.cc b/src/tint/lang/spirv/writer/raise/pass_matrix_by_pointer.cc
index 85b5d04..504e43d 100644
--- a/src/tint/lang/spirv/writer/raise/pass_matrix_by_pointer.cc
+++ b/src/tint/lang/spirv/writer/raise/pass_matrix_by_pointer.cc
@@ -127,7 +127,7 @@
 
 }  // namespace
 
-Result<SuccessType> PassMatrixByPointer(core::ir::Module& ir) {
+diag::Result<SuccessType> PassMatrixByPointer(core::ir::Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "spirv.PassMatrixByPointer");
     if (result != Success) {
         return result;
diff --git a/src/tint/lang/spirv/writer/raise/pass_matrix_by_pointer.h b/src/tint/lang/spirv/writer/raise/pass_matrix_by_pointer.h
index a6e9382..de56456 100644
--- a/src/tint/lang/spirv/writer/raise/pass_matrix_by_pointer.h
+++ b/src/tint/lang/spirv/writer/raise/pass_matrix_by_pointer.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_SPIRV_WRITER_RAISE_PASS_MATRIX_BY_POINTER_H_
 #define SRC_TINT_LANG_SPIRV_WRITER_RAISE_PASS_MATRIX_BY_POINTER_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -42,7 +42,7 @@
 /// This is used to workaround bugs in some Qualcomm drivers (see crbug.com/tint/2045).
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> PassMatrixByPointer(core::ir::Module& module);
+diag::Result<SuccessType> PassMatrixByPointer(core::ir::Module& module);
 
 }  // namespace tint::spirv::writer::raise
 
diff --git a/src/tint/lang/spirv/writer/raise/raise.cc b/src/tint/lang/spirv/writer/raise/raise.cc
index 8a02bf2..44fb351 100644
--- a/src/tint/lang/spirv/writer/raise/raise.cc
+++ b/src/tint/lang/spirv/writer/raise/raise.cc
@@ -27,8 +27,6 @@
 
 #include "src/tint/lang/spirv/writer/raise/raise.h"
 
-#include <utility>
-
 #include "src/tint/lang/core/ir/module.h"
 #include "src/tint/lang/core/ir/transform/add_empty_entry_point.h"
 #include "src/tint/lang/core/ir/transform/bgra8unorm_polyfill.h"
@@ -62,7 +60,7 @@
 
 namespace tint::spirv::writer {
 
-Result<SuccessType> Raise(core::ir::Module& module, const Options& options) {
+diag::Result<SuccessType> Raise(core::ir::Module& module, const Options& options) {
 #define RUN_TRANSFORM(name, ...)         \
     do {                                 \
         auto result = name(__VA_ARGS__); \
diff --git a/src/tint/lang/spirv/writer/raise/raise.h b/src/tint/lang/spirv/writer/raise/raise.h
index 64854f3..6eccfc9 100644
--- a/src/tint/lang/spirv/writer/raise/raise.h
+++ b/src/tint/lang/spirv/writer/raise/raise.h
@@ -28,11 +28,8 @@
 #ifndef SRC_TINT_LANG_SPIRV_WRITER_RAISE_RAISE_H_
 #define SRC_TINT_LANG_SPIRV_WRITER_RAISE_RAISE_H_
 
-#include <string>
-
 #include "src/tint/lang/spirv/writer/common/options.h"
 #include "src/tint/utils/diagnostic/diagnostic.h"
-#include "src/tint/utils/result/result.h"
 
 // Forward declarations
 namespace tint::core::ir {
@@ -45,7 +42,7 @@
 /// @param module the core IR module to raise to SPIR-V dialect
 /// @param options the SPIR-V writer options
 /// @returns success or failure
-Result<SuccessType> Raise(core::ir::Module& module, const Options& options);
+diag::Result<SuccessType> Raise(core::ir::Module& module, const Options& options);
 
 }  // namespace tint::spirv::writer
 
diff --git a/src/tint/lang/spirv/writer/raise/remove_unreachable_in_loop_continuing.cc b/src/tint/lang/spirv/writer/raise/remove_unreachable_in_loop_continuing.cc
index 5f534b4..6b75085 100644
--- a/src/tint/lang/spirv/writer/raise/remove_unreachable_in_loop_continuing.cc
+++ b/src/tint/lang/spirv/writer/raise/remove_unreachable_in_loop_continuing.cc
@@ -93,7 +93,7 @@
 
 }  // namespace
 
-Result<SuccessType> RemoveUnreachableInLoopContinuing(core::ir::Module& ir) {
+diag::Result<SuccessType> RemoveUnreachableInLoopContinuing(core::ir::Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "spirv.RemoveUnreachableInLoopContinuing");
     if (result != Success) {
         return result;
diff --git a/src/tint/lang/spirv/writer/raise/remove_unreachable_in_loop_continuing.h b/src/tint/lang/spirv/writer/raise/remove_unreachable_in_loop_continuing.h
index 17602fc..fe59d18 100644
--- a/src/tint/lang/spirv/writer/raise/remove_unreachable_in_loop_continuing.h
+++ b/src/tint/lang/spirv/writer/raise/remove_unreachable_in_loop_continuing.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_SPIRV_WRITER_RAISE_REMOVE_UNREACHABLE_IN_LOOP_CONTINUING_H_
 #define SRC_TINT_LANG_SPIRV_WRITER_RAISE_REMOVE_UNREACHABLE_IN_LOOP_CONTINUING_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -41,7 +41,7 @@
 /// nested inside a loop continuing block, as SPIR-V's structured control flow rules prohibit this.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> RemoveUnreachableInLoopContinuing(core::ir::Module& module);
+diag::Result<SuccessType> RemoveUnreachableInLoopContinuing(core::ir::Module& module);
 
 }  // namespace tint::spirv::writer::raise
 
diff --git a/src/tint/lang/spirv/writer/raise/shader_io.cc b/src/tint/lang/spirv/writer/raise/shader_io.cc
index cd1f33a..0ae5a62 100644
--- a/src/tint/lang/spirv/writer/raise/shader_io.cc
+++ b/src/tint/lang/spirv/writer/raise/shader_io.cc
@@ -28,7 +28,6 @@
 #include "src/tint/lang/spirv/writer/raise/shader_io.h"
 
 #include <memory>
-#include <utility>
 
 #include "src/tint/lang/core/ir/builder.h"
 #include "src/tint/lang/core/ir/module.h"
@@ -207,7 +206,7 @@
 };
 }  // namespace
 
-Result<SuccessType> ShaderIO(core::ir::Module& ir, const ShaderIOConfig& config) {
+diag::Result<SuccessType> ShaderIO(core::ir::Module& ir, const ShaderIOConfig& config) {
     auto result = ValidateAndDumpIfNeeded(ir, "spirv.ShaderIO");
     if (result != Success) {
         return result;
diff --git a/src/tint/lang/spirv/writer/raise/shader_io.h b/src/tint/lang/spirv/writer/raise/shader_io.h
index bef9452..c770854 100644
--- a/src/tint/lang/spirv/writer/raise/shader_io.h
+++ b/src/tint/lang/spirv/writer/raise/shader_io.h
@@ -28,12 +28,9 @@
 #ifndef SRC_TINT_LANG_SPIRV_WRITER_RAISE_SHADER_IO_H_
 #define SRC_TINT_LANG_SPIRV_WRITER_RAISE_SHADER_IO_H_
 
-#include <string>
-
 #include "src/tint/lang/core/ir/transform/prepare_push_constants.h"
 #include "src/tint/lang/spirv/writer/common/options.h"
 #include "src/tint/utils/diagnostic/diagnostic.h"
-#include "src/tint/utils/result/result.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -60,7 +57,7 @@
 /// @param module the module to transform
 /// @param config the configuration
 /// @returns success or failure
-Result<SuccessType> ShaderIO(core::ir::Module& module, const ShaderIOConfig& config);
+diag::Result<SuccessType> ShaderIO(core::ir::Module& module, const ShaderIOConfig& config);
 
 }  // namespace tint::spirv::writer::raise
 
diff --git a/src/tint/lang/spirv/writer/raise/var_for_dynamic_index.cc b/src/tint/lang/spirv/writer/raise/var_for_dynamic_index.cc
index 5a01b2b..97368fe 100644
--- a/src/tint/lang/spirv/writer/raise/var_for_dynamic_index.cc
+++ b/src/tint/lang/spirv/writer/raise/var_for_dynamic_index.cc
@@ -27,8 +27,6 @@
 
 #include "src/tint/lang/spirv/writer/raise/var_for_dynamic_index.h"
 
-#include <utility>
-
 #include "src/tint/lang/core/fluent_types.h"
 #include "src/tint/lang/core/ir/builder.h"
 #include "src/tint/lang/core/ir/module.h"
@@ -250,7 +248,7 @@
 
 }  // namespace
 
-Result<SuccessType> VarForDynamicIndex(core::ir::Module& ir) {
+diag::Result<SuccessType> VarForDynamicIndex(core::ir::Module& ir) {
     auto result = ValidateAndDumpIfNeeded(ir, "spirv.VarForDynamicIndex");
     if (result != Success) {
         return result;
diff --git a/src/tint/lang/spirv/writer/raise/var_for_dynamic_index.h b/src/tint/lang/spirv/writer/raise/var_for_dynamic_index.h
index 73b9507..e819e01 100644
--- a/src/tint/lang/spirv/writer/raise/var_for_dynamic_index.h
+++ b/src/tint/lang/spirv/writer/raise/var_for_dynamic_index.h
@@ -28,10 +28,7 @@
 #ifndef SRC_TINT_LANG_SPIRV_WRITER_RAISE_VAR_FOR_DYNAMIC_INDEX_H_
 #define SRC_TINT_LANG_SPIRV_WRITER_RAISE_VAR_FOR_DYNAMIC_INDEX_H_
 
-#include <string>
-
 #include "src/tint/utils/diagnostic/diagnostic.h"
-#include "src/tint/utils/result/result.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -46,7 +43,7 @@
 /// composite.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> VarForDynamicIndex(core::ir::Module& module);
+diag::Result<SuccessType> VarForDynamicIndex(core::ir::Module& module);
 
 }  // namespace tint::spirv::writer::raise
 
diff --git a/src/tint/lang/spirv/writer/writer.cc b/src/tint/lang/spirv/writer/writer.cc
index 041fe08..6a10786 100644
--- a/src/tint/lang/spirv/writer/writer.cc
+++ b/src/tint/lang/spirv/writer/writer.cc
@@ -41,12 +41,12 @@
 
 namespace tint::spirv::writer {
 
-Result<SuccessType> CanGenerate(const core::ir::Module& ir, const Options& options) {
+diag::Result<SuccessType> CanGenerate(const core::ir::Module& ir, const Options& options) {
     // Check optionally supported types against their required options.
     for (auto* ty : ir.Types()) {
         if (ty->Is<core::type::SubgroupMatrix>()) {
             if (!options.use_vulkan_memory_model) {
-                return Failure("using subgroup matrices requires the Vulkan Memory Model");
+                return diag::Failure("using subgroup matrices requires the Vulkan Memory Model");
             }
         }
     }
@@ -55,7 +55,7 @@
     // embedded null characters.
     if (!options.remapped_entry_point_name.empty()) {
         if (options.remapped_entry_point_name.find('\0') != std::string::npos) {
-            return Failure("remapped entry point name contains null character");
+            return diag::Failure("remapped entry point name contains null character");
         }
 
         // Check for multiple entry points.
@@ -64,7 +64,7 @@
         for (auto& func : ir.functions) {
             if (func->IsEntryPoint()) {
                 if (has_entry_point) {
-                    return Failure("module must only contain a single entry point");
+                    return diag::Failure("module must only contain a single entry point");
                 }
                 has_entry_point = true;
             }
@@ -78,13 +78,14 @@
         auto* var = inst->As<core::ir::Var>();
         auto* ptr = var->Result(0)->Type()->As<core::type::Pointer>();
         if (ptr->AddressSpace() == core::AddressSpace::kPixelLocal) {
-            return Failure("pixel_local address space is not supported by the SPIR-V backend");
+            return diag::Failure(
+                "pixel_local address space is not supported by the SPIR-V backend");
         }
 
         if (ptr->AddressSpace() == core::AddressSpace::kPushConstant) {
             if (user_push_constant_size > 0) {
                 // We've already seen a user-declared push constant.
-                return Failure("module contains multiple user-declared push constants");
+                return diag::Failure("module contains multiple user-declared push constants");
             }
             user_push_constant_size = tint::RoundUp(4u, ptr->StoreType()->Size());
         }
@@ -115,14 +116,14 @@
     if (options.depth_range_offsets) {
         if (!check_push_constant_offset(options.depth_range_offsets->max) ||
             !check_push_constant_offset(options.depth_range_offsets->min)) {
-            return Failure("invalid offsets for depth range push constants");
+            return diag::Failure("invalid offsets for depth range push constants");
         }
     }
 
     return Success;
 }
 
-Result<Output> Generate(core::ir::Module& ir, const Options& options) {
+diag::Result<Output> Generate(core::ir::Module& ir, const Options& options) {
     {
         auto res = ValidateBindingOptions(options);
         if (res != Success) {
diff --git a/src/tint/lang/spirv/writer/writer.h b/src/tint/lang/spirv/writer/writer.h
index 30b9549..afa6747 100644
--- a/src/tint/lang/spirv/writer/writer.h
+++ b/src/tint/lang/spirv/writer/writer.h
@@ -31,7 +31,7 @@
 #include "src/tint/lang/core/ir/module.h"
 #include "src/tint/lang/spirv/writer/common/options.h"
 #include "src/tint/lang/spirv/writer/common/output.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 namespace tint::spirv::writer {
 
@@ -39,14 +39,14 @@
 /// @param ir the module
 /// @param options the writer options
 /// @returns Success or a failure message indicating why SPIR-V generation would fail
-Result<SuccessType> CanGenerate(const core::ir::Module& ir, const Options& options);
+diag::Result<SuccessType> CanGenerate(const core::ir::Module& ir, const Options& options);
 
 /// Generate SPIR-V for a program, according to a set of configuration options.
 /// The result will contain the SPIR-V or failure.
 /// @param ir the IR module to translate to SPIR-V
 /// @param options the configuration options to use when generating SPIR-V
 /// @returns the resulting SPIR-V and supplementary information, or failure.
-Result<Output> Generate(core::ir::Module& ir, const Options& options);
+diag::Result<Output> Generate(core::ir::Module& ir, const Options& options);
 
 }  // namespace tint::spirv::writer
 
diff --git a/src/tint/lang/spirv/writer/writer_fuzz.cc b/src/tint/lang/spirv/writer/writer_fuzz.cc
index f78d869..e46d4ed 100644
--- a/src/tint/lang/spirv/writer/writer_fuzz.cc
+++ b/src/tint/lang/spirv/writer/writer_fuzz.cc
@@ -35,7 +35,9 @@
 namespace tint::spirv::writer {
 namespace {
 
-Result<SuccessType> IRFuzzer(core::ir::Module& module, const fuzz::ir::Context&, Options options) {
+diag::Result<SuccessType> IRFuzzer(core::ir::Module& module,
+                                   const fuzz::ir::Context&,
+                                   Options options) {
     auto check = CanGenerate(module, options);
     if (check != Success) {
         return check;
diff --git a/src/tint/lang/wgsl/BUILD.bazel b/src/tint/lang/wgsl/BUILD.bazel
index b0e4521..69922f6 100644
--- a/src/tint/lang/wgsl/BUILD.bazel
+++ b/src/tint/lang/wgsl/BUILD.bazel
@@ -57,6 +57,7 @@
     "//src/tint/utils/macros",
     "//src/tint/utils/math",
     "//src/tint/utils/memory",
+    "//src/tint/utils/result",
     "//src/tint/utils/rtti",
     "//src/tint/utils/text",
     "//src/utils",
@@ -144,6 +145,7 @@
     "//src/tint/utils/macros",
     "//src/tint/utils/math",
     "//src/tint/utils/memory",
+    "//src/tint/utils/result",
     "//src/tint/utils/rtti",
     "//src/tint/utils/text",
     "@benchmark",
diff --git a/src/tint/lang/wgsl/BUILD.cmake b/src/tint/lang/wgsl/BUILD.cmake
index bfadd19..1c5c889 100644
--- a/src/tint/lang/wgsl/BUILD.cmake
+++ b/src/tint/lang/wgsl/BUILD.cmake
@@ -70,6 +70,7 @@
   tint_utils_macros
   tint_utils_math
   tint_utils_memory
+  tint_utils_result
   tint_utils_rtti
   tint_utils_text
 )
@@ -160,6 +161,7 @@
   tint_utils_macros
   tint_utils_math
   tint_utils_memory
+  tint_utils_result
   tint_utils_rtti
   tint_utils_text
 )
diff --git a/src/tint/lang/wgsl/BUILD.gn b/src/tint/lang/wgsl/BUILD.gn
index 05cbc91..fcc4649 100644
--- a/src/tint/lang/wgsl/BUILD.gn
+++ b/src/tint/lang/wgsl/BUILD.gn
@@ -62,6 +62,7 @@
     "${tint_src_dir}/utils/macros",
     "${tint_src_dir}/utils/math",
     "${tint_src_dir}/utils/memory",
+    "${tint_src_dir}/utils/result",
     "${tint_src_dir}/utils/rtti",
     "${tint_src_dir}/utils/text",
   ]
@@ -138,6 +139,7 @@
       "${tint_src_dir}/utils/macros",
       "${tint_src_dir}/utils/math",
       "${tint_src_dir}/utils/memory",
+      "${tint_src_dir}/utils/result",
       "${tint_src_dir}/utils/rtti",
       "${tint_src_dir}/utils/text",
     ]
diff --git a/src/tint/lang/wgsl/reader/lower/lower.cc b/src/tint/lang/wgsl/reader/lower/lower.cc
index 73d3c5f..6458b6a 100644
--- a/src/tint/lang/wgsl/reader/lower/lower.cc
+++ b/src/tint/lang/wgsl/reader/lower/lower.cc
@@ -208,7 +208,7 @@
 
 }  // namespace
 
-Result<SuccessType> Lower(core::ir::Module& mod) {
+diag::Result<SuccessType> Lower(core::ir::Module& mod) {
     auto res = core::ir::ValidateAndDumpIfNeeded(
         mod, "wgsl.Lower", core::ir::Capabilities{core::ir::Capability::kAllowOverrides});
     if (res != Success) {
diff --git a/src/tint/lang/wgsl/reader/lower/lower.h b/src/tint/lang/wgsl/reader/lower/lower.h
index b11a139..2e744ee 100644
--- a/src/tint/lang/wgsl/reader/lower/lower.h
+++ b/src/tint/lang/wgsl/reader/lower/lower.h
@@ -36,7 +36,7 @@
 /// Lower converts a WGSL-dialect IR module to a core-dialect IR module
 /// @param  mod the IR module
 /// @return the result of the operation
-Result<SuccessType> Lower(core::ir::Module& mod);
+diag::Result<SuccessType> Lower(core::ir::Module& mod);
 
 }  // namespace tint::wgsl::reader
 
diff --git a/src/tint/lang/wgsl/reader/program_to_ir/ir_program_test.h b/src/tint/lang/wgsl/reader/program_to_ir/ir_program_test.h
index 0761c34..ad33c3c5 100644
--- a/src/tint/lang/wgsl/reader/program_to_ir/ir_program_test.h
+++ b/src/tint/lang/wgsl/reader/program_to_ir/ir_program_test.h
@@ -50,10 +50,10 @@
 
     /// Builds a core-dialect module from this ProgramBuilder.
     /// @returns the generated core-dialect module
-    tint::Result<core::ir::Module> Build() {
+    diag::Result<core::ir::Module> Build() {
         Program program{resolver::Resolve(*this)};
         if (!program.IsValid()) {
-            return Failure{program.Diagnostics()};
+            return diag::Failure{program.Diagnostics()};
         }
 
         auto result = wgsl::reader::ProgramToIR(program);
@@ -76,7 +76,7 @@
     /// Build the module from the given WGSL.
     /// @param wgsl the WGSL to convert to IR
     /// @returns the generated module
-    Result<core::ir::Module> Build(std::string wgsl) {
+    diag::Result<core::ir::Module> Build(std::string wgsl) {
         Source::File file("test.wgsl", std::move(wgsl));
         auto result = wgsl::reader::WgslToIR(&file);
         if (result == Success) {
diff --git a/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc b/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc
index 40274cb..5be779a 100644
--- a/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc
+++ b/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc
@@ -118,7 +118,7 @@
 namespace tint::wgsl::reader {
 namespace {
 
-using ResultType = tint::Result<core::ir::Module>;
+using ResultType = diag::Result<core::ir::Module>;
 
 /// Impl is the private-implementation of FromProgram().
 class Impl {
@@ -257,7 +257,7 @@
         }
 
         if (diagnostics_.ContainsErrors()) {
-            return Failure{std::move(diagnostics_)};
+            return diag::Failure{std::move(diagnostics_)};
         }
 
         return std::move(mod);
@@ -1373,9 +1373,9 @@
 
 }  // namespace
 
-tint::Result<core::ir::Module> ProgramToIR(const Program& program) {
+diag::Result<core::ir::Module> ProgramToIR(const Program& program) {
     if (!program.IsValid()) {
-        return Failure{program.Diagnostics()};
+        return diag::Failure{program.Diagnostics()};
     }
 
     Impl b(program);
@@ -1383,7 +1383,7 @@
     if (r != Success) {
         diag::List err = std::move(r.Failure().reason);
         err.AddNote(Source{}) << "AST:\n" + Program::printer(program);
-        return Failure{err};
+        return diag::Failure{err};
     }
 
     return r.Move();
diff --git a/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.h b/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.h
index 822467d..c52c810 100644
--- a/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.h
+++ b/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.h
@@ -29,7 +29,7 @@
 #define SRC_TINT_LANG_WGSL_READER_PROGRAM_TO_IR_PROGRAM_TO_IR_H_
 
 #include "src/tint/lang/core/ir/module.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward Declarations
 namespace tint {
@@ -45,7 +45,7 @@
 /// @note this assumes the `program.IsValid()`, and has had const-eval done so
 /// any abstract values have been calculated and converted into the relevant
 /// concrete types.
-tint::Result<core::ir::Module> ProgramToIR(const Program& program);
+diag::Result<core::ir::Module> ProgramToIR(const Program& program);
 
 }  // namespace tint::wgsl::reader
 
diff --git a/src/tint/lang/wgsl/reader/reader.cc b/src/tint/lang/wgsl/reader/reader.cc
index e9792ae..026a202 100644
--- a/src/tint/lang/wgsl/reader/reader.cc
+++ b/src/tint/lang/wgsl/reader/reader.cc
@@ -49,12 +49,12 @@
     return resolver::Resolve(parser.builder(), options.allowed_features);
 }
 
-Result<core::ir::Module> WgslToIR(const Source::File* file, const Options& options) {
+diag::Result<core::ir::Module> WgslToIR(const Source::File* file, const Options& options) {
     Program program = Parse(file, options);
     return ProgramToLoweredIR(program);
 }
 
-tint::Result<core::ir::Module> ProgramToLoweredIR(const Program& program) {
+diag::Result<core::ir::Module> ProgramToLoweredIR(const Program& program) {
     auto ir = ProgramToIR(program);
     if (ir != Success) {
         return ir.Failure();
diff --git a/src/tint/lang/wgsl/reader/reader.h b/src/tint/lang/wgsl/reader/reader.h
index 991e3e0..faf594e 100644
--- a/src/tint/lang/wgsl/reader/reader.h
+++ b/src/tint/lang/wgsl/reader/reader.h
@@ -51,7 +51,7 @@
 /// @param file the input WGSL file
 /// @param options the configuration options to use when parsing WGSL
 /// @returns the resulting IR module, or failure
-Result<core::ir::Module> WgslToIR(const Source::File* file, const Options& options = {});
+diag::Result<core::ir::Module> WgslToIR(const Source::File* file, const Options& options = {});
 
 /// Builds a core-dialect core::ir::Module from the given Program
 /// @param program the Program to use.
@@ -60,7 +60,7 @@
 /// @note this assumes the `program.IsValid()`, and has had const-eval done so
 /// any abstract values have been calculated and converted into the relevant
 /// concrete types.
-tint::Result<core::ir::Module> ProgramToLoweredIR(const Program& program);
+diag::Result<core::ir::Module> ProgramToLoweredIR(const Program& program);
 
 /// Allows for checking if an extension is currently supported/unsupported by IR
 /// before trying to convert to it.
diff --git a/src/tint/lang/wgsl/resolver/resolver.cc b/src/tint/lang/wgsl/resolver/resolver.cc
index f747bf4..350e481 100644
--- a/src/tint/lang/wgsl/resolver/resolver.cc
+++ b/src/tint/lang/wgsl/resolver/resolver.cc
@@ -28,8 +28,6 @@
 #include "src/tint/lang/wgsl/resolver/resolver.h"
 
 #include <algorithm>
-#include <cmath>
-#include <iomanip>
 #include <limits>
 #include <string_view>
 #include <utility>
diff --git a/src/tint/lang/wgsl/writer/raise/ptr_to_ref.cc b/src/tint/lang/wgsl/writer/raise/ptr_to_ref.cc
index b7a2342..92d8036 100644
--- a/src/tint/lang/wgsl/writer/raise/ptr_to_ref.cc
+++ b/src/tint/lang/wgsl/writer/raise/ptr_to_ref.cc
@@ -44,7 +44,7 @@
     core::ir::Module& mod;
     core::ir::Builder b{mod};
 
-    Result<SuccessType> Run() {
+    void Run() {
         Vector<core::ir::Block*, 32> blocks;
         for (auto fn : mod.functions) {
             blocks.Push(fn->Block());
@@ -89,8 +89,6 @@
                     });
             }
         }
-
-        return Success;
     }
 
     void OperandsRefToPtr(core::ir::Instruction* inst) {
@@ -140,8 +138,10 @@
 
 }  // namespace
 
-Result<SuccessType> PtrToRef(core::ir::Module& mod) {
-    return Impl{mod}.Run();
+diag::Result<SuccessType> PtrToRef(core::ir::Module& mod) {
+    Impl{mod}.Run();
+
+    return Success;
 }
 
 }  // namespace tint::wgsl::writer::raise
diff --git a/src/tint/lang/wgsl/writer/raise/ptr_to_ref.h b/src/tint/lang/wgsl/writer/raise/ptr_to_ref.h
index 2d4279c..bad2ebe 100644
--- a/src/tint/lang/wgsl/writer/raise/ptr_to_ref.h
+++ b/src/tint/lang/wgsl/writer/raise/ptr_to_ref.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_WGSL_WRITER_RAISE_PTR_TO_REF_H_
 #define SRC_TINT_LANG_WGSL_WRITER_RAISE_PTR_TO_REF_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -41,7 +41,7 @@
 /// reference types.
 /// @param module the module to transform
 /// @returns success or failure
-Result<SuccessType> PtrToRef(core::ir::Module& module);
+diag::Result<SuccessType> PtrToRef(core::ir::Module& module);
 
 }  // namespace tint::wgsl::writer::raise
 
diff --git a/src/tint/lang/wgsl/writer/raise/ptr_to_ref_fuzz.cc b/src/tint/lang/wgsl/writer/raise/ptr_to_ref_fuzz.cc
index 9141041..2b214ec 100644
--- a/src/tint/lang/wgsl/writer/raise/ptr_to_ref_fuzz.cc
+++ b/src/tint/lang/wgsl/writer/raise/ptr_to_ref_fuzz.cc
@@ -33,7 +33,7 @@
 namespace tint::wgsl::writer::raise {
 namespace {
 
-Result<SuccessType> PtrToRefFuzzer(core::ir::Module& ir, const fuzz::ir::Context&) {
+diag::Result<SuccessType> PtrToRefFuzzer(core::ir::Module& ir, const fuzz::ir::Context&) {
     return PtrToRef(ir);
 }
 
diff --git a/src/tint/lang/wgsl/writer/raise/raise.cc b/src/tint/lang/wgsl/writer/raise/raise.cc
index 4151c96..f67fab7 100644
--- a/src/tint/lang/wgsl/writer/raise/raise.cc
+++ b/src/tint/lang/wgsl/writer/raise/raise.cc
@@ -256,7 +256,7 @@
 
 }  // namespace
 
-Result<SuccessType> Raise(core::ir::Module& mod) {
+diag::Result<SuccessType> Raise(core::ir::Module& mod) {
     core::ir::Builder b{mod};
     for (auto* inst : mod.Instructions()) {
         if (auto* call = inst->As<core::ir::CoreBuiltinCall>()) {
diff --git a/src/tint/lang/wgsl/writer/raise/raise.h b/src/tint/lang/wgsl/writer/raise/raise.h
index 1d0a9cc..2a91c4f 100644
--- a/src/tint/lang/wgsl/writer/raise/raise.h
+++ b/src/tint/lang/wgsl/writer/raise/raise.h
@@ -30,14 +30,13 @@
 
 #include "src/tint/lang/core/ir/module.h"
 #include "src/tint/utils/diagnostic/diagnostic.h"
-#include "src/tint/utils/result/result.h"
 
 namespace tint::wgsl::writer {
 
 /// Raise converts a core-dialect IR module to a WGSL-dialect IR module
 /// @param  mod the IR module
 /// @return the result of the operation
-Result<SuccessType> Raise(core::ir::Module& mod);
+diag::Result<SuccessType> Raise(core::ir::Module& mod);
 
 }  // namespace tint::wgsl::writer
 
diff --git a/src/tint/lang/wgsl/writer/raise/raise_fuzz.cc b/src/tint/lang/wgsl/writer/raise/raise_fuzz.cc
index ead8f89..63d4ad7 100644
--- a/src/tint/lang/wgsl/writer/raise/raise_fuzz.cc
+++ b/src/tint/lang/wgsl/writer/raise/raise_fuzz.cc
@@ -33,7 +33,7 @@
 namespace tint::wgsl::writer::raise {
 namespace {
 
-Result<SuccessType> RaiseFuzzer(core::ir::Module& ir, const fuzz::ir::Context&) {
+diag::Result<SuccessType> RaiseFuzzer(core::ir::Module& ir, const fuzz::ir::Context&) {
     return Raise(ir);
 }
 
diff --git a/src/tint/lang/wgsl/writer/raise/value_to_let.cc b/src/tint/lang/wgsl/writer/raise/value_to_let.cc
index 4c08108..38c98ee 100644
--- a/src/tint/lang/wgsl/writer/raise/value_to_let.cc
+++ b/src/tint/lang/wgsl/writer/raise/value_to_let.cc
@@ -192,7 +192,7 @@
 
 }  // namespace
 
-Result<SuccessType> ValueToLet(core::ir::Module& ir) {
+diag::Result<SuccessType> ValueToLet(core::ir::Module& ir) {
     auto result = core::ir::ValidateAndDumpIfNeeded(ir, "wgsl.ValueToLet",
                                                     core::ir::Capabilities{
                                                         core::ir::Capability::kAllowOverrides,
diff --git a/src/tint/lang/wgsl/writer/raise/value_to_let.h b/src/tint/lang/wgsl/writer/raise/value_to_let.h
index 2a3b4c0..2518f66 100644
--- a/src/tint/lang/wgsl/writer/raise/value_to_let.h
+++ b/src/tint/lang/wgsl/writer/raise/value_to_let.h
@@ -28,7 +28,7 @@
 #ifndef SRC_TINT_LANG_WGSL_WRITER_RAISE_VALUE_TO_LET_H_
 #define SRC_TINT_LANG_WGSL_WRITER_RAISE_VALUE_TO_LET_H_
 
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations.
 namespace tint::core::ir {
@@ -47,7 +47,7 @@
 ///
 /// @param module the module to transform
 /// @returns error diagnostics on failure
-Result<SuccessType> ValueToLet(core::ir::Module& module);
+diag::Result<SuccessType> ValueToLet(core::ir::Module& module);
 
 }  // namespace tint::wgsl::writer::raise
 
diff --git a/src/tint/lang/wgsl/writer/raise/value_to_let_fuzz.cc b/src/tint/lang/wgsl/writer/raise/value_to_let_fuzz.cc
index 166c3c7..79b35ad 100644
--- a/src/tint/lang/wgsl/writer/raise/value_to_let_fuzz.cc
+++ b/src/tint/lang/wgsl/writer/raise/value_to_let_fuzz.cc
@@ -33,7 +33,7 @@
 namespace tint::wgsl::writer::raise {
 namespace {
 
-Result<SuccessType> ValueToLetFuzzer(core::ir::Module& ir, const fuzz::ir::Context&) {
+diag::Result<SuccessType> ValueToLetFuzzer(core::ir::Module& ir, const fuzz::ir::Context&) {
     return ValueToLet(ir);
 }
 
diff --git a/src/tint/lang/wgsl/writer/writer.cc b/src/tint/lang/wgsl/writer/writer.cc
index 4013848..cd4c44c 100644
--- a/src/tint/lang/wgsl/writer/writer.cc
+++ b/src/tint/lang/wgsl/writer/writer.cc
@@ -28,7 +28,6 @@
 #include "src/tint/lang/wgsl/writer/writer.h"
 
 #include <memory>
-#include <utility>
 
 #include "src/tint/lang/wgsl/program/program.h"
 #include "src/tint/lang/wgsl/writer/ast_printer/ast_printer.h"
@@ -41,7 +40,7 @@
 
 namespace tint::wgsl::writer {
 
-Result<Output> Generate(const Program& program, const Options& options) {
+diag::Result<Output> Generate(const Program& program, const Options& options) {
     (void)options;
 
     Output output;
@@ -50,7 +49,7 @@
         // Generate the WGSL code.
         auto impl = std::make_unique<SyntaxTreePrinter>(program);
         if (!impl->Generate()) {
-            return Failure{impl->Diagnostics()};
+            return diag::Failure{impl->Diagnostics()};
         }
         output.wgsl = impl->Result();
     } else  // NOLINT(readability/braces)
@@ -59,7 +58,7 @@
         // Generate the WGSL code.
         auto impl = std::make_unique<ASTPrinter>(program);
         if (!impl->Generate()) {
-            return Failure{impl->Diagnostics()};
+            return diag::Failure{impl->Diagnostics()};
         }
         output.wgsl = impl->Result();
     }
@@ -67,7 +66,7 @@
     return output;
 }
 
-Result<Output> WgslFromIR(core::ir::Module& module, const ProgramOptions& options) {
+diag::Result<Output> WgslFromIR(core::ir::Module& module, const ProgramOptions& options) {
     auto res = ProgramFromIR(module, options);
     if (res != Success) {
         return res.Failure();
@@ -75,7 +74,7 @@
     return Generate(res.Move(), Options{});
 }
 
-Result<Program> ProgramFromIR(core::ir::Module& module, const ProgramOptions& options) {
+diag::Result<Program> ProgramFromIR(core::ir::Module& module, const ProgramOptions& options) {
     // core-dialect -> WGSL-dialect
     if (auto res = Raise(module); res != Success) {
         return res.Failure();
@@ -83,7 +82,7 @@
 
     auto program = IRToProgram(module, options);
     if (!program.IsValid()) {
-        return Failure{program.Diagnostics()};
+        return diag::Failure{program.Diagnostics()};
     }
 
     return program;
diff --git a/src/tint/lang/wgsl/writer/writer.h b/src/tint/lang/wgsl/writer/writer.h
index a79ea4d..a877bad 100644
--- a/src/tint/lang/wgsl/writer/writer.h
+++ b/src/tint/lang/wgsl/writer/writer.h
@@ -31,7 +31,7 @@
 #include "src/tint/lang/wgsl/writer/ir_to_program/program_options.h"
 #include "src/tint/lang/wgsl/writer/options.h"
 #include "src/tint/lang/wgsl/writer/output.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 
 // Forward declarations
 namespace tint {
@@ -48,18 +48,18 @@
 /// @param program the program to translate to WGSL
 /// @param options the configuration options to use when generating WGSL
 /// @returns the resulting WGSL, or failure
-Result<Output> Generate(const Program& program, const Options& options);
+diag::Result<Output> Generate(const Program& program, const Options& options);
 
 /// Generate WGSL from a core-dialect ir::Module.
 /// @param module the core-dialect ir::Module.
 /// @param options the configuration options to use when generating WGSL
 /// @returns the resulting WGSL, or failure
-Result<Output> WgslFromIR(core::ir::Module& module, const ProgramOptions& options);
+diag::Result<Output> WgslFromIR(core::ir::Module& module, const ProgramOptions& options);
 
 /// Generate a Program from a core-dialect ir::Module.
 /// @param module the core-dialect ir::Module.
 /// @returns the resulting Program, or failure
-Result<Program> ProgramFromIR(core::ir::Module& module, const ProgramOptions& options);
+diag::Result<Program> ProgramFromIR(core::ir::Module& module, const ProgramOptions& options);
 
 }  // namespace tint::wgsl::writer
 
diff --git a/src/tint/utils/bytes/buffer_reader.cc b/src/tint/utils/bytes/buffer_reader.cc
index f97276e..a1c3541 100644
--- a/src/tint/utils/bytes/buffer_reader.cc
+++ b/src/tint/utils/bytes/buffer_reader.cc
@@ -27,6 +27,8 @@
 
 #include "src/tint/utils/bytes/buffer_reader.h"
 
+#include <algorithm>
+
 #include "src/tint/utils/macros/compiler.h"
 
 TINT_BEGIN_DISABLE_WARNING(UNSAFE_BUFFER_USAGE);
diff --git a/src/tint/utils/bytes/buffer_reader.h b/src/tint/utils/bytes/buffer_reader.h
index 0367bb0..8a91d6d 100644
--- a/src/tint/utils/bytes/buffer_reader.h
+++ b/src/tint/utils/bytes/buffer_reader.h
@@ -28,10 +28,10 @@
 #ifndef SRC_TINT_UTILS_BYTES_BUFFER_READER_H_
 #define SRC_TINT_UTILS_BYTES_BUFFER_READER_H_
 
-#include <algorithm>
-#include <string>
+#include <string_view>
 
 #include "src/tint/utils/bytes/reader.h"
+#include "src/tint/utils/containers/slice.h"
 #include "src/tint/utils/ice/ice.h"
 
 namespace tint::bytes {
@@ -50,10 +50,9 @@
     }
 
     /// Constructor
-    /// @param string the string to read from
-    explicit BufferReader(std::string_view string)
-        : data_(reinterpret_cast<const std::byte*>(string.data())),
-          bytes_remaining_(string.length()) {}
+    /// @param str the string to read from
+    explicit BufferReader(std::string_view str)
+        : data_(reinterpret_cast<const std::byte*>(str.data())), bytes_remaining_(str.length()) {}
 
     /// Constructor
     /// @param slice the byte slice to read from
diff --git a/src/tint/utils/bytes/decoder.h b/src/tint/utils/bytes/decoder.h
index 4f218d7..6115790 100644
--- a/src/tint/utils/bytes/decoder.h
+++ b/src/tint/utils/bytes/decoder.h
@@ -39,6 +39,7 @@
 #include <vector>
 
 #include "src/tint/utils/bytes/reader.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 #include "src/tint/utils/reflection.h"
 
 namespace tint::bytes {
@@ -51,7 +52,7 @@
 /// @param args additional arguments used by Decoder<T>::Decode()
 /// @returns the decoded object
 template <typename T, typename... ARGS>
-Result<T> Decode(Reader& reader, ARGS&&... args) {
+diag::Result<T> Decode(Reader& reader, ARGS&&... args) {
     return Decoder<T>::Decode(reader, std::forward<ARGS>(args)...);
 }
 
@@ -62,7 +63,7 @@
     /// @param reader the reader to decode from
     /// @param endianness the endianness of the integer
     /// @returns the decoded integer type, or an error if the stream is too short.
-    static Result<T> Decode(Reader& reader, Endianness endianness = Endianness::kLittle) {
+    static diag::Result<T> Decode(Reader& reader, Endianness endianness = Endianness::kLittle) {
         return reader.Int<T>(endianness);
     }
 };
@@ -73,7 +74,7 @@
     /// Decode decodes the floating point type from @p reader.
     /// @param reader the reader to decode from
     /// @returns the decoded floating point type, or an error if the stream is too short.
-    static Result<T> Decode(Reader& reader) { return reader.Float<T>(); }
+    static diag::Result<T> Decode(Reader& reader) { return reader.Float<T>(); }
 };
 
 /// Decoder specialization for a uint16_t length prefixed string.
@@ -82,7 +83,7 @@
     /// Decode decodes the string from @p reader.
     /// @param reader the reader to decode from
     /// @returns the decoded string, or an error if the stream is too short.
-    static Result<std::string> Decode(Reader& reader) {
+    static diag::Result<std::string> Decode(Reader& reader) {
         auto len = reader.Int<uint16_t>();
         if (len != Success) {
             return len.Failure();
@@ -97,7 +98,7 @@
     /// Decode decodes the boolean from @p reader.
     /// @param reader the reader to decode from
     /// @returns the decoded boolean, or an error if the stream is too short.
-    static Result<bool> Decode(Reader& reader) { return reader.Bool(); }
+    static diag::Result<bool> Decode(Reader& reader) { return reader.Bool(); }
 };
 
 /// Decoder specialization for types that use TINT_REFLECT
@@ -106,7 +107,7 @@
     /// Decode decodes the reflected type from @p reader.
     /// @param reader the reader to decode from
     /// @returns the decoded reflected type, or an error if the stream is too short.
-    static Result<T> Decode(Reader& reader) {
+    static diag::Result<T> Decode(Reader& reader) {
         T object{};
         diag::List errs;
         ForeachField(object, [&](auto& field) {  //
@@ -120,7 +121,7 @@
         if (errs.empty()) {
             return object;
         }
-        return Failure{errs};
+        return diag::Failure{errs};
     }
 };
 
@@ -130,7 +131,7 @@
     /// Decode decodes the map from @p reader.
     /// @param reader the reader to decode from
     /// @returns the decoded map, or an error if the stream is too short.
-    static Result<std::unordered_map<K, V>> Decode(Reader& reader) {
+    static diag::Result<std::unordered_map<K, V>> Decode(Reader& reader) {
         std::unordered_map<K, V> out;
 
         while (!reader.IsEOF()) {
@@ -162,7 +163,7 @@
     /// Decode decodes the set from @p reader.
     /// @param reader the reader to decode from
     /// @returns the decoded set, or an error if the stream is too short.
-    static Result<std::unordered_set<V>> Decode(Reader& reader) {
+    static diag::Result<std::unordered_set<V>> Decode(Reader& reader) {
         std::unordered_set<V> out;
 
         while (!reader.IsEOF()) {
@@ -190,7 +191,7 @@
     /// Decode decodes the vector from @p reader.
     /// @param reader the reader to decode from
     /// @returns the decoded vector, or an error if the stream is too short.
-    static Result<std::vector<V>> Decode(Reader& reader) {
+    static diag::Result<std::vector<V>> Decode(Reader& reader) {
         std::vector<V> out;
 
         while (!reader.IsEOF()) {
@@ -218,7 +219,7 @@
     /// Decode decodes the optional from @p reader.
     /// @param reader the reader to decode from
     /// @returns the decoded optional, or an error if the stream is too short.
-    static Result<std::optional<T>> Decode(Reader& reader) {
+    static diag::Result<std::optional<T>> Decode(Reader& reader) {
         auto has_value = bytes::Decode<bool>(reader);
         if (has_value != Success) {
             return has_value.Failure();
@@ -240,12 +241,12 @@
     /// Decode decodes the bitset from @p reader.
     /// @param reader the reader to decode from
     /// @returns the decoded bitset, or an error if the stream is too short.
-    static Result<std::bitset<N>> Decode(Reader& reader) {
+    static diag::Result<std::bitset<N>> Decode(Reader& reader) {
         Vector<std::byte, 32> vec;
         vec.Resize((N + CHAR_BIT - 1) / CHAR_BIT);
 
         if (auto len = reader.Read(&vec[0], vec.Length()); len != vec.Length()) {
-            return Failure{"EOF"};
+            return diag::Failure{"EOF"};
         }
 
         std::bitset<N> out;
@@ -264,7 +265,7 @@
     /// Decode decodes the tuple from @p reader.
     /// @param reader the reader to decode from
     /// @returns the decoded tuple, or an error if the stream is too short.
-    static Result<std::tuple<FIRST, OTHERS...>> Decode(Reader& reader) {
+    static diag::Result<std::tuple<FIRST, OTHERS...>> Decode(Reader& reader) {
         auto first = bytes::Decode<FIRST>(reader);
         if (first != Success) {
             return first.Failure();
@@ -288,7 +289,7 @@
     /// @param reader the reader to decode from
     /// @param endianness the endianness of the enum
     /// @returns the decoded enum type, or an error if the stream is too short.
-    static Result<T> Decode(Reader& reader, Endianness endianness = Endianness::kLittle) {
+    static diag::Result<T> Decode(Reader& reader, Endianness endianness = Endianness::kLittle) {
         using Range = tint::EnumRange<T>;
         using U = std::underlying_type_t<T>;
         auto value = reader.Int<U>(endianness);
@@ -298,7 +299,7 @@
         static constexpr U kMin = static_cast<U>(Range::kMin);
         static constexpr U kMax = static_cast<U>(Range::kMax);
         if (value.Get() < kMin || value.Get() > kMax) {
-            return Failure{"value " + std::to_string(value.Get()) + " out of range for enum"};
+            return diag::Failure{"value " + std::to_string(value.Get()) + " out of range for enum"};
         }
         return static_cast<T>(value.Get());
     }
diff --git a/src/tint/utils/bytes/reader.h b/src/tint/utils/bytes/reader.h
index f0d074a..57d3cf7 100644
--- a/src/tint/utils/bytes/reader.h
+++ b/src/tint/utils/bytes/reader.h
@@ -32,7 +32,8 @@
 
 #include "src/tint/utils/bytes/endianness.h"
 #include "src/tint/utils/bytes/swap.h"
-#include "src/tint/utils/result/result.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
+
 namespace tint::bytes {
 
 /// A binary stream reader interface
@@ -59,11 +60,11 @@
     /// @param endianness the encoded endianness of the integer
     /// @return the deserialized integer
     template <typename T>
-    Result<T> Int(Endianness endianness = Endianness::kLittle) {
+    diag::Result<T> Int(Endianness endianness = Endianness::kLittle) {
         static_assert(std::is_integral_v<T>);
         T out = 0;
         if (size_t n = Read(reinterpret_cast<std::byte*>(&out), sizeof(T)); n != sizeof(T)) {
-            return Failure{"EOF"};
+            return diag::Failure{"EOF"};
         }
         if (NativeEndianness() != endianness) {
             out = Swap(out);
@@ -75,11 +76,11 @@
     /// If there are too few bytes remaining in the stream, then a failure is returned.
     /// @return the deserialized floating point number
     template <typename T>
-    Result<T> Float() {
+    diag::Result<T> Float() {
         static_assert(std::is_floating_point_v<T>);
         T out = 0;
         if (size_t n = Read(reinterpret_cast<std::byte*>(&out), sizeof(T)); n != sizeof(T)) {
-            return Failure{"EOF"};
+            return diag::Failure{"EOF"};
         }
         return out;
     }
@@ -87,10 +88,10 @@
     /// Reads a boolean from the stream
     /// If there are too few bytes remaining in the stream, then a failure is returned.
     /// @returns true if the next byte is non-zero
-    Result<bool> Bool() {
+    diag::Result<bool> Bool() {
         std::byte b{0};
         if (size_t n = Read(&b, 1); n != 1) {
-            return Failure{"EOF"};
+            return diag::Failure{"EOF"};
         }
         return b != std::byte{0};
     }
@@ -99,12 +100,12 @@
     /// If there are too few bytes remaining in the stream, then a failure is returned.
     /// @param len the length of the returned string in bytes
     /// @return the deserialized string
-    Result<std::string> String(size_t len) {
+    diag::Result<std::string> String(size_t len) {
         std::string out;
         out.resize(len);
         if (size_t n = Read(reinterpret_cast<std::byte*>(out.data()), sizeof(char) * len);
             n != len) {
-            return Failure{"EOF"};
+            return diag::Failure{"EOF"};
         }
         return out;
     }
diff --git a/src/tint/utils/command/BUILD.bazel b/src/tint/utils/command/BUILD.bazel
index 4d8aecb..23079da 100644
--- a/src/tint/utils/command/BUILD.bazel
+++ b/src/tint/utils/command/BUILD.bazel
@@ -64,7 +64,6 @@
   ],
   deps = [
     "//src/tint/utils/containers",
-    "//src/tint/utils/diagnostic",
     "//src/tint/utils/ice",
     "//src/tint/utils/macros",
     "//src/tint/utils/math",
@@ -89,7 +88,6 @@
   deps = [
     "//src/tint/utils/command",
     "//src/tint/utils/containers",
-    "//src/tint/utils/diagnostic",
     "//src/tint/utils/ice",
     "//src/tint/utils/macros",
     "//src/tint/utils/math",
diff --git a/src/tint/utils/command/BUILD.cmake b/src/tint/utils/command/BUILD.cmake
index 8d730ef..12642a0 100644
--- a/src/tint/utils/command/BUILD.cmake
+++ b/src/tint/utils/command/BUILD.cmake
@@ -48,7 +48,6 @@
 
 tint_target_add_dependencies(tint_utils_command lib
   tint_utils_containers
-  tint_utils_diagnostic
   tint_utils_ice
   tint_utils_macros
   tint_utils_math
@@ -94,7 +93,6 @@
 tint_target_add_dependencies(tint_utils_command_test test
   tint_utils_command
   tint_utils_containers
-  tint_utils_diagnostic
   tint_utils_ice
   tint_utils_macros
   tint_utils_math
diff --git a/src/tint/utils/command/BUILD.gn b/src/tint/utils/command/BUILD.gn
index 86a0acb..8d68407 100644
--- a/src/tint/utils/command/BUILD.gn
+++ b/src/tint/utils/command/BUILD.gn
@@ -54,7 +54,6 @@
   deps = [
     "${dawn_root}/src/utils:utils",
     "${tint_src_dir}/utils/containers",
-    "${tint_src_dir}/utils/diagnostic",
     "${tint_src_dir}/utils/ice",
     "${tint_src_dir}/utils/macros",
     "${tint_src_dir}/utils/math",
@@ -89,7 +88,6 @@
       "${tint_src_dir}:gmock_and_gtest",
       "${tint_src_dir}/utils/command",
       "${tint_src_dir}/utils/containers",
-      "${tint_src_dir}/utils/diagnostic",
       "${tint_src_dir}/utils/ice",
       "${tint_src_dir}/utils/macros",
       "${tint_src_dir}/utils/math",
diff --git a/src/tint/utils/command/cli.cc b/src/tint/utils/command/cli.cc
index ea28581..0fd8c11 100644
--- a/src/tint/utils/command/cli.cc
+++ b/src/tint/utils/command/cli.cc
@@ -33,7 +33,7 @@
 
 #include "src/tint/utils/containers/hashset.h"
 #include "src/tint/utils/containers/transform.h"
-#include "src/tint/utils/text/string.h"
+#include "src/tint/utils/text/styled_text.h"
 
 namespace tint::cli {
 
diff --git a/src/tint/utils/command/cli_test.cc b/src/tint/utils/command/cli_test.cc
index fc33cbd..5941ad8 100644
--- a/src/tint/utils/command/cli_test.cc
+++ b/src/tint/utils/command/cli_test.cc
@@ -189,7 +189,7 @@
 
     auto res = opts.Parse(Split("--myoption false", " "));
     ASSERT_NE(res, Success);
-    EXPECT_EQ(res.Failure().reason.Str(), R"(error: unknown flag: --myoption
+    EXPECT_EQ(res.Failure().reason, R"(unknown flag: --myoption
 Did you mean '--my_option'?)");
 }
 
diff --git a/src/tint/utils/diagnostic/BUILD.bazel b/src/tint/utils/diagnostic/BUILD.bazel
index 693b7e1..47013bdd 100644
--- a/src/tint/utils/diagnostic/BUILD.bazel
+++ b/src/tint/utils/diagnostic/BUILD.bazel
@@ -54,6 +54,7 @@
     "//src/tint/utils/macros",
     "//src/tint/utils/math",
     "//src/tint/utils/memory",
+    "//src/tint/utils/result",
     "//src/tint/utils/rtti",
     "//src/tint/utils/text",
     "//src/utils",
@@ -76,6 +77,7 @@
     "//src/tint/utils/macros",
     "//src/tint/utils/math",
     "//src/tint/utils/memory",
+    "//src/tint/utils/result",
     "//src/tint/utils/rtti",
     "//src/tint/utils/text",
     "@gtest",
diff --git a/src/tint/utils/diagnostic/BUILD.cmake b/src/tint/utils/diagnostic/BUILD.cmake
index 182e71c..777d039 100644
--- a/src/tint/utils/diagnostic/BUILD.cmake
+++ b/src/tint/utils/diagnostic/BUILD.cmake
@@ -53,6 +53,7 @@
   tint_utils_macros
   tint_utils_math
   tint_utils_memory
+  tint_utils_result
   tint_utils_rtti
   tint_utils_text
 )
@@ -78,6 +79,7 @@
   tint_utils_macros
   tint_utils_math
   tint_utils_memory
+  tint_utils_result
   tint_utils_rtti
   tint_utils_text
 )
diff --git a/src/tint/utils/diagnostic/BUILD.gn b/src/tint/utils/diagnostic/BUILD.gn
index f79f068..0e544d9 100644
--- a/src/tint/utils/diagnostic/BUILD.gn
+++ b/src/tint/utils/diagnostic/BUILD.gn
@@ -59,6 +59,7 @@
     "${tint_src_dir}/utils/macros",
     "${tint_src_dir}/utils/math",
     "${tint_src_dir}/utils/memory",
+    "${tint_src_dir}/utils/result",
     "${tint_src_dir}/utils/rtti",
     "${tint_src_dir}/utils/text",
   ]
@@ -79,6 +80,7 @@
       "${tint_src_dir}/utils/macros",
       "${tint_src_dir}/utils/math",
       "${tint_src_dir}/utils/memory",
+      "${tint_src_dir}/utils/result",
       "${tint_src_dir}/utils/rtti",
       "${tint_src_dir}/utils/text",
     ]
diff --git a/src/tint/utils/diagnostic/diagnostic.cc b/src/tint/utils/diagnostic/diagnostic.cc
index 2a21caa..b0825e0 100644
--- a/src/tint/utils/diagnostic/diagnostic.cc
+++ b/src/tint/utils/diagnostic/diagnostic.cc
@@ -73,4 +73,14 @@
     return Formatter{style}.Format(*this).Plain();
 }
 
+Failure::Failure() = default;
+
+Failure::Failure(std::string_view err) {
+    reason.AddError(Source{}) << err;
+}
+
+Failure::Failure(diag::Diagnostic diagnostic) : reason(diag::List{std::move(diagnostic)}) {}
+
+Failure::Failure(diag::List diagnostics) : reason(std::move(diagnostics)) {}
+
 }  // namespace tint::diag
diff --git a/src/tint/utils/diagnostic/diagnostic.h b/src/tint/utils/diagnostic/diagnostic.h
index 10dcf56..e85bc72 100644
--- a/src/tint/utils/diagnostic/diagnostic.h
+++ b/src/tint/utils/diagnostic/diagnostic.h
@@ -35,6 +35,7 @@
 
 #include "src/tint/utils/containers/vector.h"
 #include "src/tint/utils/diagnostic/source.h"
+#include "src/tint/utils/result/result.h"
 #include "src/tint/utils/rtti/traits.h"
 #include "src/tint/utils/text/styled_text.h"
 
@@ -220,6 +221,39 @@
     size_t error_count_ = 0;
 };
 
+/// The default Result error type.
+struct Failure {
+    /// Constructor with no diagnostics
+    Failure();
+
+    /// Constructor with a single diagnostic
+    /// @param err the single error diagnostic
+    explicit Failure(std::string_view err);
+
+    /// Constructor with a single diagnostic
+    /// @param diagnostic the failure diagnostic
+    explicit Failure(diag::Diagnostic diagnostic);
+
+    /// Constructor with a list of diagnostics
+    /// @param diagnostics the failure diagnostics
+    explicit Failure(diag::List diagnostics);
+
+    /// The diagnostics explaining the failure reason
+    diag::List reason;
+};
+
+template <typename SUCCESS_TYPE>
+using Result = ::tint::Result<SUCCESS_TYPE, diag::Failure>;
+
+/// Write the Failure to the given stream
+/// @param out the output stream
+/// @param failure the Failure
+/// @returns the output stream
+template <typename STREAM, typename = traits::EnableIfIsOStream<STREAM>>
+auto& operator<<(STREAM& out, const Failure& failure) {
+    return out << failure.reason;
+}
+
 /// Write the diagnostic list to the given stream
 /// @param out the output stream
 /// @param list the list to emit
diff --git a/src/tint/utils/reflection.cc b/src/tint/utils/reflection.cc
index 855189d..72bbcf0 100644
--- a/src/tint/utils/reflection.cc
+++ b/src/tint/utils/reflection.cc
@@ -35,13 +35,13 @@
 
 namespace tint::reflection::detail {
 
-Result<SuccessType> CheckAllFieldsReflected(VectorRef<ReflectedFieldInfo> fields,
-                                            std::string_view class_name,
-                                            size_t class_size,
-                                            size_t class_align,
-                                            bool class_is_castable,
-                                            std::string_view reflect_file,
-                                            uint32_t reflect_line) {
+diag::Result<SuccessType> CheckAllFieldsReflected(VectorRef<ReflectedFieldInfo> fields,
+                                                  std::string_view class_name,
+                                                  size_t class_size,
+                                                  size_t class_align,
+                                                  bool class_is_castable,
+                                                  std::string_view reflect_file,
+                                                  uint32_t reflect_line) {
     size_t calculated_offset = class_is_castable ? sizeof(CastableBase) : 0;
     for (auto& field : fields) {
         calculated_offset = RoundUp(field.align, calculated_offset);
@@ -57,7 +57,7 @@
             err.source.file = err.owned_file.get();
             err.source.range.begin.line = reflect_line;
             err.source.range.end.line = reflect_line;
-            return Failure{std::move(err)};
+            return diag::Failure{std::move(err)};
         }
         calculated_offset += field.size;
     }
@@ -74,7 +74,7 @@
         err.source.file = err.owned_file.get();
         err.source.range.begin.line = reflect_line;
         err.source.range.end.line = reflect_line;
-        return Failure{std::move(err)};
+        return diag::Failure{std::move(err)};
     }
     return Success;
 }
diff --git a/src/tint/utils/reflection.h b/src/tint/utils/reflection.h
index b4749e9..b3ec51b 100644
--- a/src/tint/utils/reflection.h
+++ b/src/tint/utils/reflection.h
@@ -33,9 +33,10 @@
 #include <type_traits>
 #include <utility>
 
+#include "src/tint/utils/containers/vector.h"
+#include "src/tint/utils/diagnostic/diagnostic.h"
 #include "src/tint/utils/macros/foreach.h"
 #include "src/tint/utils/memory/aligned_storage.h"
-#include "src/tint/utils/result/result.h"
 
 /// Forward declarations
 namespace tint {
@@ -81,18 +82,18 @@
 
 /// @returns Success if the sequential fields of @p fields have the expected offsets, and aligned
 /// sum match the class size @p class_size.
-::tint::Result<SuccessType> CheckAllFieldsReflected(VectorRef<ReflectedFieldInfo> fields,
-                                                    std::string_view class_name,
-                                                    size_t class_size,
-                                                    size_t class_align,
-                                                    bool class_is_castable,
-                                                    std::string_view reflect_file,
-                                                    uint32_t reflect_line);
+diag::Result<SuccessType> CheckAllFieldsReflected(VectorRef<ReflectedFieldInfo> fields,
+                                                  std::string_view class_name,
+                                                  size_t class_size,
+                                                  size_t class_align,
+                                                  bool class_is_castable,
+                                                  std::string_view reflect_file,
+                                                  uint32_t reflect_line);
 
 /// @returns Success if the TINT_REFLECT() reflected fields of @tparam CLASS match the declaration
 /// order, do not have any gaps, and fully account for the entire size of the class.
 template <typename CLASS>
-::tint::Result<SuccessType> CheckAllFieldsReflected() {
+diag::Result<SuccessType> CheckAllFieldsReflected() {
     static_assert(!std::has_virtual_destructor_v<CLASS> || std::is_base_of_v<CastableBase, CLASS>,
                   "TINT_ASSERT_ALL_FIELDS_REFLECTED() cannot be used on virtual classes, except "
                   "for types using the tint::Castable framework");
diff --git a/src/tint/utils/result/BUILD.bazel b/src/tint/utils/result/BUILD.bazel
index 4a0321b..c38112f 100644
--- a/src/tint/utils/result/BUILD.bazel
+++ b/src/tint/utils/result/BUILD.bazel
@@ -45,14 +45,9 @@
     "result.h",
   ],
   deps = [
-    "//src/tint/utils/containers",
-    "//src/tint/utils/diagnostic",
     "//src/tint/utils/ice",
     "//src/tint/utils/macros",
-    "//src/tint/utils/math",
-    "//src/tint/utils/memory",
     "//src/tint/utils/rtti",
-    "//src/tint/utils/text",
     "//src/utils",
   ],
   copts = COPTS,
@@ -65,15 +60,10 @@
     "result_test.cc",
   ],
   deps = [
-    "//src/tint/utils/containers",
-    "//src/tint/utils/diagnostic",
     "//src/tint/utils/ice",
     "//src/tint/utils/macros",
-    "//src/tint/utils/math",
-    "//src/tint/utils/memory",
     "//src/tint/utils/result",
     "//src/tint/utils/rtti",
-    "//src/tint/utils/text",
     "@gtest",
     "//src/utils",
   ],
diff --git a/src/tint/utils/result/BUILD.cmake b/src/tint/utils/result/BUILD.cmake
index 16ec080..120254e 100644
--- a/src/tint/utils/result/BUILD.cmake
+++ b/src/tint/utils/result/BUILD.cmake
@@ -44,14 +44,9 @@
 )
 
 tint_target_add_dependencies(tint_utils_result lib
-  tint_utils_containers
-  tint_utils_diagnostic
   tint_utils_ice
   tint_utils_macros
-  tint_utils_math
-  tint_utils_memory
   tint_utils_rtti
-  tint_utils_text
 )
 
 tint_target_add_external_dependencies(tint_utils_result lib
@@ -67,15 +62,10 @@
 )
 
 tint_target_add_dependencies(tint_utils_result_test test
-  tint_utils_containers
-  tint_utils_diagnostic
   tint_utils_ice
   tint_utils_macros
-  tint_utils_math
-  tint_utils_memory
   tint_utils_result
   tint_utils_rtti
-  tint_utils_text
 )
 
 tint_target_add_external_dependencies(tint_utils_result_test test
diff --git a/src/tint/utils/result/BUILD.gn b/src/tint/utils/result/BUILD.gn
index c3037ae..64c69e6 100644
--- a/src/tint/utils/result/BUILD.gn
+++ b/src/tint/utils/result/BUILD.gn
@@ -50,14 +50,9 @@
   ]
   deps = [
     "${dawn_root}/src/utils:utils",
-    "${tint_src_dir}/utils/containers",
-    "${tint_src_dir}/utils/diagnostic",
     "${tint_src_dir}/utils/ice",
     "${tint_src_dir}/utils/macros",
-    "${tint_src_dir}/utils/math",
-    "${tint_src_dir}/utils/memory",
     "${tint_src_dir}/utils/rtti",
-    "${tint_src_dir}/utils/text",
   ]
 }
 if (tint_build_unittests) {
@@ -66,15 +61,10 @@
     deps = [
       "${dawn_root}/src/utils:utils",
       "${tint_src_dir}:gmock_and_gtest",
-      "${tint_src_dir}/utils/containers",
-      "${tint_src_dir}/utils/diagnostic",
       "${tint_src_dir}/utils/ice",
       "${tint_src_dir}/utils/macros",
-      "${tint_src_dir}/utils/math",
-      "${tint_src_dir}/utils/memory",
       "${tint_src_dir}/utils/result",
       "${tint_src_dir}/utils/rtti",
-      "${tint_src_dir}/utils/text",
     ]
   }
 }
diff --git a/src/tint/utils/result/result.cc b/src/tint/utils/result/result.cc
index 0a8c6c8..e70c488 100644
--- a/src/tint/utils/result/result.cc
+++ b/src/tint/utils/result/result.cc
@@ -27,16 +27,14 @@
 
 #include "src/tint/utils/result/result.h"
 
+#include <string>
+
 namespace tint {
 
 Failure::Failure() = default;
 
 Failure::Failure(std::string_view err) {
-    reason.AddError(Source{}) << err;
+    reason = std::string(err);
 }
 
-Failure::Failure(diag::Diagnostic diagnostic) : reason(diag::List{std::move(diagnostic)}) {}
-
-Failure::Failure(diag::List diagnostics) : reason(std::move(diagnostics)) {}
-
 }  // namespace tint
diff --git a/src/tint/utils/result/result.h b/src/tint/utils/result/result.h
index 9a1f49a..fd802bf 100644
--- a/src/tint/utils/result/result.h
+++ b/src/tint/utils/result/result.h
@@ -28,13 +28,13 @@
 #ifndef SRC_TINT_UTILS_RESULT_RESULT_H_
 #define SRC_TINT_UTILS_RESULT_RESULT_H_
 
+#include <string>
+#include <string_view>
 #include <utility>
 #include <variant>
 
-#include "src/tint/utils/diagnostic/diagnostic.h"
 #include "src/tint/utils/ice/ice.h"
 #include "src/tint/utils/rtti/traits.h"
-#include "src/tint/utils/text/string_stream.h"
 
 namespace tint {
 
@@ -53,16 +53,7 @@
     /// @param err the single error diagnostic
     explicit Failure(std::string_view err);
 
-    /// Constructor with a single diagnostic
-    /// @param diagnostic the failure diagnostic
-    explicit Failure(diag::Diagnostic diagnostic);
-
-    /// Constructor with a list of diagnostics
-    /// @param diagnostics the failure diagnostics
-    explicit Failure(diag::List diagnostics);
-
-    /// The diagnostics explaining the failure reason
-    diag::List reason;
+    std::string reason;
 };
 
 /// Write the Failure to the given stream
diff --git a/src/tint/utils/strconv/BUILD.bazel b/src/tint/utils/strconv/BUILD.bazel
index af10e74..e6083c1 100644
--- a/src/tint/utils/strconv/BUILD.bazel
+++ b/src/tint/utils/strconv/BUILD.bazel
@@ -47,12 +47,8 @@
     "parse_num.h",
   ],
   deps = [
-    "//src/tint/utils/containers",
-    "//src/tint/utils/diagnostic",
     "//src/tint/utils/ice",
     "//src/tint/utils/macros",
-    "//src/tint/utils/math",
-    "//src/tint/utils/memory",
     "//src/tint/utils/result",
     "//src/tint/utils/rtti",
     "//src/tint/utils/text",
diff --git a/src/tint/utils/strconv/BUILD.cmake b/src/tint/utils/strconv/BUILD.cmake
index 51d7bde..b51c665 100644
--- a/src/tint/utils/strconv/BUILD.cmake
+++ b/src/tint/utils/strconv/BUILD.cmake
@@ -46,12 +46,8 @@
 )
 
 tint_target_add_dependencies(tint_utils_strconv lib
-  tint_utils_containers
-  tint_utils_diagnostic
   tint_utils_ice
   tint_utils_macros
-  tint_utils_math
-  tint_utils_memory
   tint_utils_result
   tint_utils_rtti
   tint_utils_text
diff --git a/src/tint/utils/strconv/BUILD.gn b/src/tint/utils/strconv/BUILD.gn
index ef5e5f3..f8cb812 100644
--- a/src/tint/utils/strconv/BUILD.gn
+++ b/src/tint/utils/strconv/BUILD.gn
@@ -53,12 +53,8 @@
   deps = [
     "${dawn_root}/src/utils:utils",
     "${tint_src_dir}:abseil",
-    "${tint_src_dir}/utils/containers",
-    "${tint_src_dir}/utils/diagnostic",
     "${tint_src_dir}/utils/ice",
     "${tint_src_dir}/utils/macros",
-    "${tint_src_dir}/utils/math",
-    "${tint_src_dir}/utils/memory",
     "${tint_src_dir}/utils/result",
     "${tint_src_dir}/utils/rtti",
     "${tint_src_dir}/utils/text",
diff --git a/src/tint/utils/strconv/parse_num.h b/src/tint/utils/strconv/parse_num.h
index 704bd47..e3a469d 100644
--- a/src/tint/utils/strconv/parse_num.h
+++ b/src/tint/utils/strconv/parse_num.h
@@ -28,6 +28,8 @@
 #ifndef SRC_TINT_UTILS_STRCONV_PARSE_NUM_H_
 #define SRC_TINT_UTILS_STRCONV_PARSE_NUM_H_
 
+#include <cstdint>
+
 #include "src/tint/utils/macros/compiler.h"
 #include "src/tint/utils/result/result.h"