[tint][ir] Stylize more validator diagnostics

Change-Id: I9c9712c6aaad4d90769407edb45e6529849e74e3
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/186624
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/lang/core/ir/disassembly.cc b/src/tint/lang/core/ir/disassembly.cc
index a07033f..df0cc4e 100644
--- a/src/tint/lang/core/ir/disassembly.cc
+++ b/src/tint/lang/core/ir/disassembly.cc
@@ -30,6 +30,7 @@
 #include <string_view>
 
 #include "src//tint/lang/core/ir/unary.h"
+#include "src/tint/lang/core/binary_op.h"
 #include "src/tint/lang/core/constant/composite.h"
 #include "src/tint/lang/core/constant/scalar.h"
 #include "src/tint/lang/core/constant/splat.h"
@@ -796,64 +797,7 @@
 void Disassembly::EmitBinary(const Binary* b) {
     SourceMarker sm(this);
     EmitValueWithType(b);
-    out_ << " = ";
-    switch (b->Op()) {
-        case BinaryOp::kAdd:
-            out_ << StyleInstruction("add");
-            break;
-        case BinaryOp::kSubtract:
-            out_ << StyleInstruction("sub");
-            break;
-        case BinaryOp::kMultiply:
-            out_ << StyleInstruction("mul");
-            break;
-        case BinaryOp::kDivide:
-            out_ << StyleInstruction("div");
-            break;
-        case BinaryOp::kModulo:
-            out_ << StyleInstruction("mod");
-            break;
-        case BinaryOp::kAnd:
-            out_ << StyleInstruction("and");
-            break;
-        case BinaryOp::kOr:
-            out_ << StyleInstruction("or");
-            break;
-        case BinaryOp::kXor:
-            out_ << StyleInstruction("xor");
-            break;
-        case BinaryOp::kEqual:
-            out_ << StyleInstruction("eq");
-            break;
-        case BinaryOp::kNotEqual:
-            out_ << StyleInstruction("neq");
-            break;
-        case BinaryOp::kLessThan:
-            out_ << StyleInstruction("lt");
-            break;
-        case BinaryOp::kGreaterThan:
-            out_ << StyleInstruction("gt");
-            break;
-        case BinaryOp::kLessThanEqual:
-            out_ << StyleInstruction("lte");
-            break;
-        case BinaryOp::kGreaterThanEqual:
-            out_ << StyleInstruction("gte");
-            break;
-        case BinaryOp::kShiftLeft:
-            out_ << StyleInstruction("shl");
-            break;
-        case BinaryOp::kShiftRight:
-            out_ << StyleInstruction("shr");
-            break;
-        case BinaryOp::kLogicalAnd:
-            out_ << StyleInstruction("logical-and");
-            break;
-        case BinaryOp::kLogicalOr:
-            out_ << StyleInstruction("logical-or");
-            break;
-    }
-    out_ << " ";
+    out_ << " = " << NameOf(b->Op()) << " ";
     EmitOperandList(b);
 
     sm.Store(b);
@@ -862,25 +806,7 @@
 void Disassembly::EmitUnary(const Unary* u) {
     SourceMarker sm(this);
     EmitValueWithType(u);
-    out_ << " = ";
-    switch (u->Op()) {
-        case UnaryOp::kComplement:
-            out_ << StyleInstruction("complement");
-            break;
-        case UnaryOp::kNegation:
-            out_ << StyleInstruction("negation");
-            break;
-        case UnaryOp::kAddressOf:
-            out_ << StyleInstruction("ref-to-ptr");
-            break;
-        case UnaryOp::kIndirection:
-            out_ << StyleInstruction("ptr-to-ref");
-            break;
-        case UnaryOp::kNot:
-            out_ << StyleInstruction("not");
-            break;
-    }
-    out_ << " ";
+    out_ << " = " << NameOf(u->Op()) << " ";
     EmitOperandList(u);
 
     sm.Store(u);
@@ -984,4 +910,62 @@
     return StyledText{} << StyleInstruction(name);
 }
 
+StyledText Disassembly::NameOf(BinaryOp op) {
+    switch (op) {
+        case BinaryOp::kAdd:
+            return StyledText{} << StyleInstruction("add");
+        case BinaryOp::kSubtract:
+            return StyledText{} << StyleInstruction("sub");
+        case BinaryOp::kMultiply:
+            return StyledText{} << StyleInstruction("mul");
+        case BinaryOp::kDivide:
+            return StyledText{} << StyleInstruction("div");
+        case BinaryOp::kModulo:
+            return StyledText{} << StyleInstruction("mod");
+        case BinaryOp::kAnd:
+            return StyledText{} << StyleInstruction("and");
+        case BinaryOp::kOr:
+            return StyledText{} << StyleInstruction("or");
+        case BinaryOp::kXor:
+            return StyledText{} << StyleInstruction("xor");
+        case BinaryOp::kEqual:
+            return StyledText{} << StyleInstruction("eq");
+        case BinaryOp::kNotEqual:
+            return StyledText{} << StyleInstruction("neq");
+        case BinaryOp::kLessThan:
+            return StyledText{} << StyleInstruction("lt");
+        case BinaryOp::kGreaterThan:
+            return StyledText{} << StyleInstruction("gt");
+        case BinaryOp::kLessThanEqual:
+            return StyledText{} << StyleInstruction("lte");
+        case BinaryOp::kGreaterThanEqual:
+            return StyledText{} << StyleInstruction("gte");
+        case BinaryOp::kShiftLeft:
+            return StyledText{} << StyleInstruction("shl");
+        case BinaryOp::kShiftRight:
+            return StyledText{} << StyleInstruction("shr");
+        case BinaryOp::kLogicalAnd:
+            return StyledText{} << StyleInstruction("logical-and");
+        case BinaryOp::kLogicalOr:
+            return StyledText{} << StyleInstruction("logical-or");
+    }
+    TINT_UNREACHABLE() << op;
+}
+
+StyledText Disassembly::NameOf(UnaryOp op) {
+    switch (op) {
+        case UnaryOp::kComplement:
+            return StyledText{} << StyleInstruction("complement");
+        case UnaryOp::kNegation:
+            return StyledText{} << StyleInstruction("negation");
+        case UnaryOp::kAddressOf:
+            return StyledText{} << StyleInstruction("ref-to-ptr");
+        case UnaryOp::kIndirection:
+            return StyledText{} << StyleInstruction("ptr-to-ref");
+        case UnaryOp::kNot:
+            return StyledText{} << StyleInstruction("not");
+    }
+    TINT_UNREACHABLE() << op;
+}
+
 }  // namespace tint::core::ir
diff --git a/src/tint/lang/core/ir/disassembly.h b/src/tint/lang/core/ir/disassembly.h
index 677b386..70c48b4 100644
--- a/src/tint/lang/core/ir/disassembly.h
+++ b/src/tint/lang/core/ir/disassembly.h
@@ -32,6 +32,7 @@
 #include <string>
 #include <string_view>
 
+#include "src/tint/lang/core/binary_op.h"
 #include "src/tint/lang/core/ir/binary.h"
 #include "src/tint/lang/core/ir/block.h"
 #include "src/tint/lang/core/ir/block_param.h"
@@ -108,6 +109,12 @@
     /// @returns the disassembled name for the Switch @p inst
     StyledText NameOf(const Switch* inst);
 
+    /// @returns the disassembled name for the BinaryOp @p op
+    StyledText NameOf(BinaryOp op);
+
+    /// @returns the disassembled name for the UnaryOp @p op
+    StyledText NameOf(UnaryOp op);
+
     /// @param inst the instruction to retrieve
     /// @returns the source for the instruction
     Source InstructionSource(const Instruction* inst) const {
diff --git a/src/tint/lang/core/ir/validator.cc b/src/tint/lang/core/ir/validator.cc
index e945cc6..892aa4a 100644
--- a/src/tint/lang/core/ir/validator.cc
+++ b/src/tint/lang/core/ir/validator.cc
@@ -80,7 +80,6 @@
 #include "src/tint/utils/containers/transform.h"
 #include "src/tint/utils/ice/ice.h"
 #include "src/tint/utils/macros/defer.h"
-#include "src/tint/utils/macros/scoped_assignment.h"
 #include "src/tint/utils/rtti/switch.h"
 #include "src/tint/utils/text/styled_text.h"
 #include "src/tint/utils/text/text_style.h"
@@ -789,7 +788,10 @@
 void Validator::CheckVar(const Var* var) {
     if (var->Result(0) && var->Initializer()) {
         if (var->Initializer()->Type() != var->Result(0)->Type()->UnwrapPtrOrRef()) {
-            AddError(var) << "initializer has incorrect type";
+            AddError(var) << "initializer type "
+                          << style::Type(var->Initializer()->Type()->FriendlyName())
+                          << " does not match store type "
+                          << style::Type(var->Result(0)->Type()->UnwrapPtrOrRef()->FriendlyName());
         }
     }
 }
@@ -799,7 +801,9 @@
 
     if (let->Result(0) && let->Value()) {
         if (let->Result(0)->Type() != let->Value()->Type()) {
-            AddError(let) << "result type does not match value type";
+            AddError(let) << "result type " << style::Type(let->Result(0)->Type()->FriendlyName())
+                          << " does not match value type "
+                          << style::Type(let->Value()->Type()->FriendlyName());
         }
     }
 }
@@ -859,8 +863,9 @@
     for (size_t i = 0; i < args.Length(); i++) {
         if (args[i]->Type() != params[i]->Type()) {
             AddError(call, UserCall::kArgsOperandOffset + i)
-                << "function parameter " << i << " is of type " << params[i]->Type()->FriendlyName()
-                << ", but argument is of type " << args[i]->Type()->FriendlyName();
+                << "function parameter " << i << " is of type "
+                << style::Type(params[i]->Type()->FriendlyName()) << ", but argument is of type "
+                << style::Type(args[i]->Type()->FriendlyName());
         }
     }
 }
@@ -880,13 +885,15 @@
     auto desc_of = [&](Kind kind, const core::type::Type* type) {
         switch (kind) {
             case kPtr:
-                return StyledText{} << "ptr<" << obj_view->AddressSpace() << ", "
-                                    << type->FriendlyName() << ", " << obj_view->Access() << ">";
+                return StyledText{}
+                       << style::Type("ptr<", obj_view->AddressSpace(), ", ", type->FriendlyName(),
+                                      ", ", obj_view->Access(), ">");
             case kRef:
-                return StyledText{} << "ref<" << obj_view->AddressSpace() << ", "
-                                    << type->FriendlyName() << ", " << obj_view->Access() << ">";
+                return StyledText{}
+                       << style::Type("ref<", obj_view->AddressSpace(), ", ", type->FriendlyName(),
+                                      ", ", obj_view->Access(), ">");
             default:
-                return StyledText{} << type->FriendlyName();
+                return StyledText{} << style::Type(type->FriendlyName());
         }
     };
 
@@ -957,7 +964,7 @@
 
     if (TINT_UNLIKELY(!ok)) {
         AddError(a) << "result of access chain is type " << desc_of(in_kind, ty)
-                    << " but instruction type is " << want->FriendlyName();
+                    << " but instruction type is " << style::Type(want->FriendlyName());
     }
 }
 
@@ -966,11 +973,7 @@
     if (b->LHS() && b->RHS()) {
         auto symbols = SymbolTable::Wrap(mod_.symbols);
         auto type_mgr = type::Manager::Wrap(mod_.Types());
-        intrinsic::Context context{
-            b->TableData(),
-            type_mgr,
-            symbols,
-        };
+        intrinsic::Context context{b->TableData(), type_mgr, symbols};
 
         auto overload =
             core::intrinsic::LookupBinary(context, b->Op(), b->LHS()->Type(), b->RHS()->Type(),
@@ -982,11 +985,10 @@
 
         if (auto* result = b->Result(0)) {
             if (overload->return_type != result->Type()) {
-                StringStream err;
-                err << "binary instruction result type (" << result->Type()->FriendlyName()
-                    << ") does not match overload result type ("
-                    << overload->return_type->FriendlyName() << ")";
-                AddError(b) << err.str();
+                AddError(b) << "result value type " << style::Type(result->Type()->FriendlyName())
+                            << " does not match "
+                            << style::Instruction(Disassembly().NameOf(b->Op())) << " result type "
+                            << style::Type(overload->return_type->FriendlyName());
             }
         }
     }
@@ -997,11 +999,7 @@
     if (u->Val()) {
         auto symbols = SymbolTable::Wrap(mod_.symbols);
         auto type_mgr = type::Manager::Wrap(mod_.Types());
-        intrinsic::Context context{
-            u->TableData(),
-            type_mgr,
-            symbols,
-        };
+        intrinsic::Context context{u->TableData(), type_mgr, symbols};
 
         auto overload = core::intrinsic::LookupUnary(context, u->Op(), u->Val()->Type(),
                                                      core::EvaluationStage::kRuntime);
@@ -1012,11 +1010,10 @@
 
         if (auto* result = u->Result(0)) {
             if (overload->return_type != result->Type()) {
-                StringStream err;
-                err << "unary instruction result type (" << result->Type()->FriendlyName()
-                    << ") does not match overload result type ("
-                    << overload->return_type->FriendlyName() << ")";
-                AddError(u) << err.str();
+                AddError(u) << "result value type " << style::Type(result->Type()->FriendlyName())
+                            << " does not match "
+                            << style::Instruction(Disassembly().NameOf(u->Op())) << " result type "
+                            << style::Type(overload->return_type->FriendlyName());
             }
         }
     }
@@ -1026,7 +1023,8 @@
     CheckOperandNotNull(if_, if_->Condition(), If::kConditionOperandOffset);
 
     if (if_->Condition() && !if_->Condition()->Type()->Is<core::type::Bool>()) {
-        AddError(if_, If::kConditionOperandOffset) << "condition must be a `bool` type";
+        AddError(if_, If::kConditionOperandOffset)
+            << "condition type must be " << style::Type("bool");
     }
 
     tasks_.Push([this] { control_stack_.Pop(); });
@@ -1114,9 +1112,9 @@
 
     for (size_t i = 0; i < results.Length(); ++i) {
         if (results[i] && args[i] && results[i]->Type() != args[i]->Type()) {
-            AddError(e, i) << "argument type (" << results[i]->Type()->FriendlyName()
-                           << ") does not match control instruction type ("
-                           << args[i]->Type()->FriendlyName() << ")";
+            AddError(e, i) << "argument type " << style::Type(results[i]->Type()->FriendlyName())
+                           << " does not match control instruction type "
+                           << style::Type(args[i]->Type()->FriendlyName());
             AddNote(e->ControlInstruction()) << "control instruction";
         }
     }
@@ -1150,7 +1148,10 @@
         if (!ret->Value()) {
             AddError(ret) << "expected return value";
         } else if (ret->Value()->Type() != func->ReturnType()) {
-            AddError(ret) << "return value type does not match function return type";
+            AddError(ret) << "return value type "
+                          << style::Type(ret->Value()->Type()->FriendlyName())
+                          << " does not match function return type "
+                          << style::Type(func->ReturnType()->FriendlyName());
         }
     }
 }
@@ -1214,7 +1215,10 @@
             return;
         }
         if (l->Result(0)->Type() != mv->StoreType()) {
-            AddError(l, Load::kFromOperandOffset) << "result type does not match source store type";
+            AddError(l, Load::kFromOperandOffset)
+                << "result type " << style::Type(l->Result(0)->Type()->FriendlyName())
+                << " does not match source store type "
+                << style::Type(mv->StoreType()->FriendlyName());
         }
     }
 }
@@ -1230,8 +1234,12 @@
                     << "store target operand is not a memory view";
                 return;
             }
-            if (from->Type() != mv->StoreType()) {
-                AddError(s, Store::kFromOperandOffset) << "value type does not match store type";
+            auto* value_type = from->Type();
+            auto* store_type = mv->StoreType();
+            if (value_type != store_type) {
+                AddError(s, Store::kFromOperandOffset)
+                    << "value type " << style::Type(value_type->FriendlyName())
+                    << " does not match store type " << style::Type(store_type->FriendlyName());
             }
         }
     }
@@ -1245,7 +1253,9 @@
     if (auto* res = l->Result(0)) {
         if (auto* el_ty = GetVectorPtrElementType(l, LoadVectorElement::kFromOperandOffset)) {
             if (res->Type() != el_ty) {
-                AddResultError(l, 0) << "result type does not match vector pointer element type";
+                AddResultError(l, 0) << "result type " << style::Type(res->Type()->FriendlyName())
+                                     << " does not match vector pointer element type "
+                                     << style::Type(el_ty->FriendlyName());
             }
         }
     }
@@ -1260,7 +1270,9 @@
         if (auto* el_ty = GetVectorPtrElementType(s, StoreVectorElement::kToOperandOffset)) {
             if (value->Type() != el_ty) {
                 AddError(s, StoreVectorElement::kValueOperandOffset)
-                    << "value type does not match vector pointer element type";
+                    << "value type " << style::Type(value->Type()->FriendlyName())
+                    << " does not match vector pointer element type "
+                    << style::Type(el_ty->FriendlyName());
             }
         }
     }
@@ -1285,7 +1297,8 @@
         }
     }
 
-    AddError(inst, idx) << "operand must be a pointer to vector, got " << type->FriendlyName();
+    AddError(inst, idx) << "operand must be a pointer to vector, got "
+                        << style::Type(type->FriendlyName());
     return nullptr;
 }
 
diff --git a/src/tint/lang/core/ir/validator_test.cc b/src/tint/lang/core/ir/validator_test.cc
index 864e24d..2619338 100644
--- a/src/tint/lang/core/ir/validator_test.cc
+++ b/src/tint/lang/core/ir/validator_test.cc
@@ -394,8 +394,9 @@
 
     auto res = ir::Validate(mod);
     ASSERT_NE(res, Success);
-    EXPECT_EQ(res.Failure().reason.Str(),
-              R"(:8:28 error: call: function parameter 1 is of type i32, but argument is of type f32
+    EXPECT_EQ(
+        res.Failure().reason.Str(),
+        R"(:8:28 error: call: function parameter 1 is of type 'i32', but argument is of type 'f32'
     %6:void = call %g, 1i, 2.0f, 3i
                            ^^^^
 
@@ -631,7 +632,7 @@
     auto res = ir::Validate(mod);
     ASSERT_NE(res, Success);
     EXPECT_EQ(res.Failure().reason.Str(),
-              R"(:3:29 error: access: index out of bounds for type vec2<f32>
+              R"(:3:29 error: access: index out of bounds for type 'vec2<f32>'
     %3:f32 = access %2, 1u, 3u
                             ^^
 
@@ -667,7 +668,7 @@
     ASSERT_NE(res, Success);
     EXPECT_EQ(
         res.Failure().reason.Str(),
-        R"(:3:55 error: access: index out of bounds for type ptr<private, array<f32, 2>, read_write>
+        R"(:3:55 error: access: index out of bounds for type 'ptr<private, array<f32, 2>, read_write>'
     %3:ptr<private, f32, read_write> = access %2, 1u, 3u
                                                       ^^
 
@@ -701,7 +702,7 @@
 
     auto res = ir::Validate(mod);
     ASSERT_NE(res, Success);
-    EXPECT_EQ(res.Failure().reason.Str(), R"(:3:25 error: access: type f32 cannot be indexed
+    EXPECT_EQ(res.Failure().reason.Str(), R"(:3:25 error: access: type 'f32' cannot be indexed
     %3:f32 = access %2, 1u
                         ^^
 
@@ -732,7 +733,7 @@
     auto res = ir::Validate(mod);
     ASSERT_NE(res, Success);
     EXPECT_EQ(res.Failure().reason.Str(),
-              R"(:3:51 error: access: type ptr<private, f32, read_write> cannot be indexed
+              R"(:3:51 error: access: type 'ptr<private, f32, read_write>' cannot be indexed
     %3:ptr<private, f32, read_write> = access %2, 1u
                                                   ^^
 
@@ -769,7 +770,7 @@
     auto res = ir::Validate(mod);
     ASSERT_NE(res, Success);
     EXPECT_EQ(res.Failure().reason.Str(),
-              R"(:8:25 error: access: type MyStruct cannot be dynamically indexed
+              R"(:8:25 error: access: type 'MyStruct' cannot be dynamically indexed
     %4:i32 = access %2, %3
                         ^^
 
@@ -812,7 +813,7 @@
     ASSERT_NE(res, Success);
     EXPECT_EQ(
         res.Failure().reason.Str(),
-        R"(:8:25 error: access: type ptr<private, MyStruct, read_write> cannot be dynamically indexed
+        R"(:8:25 error: access: type 'ptr<private, MyStruct, read_write>' cannot be dynamically indexed
     %4:i32 = access %2, %3
                         ^^
 
@@ -847,8 +848,9 @@
 
     auto res = ir::Validate(mod);
     ASSERT_NE(res, Success);
-    EXPECT_EQ(res.Failure().reason.Str(),
-              R"(:3:14 error: access: result of access chain is type f32 but instruction type is i32
+    EXPECT_EQ(
+        res.Failure().reason.Str(),
+        R"(:3:14 error: access: result of access chain is type 'f32' but instruction type is 'i32'
     %3:i32 = access %2, 1u, 1u
              ^^^^^^
 
@@ -880,7 +882,7 @@
     ASSERT_NE(res, Success);
     EXPECT_EQ(
         res.Failure().reason.Str(),
-        R"(:3:40 error: access: result of access chain is type ptr<private, f32, read_write> but instruction type is ptr<private, i32, read_write>
+        R"(:3:40 error: access: result of access chain is type 'ptr<private, f32, read_write>' but instruction type is 'ptr<private, i32, read_write>'
     %3:ptr<private, i32, read_write> = access %2, 1u, 1u
                                        ^^^^^^
 
@@ -912,7 +914,7 @@
     ASSERT_NE(res, Success);
     EXPECT_EQ(
         res.Failure().reason.Str(),
-        R"(:3:14 error: access: result of access chain is type ptr<private, f32, read_write> but instruction type is f32
+        R"(:3:14 error: access: result of access chain is type 'ptr<private, f32, read_write>' but instruction type is 'f32'
     %3:f32 = access %2, 1u, 1u
              ^^^^^^
 
@@ -1034,7 +1036,7 @@
     ASSERT_NE(res, Success);
     EXPECT_EQ(
         res.Failure().reason.Str(),
-        R"(:3:34 error: access: result of access chain is type ptr<storage, f32, read> but instruction type is ptr<uniform, f32, read>
+        R"(:3:34 error: access: result of access chain is type 'ptr<storage, f32, read>' but instruction type is 'ptr<uniform, f32, read>'
     %3:ptr<uniform, f32, read> = access %2, 1u
                                  ^^^^^^
 
@@ -1066,7 +1068,7 @@
     ASSERT_NE(res, Success);
     EXPECT_EQ(
         res.Failure().reason.Str(),
-        R"(:3:40 error: access: result of access chain is type ptr<storage, f32, read> but instruction type is ptr<storage, f32, read_write>
+        R"(:3:40 error: access: result of access chain is type 'ptr<storage, f32, read>' but instruction type is 'ptr<storage, f32, read_write>'
     %3:ptr<storage, f32, read_write> = access %2, 1u
                                        ^^^^^^
 
@@ -1197,7 +1199,7 @@
 
     auto res = ir::Validate(mod);
     ASSERT_NE(res, Success);
-    EXPECT_EQ(res.Failure().reason.Str(), R"(:3:8 error: if: condition must be a `bool` type
+    EXPECT_EQ(res.Failure().reason.Str(), R"(:3:8 error: if: condition type must be 'bool'
     if 1i [t: $B2, f: $B3] {  # if_1
        ^^
 
@@ -1400,7 +1402,8 @@
 
     auto res = ir::Validate(mod);
     ASSERT_NE(res, Success);
-    EXPECT_EQ(res.Failure().reason.Str(), R"(:3:41 error: var: initializer has incorrect type
+    EXPECT_EQ(res.Failure().reason.Str(),
+              R"(:3:41 error: var: initializer type 'i32' does not match store type 'f32'
     %2:ptr<function, f32, read_write> = var, 1i
                                         ^^^
 
@@ -1488,7 +1491,8 @@
 
     auto res = ir::Validate(mod);
     ASSERT_NE(res, Success);
-    EXPECT_EQ(res.Failure().reason.Str(), R"(:3:14 error: let: result type does not match value type
+    EXPECT_EQ(res.Failure().reason.Str(),
+              R"(:3:14 error: let: result type 'f32' does not match value type 'i32'
     %2:f32 = let 1i
              ^^^
 
@@ -1813,7 +1817,7 @@
     ASSERT_NE(res, Success);
     EXPECT_EQ(
         res.Failure().reason.Str(),
-        R"(:3:5 error: unary: unary instruction result type (f32) does not match overload result type (i32)
+        R"(:3:5 error: unary: result value type 'f32' does not match complement result type 'i32'
     %2:f32 = complement 2i
     ^^^^^^^^^^^^^^^^^^^^^^
 
@@ -1998,7 +2002,7 @@
     ASSERT_NE(res, Success);
     EXPECT_EQ(
         res.Failure().reason.Str(),
-        R"(:5:21 error: exit_if: argument type (f32) does not match control instruction type (i32)
+        R"(:5:21 error: exit_if: argument type 'f32' does not match control instruction type 'i32'
         exit_if 1i, 2i  # if_1
                     ^^
 
@@ -2392,7 +2396,7 @@
     ASSERT_NE(res, Success);
     EXPECT_EQ(
         res.Failure().reason.Str(),
-        R"(:5:25 error: exit_switch: argument type (f32) does not match control instruction type (i32)
+        R"(:5:25 error: exit_switch: argument type 'f32' does not match control instruction type 'i32'
         exit_switch 1i, 2i  # switch_1
                         ^^
 
@@ -2780,7 +2784,7 @@
     ASSERT_NE(res, Success);
     EXPECT_EQ(
         res.Failure().reason.Str(),
-        R"(:5:23 error: exit_loop: argument type (f32) does not match control instruction type (i32)
+        R"(:5:23 error: exit_loop: argument type 'f32' does not match control instruction type 'i32'
         exit_loop 1i, 2i  # loop_1
                       ^^
 
@@ -3300,8 +3304,9 @@
 
     auto res = ir::Validate(mod);
     ASSERT_NE(res, Success);
-    EXPECT_EQ(res.Failure().reason.Str(),
-              R"(:3:5 error: return: return value type does not match function return type
+    EXPECT_EQ(
+        res.Failure().reason.Str(),
+        R"(:3:5 error: return: return value type 'f32' does not match function return type 'i32'
     ret 42.0f
     ^^^^^^^^^
 
@@ -3392,7 +3397,7 @@
     auto res = ir::Validate(mod);
     ASSERT_NE(res, Success);
     EXPECT_EQ(res.Failure().reason.Str(),
-              R"(:4:19 error: load: result type does not match source store type
+              R"(:4:19 error: load: result type 'f32' does not match source store type 'i32'
     %3:f32 = load %2
                   ^^
 
@@ -3512,7 +3517,7 @@
     auto res = ir::Validate(mod);
     ASSERT_NE(res, Success);
     EXPECT_EQ(res.Failure().reason.Str(),
-              R"(:4:15 error: store: value type does not match store type
+              R"(:4:15 error: store: value type 'u32' does not match store type 'i32'
     store %2, 42u
               ^^^
 
@@ -3672,7 +3677,7 @@
   $B1: {
   ^^^
 
-:4:37 error: store_vector_element: value type does not match vector pointer element type
+:4:37 error: store_vector_element: value type 'i32' does not match vector pointer element type 'f32'
     store_vector_element %2, undef, 2i
                                     ^^