Add TINT_UNREACHABLE() and TINT_ICE() helper macros

Appends an error message with the tint compiler source location to the
provided diagnositic list, and then calls the global error handler if
one is set.
Tests and the sample app now register an error handler to print the
diagnostic list to stderr and abort when NDEBUG is not defined.

All uses of assert(false) have been fixed up to use these macros.

Change-Id: I2f63e51ed86ac23883301d280070bd1a357c6cb2
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/41620
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/intrinsic_table_test.cc b/src/intrinsic_table_test.cc
index fc75e0c..0b7c1d5 100644
--- a/src/intrinsic_table_test.cc
+++ b/src/intrinsic_table_test.cc
@@ -38,44 +38,44 @@
 };
 
 TEST_F(IntrinsicTableTest, MatchF32) {
-  auto result = table->Lookup(*this, IntrinsicType::kCos, {ty.f32()});
+  auto result = table->Lookup(*this, IntrinsicType::kCos, {ty.f32()}, Source{});
   ASSERT_NE(result.intrinsic, nullptr);
-  ASSERT_EQ(result.error, "");
+  ASSERT_EQ(result.diagnostics.str(), "");
   EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kCos);
   EXPECT_THAT(result.intrinsic->ReturnType(), ty.f32());
   EXPECT_THAT(result.intrinsic->Parameters(), ElementsAre(Parameter{ty.f32()}));
 }
 
 TEST_F(IntrinsicTableTest, MismatchF32) {
-  auto result = table->Lookup(*this, IntrinsicType::kCos, {ty.i32()});
+  auto result = table->Lookup(*this, IntrinsicType::kCos, {ty.i32()}, Source{});
   ASSERT_EQ(result.intrinsic, nullptr);
-  ASSERT_THAT(result.error, HasSubstr("no matching call"));
+  ASSERT_THAT(result.diagnostics.str(), HasSubstr("no matching call"));
 }
 
 TEST_F(IntrinsicTableTest, MatchU32) {
-  auto result =
-      table->Lookup(*this, IntrinsicType::kUnpack2x16Float, {ty.u32()});
+  auto result = table->Lookup(*this, IntrinsicType::kUnpack2x16Float,
+                              {ty.u32()}, Source{});
   ASSERT_NE(result.intrinsic, nullptr);
-  ASSERT_EQ(result.error, "");
+  ASSERT_EQ(result.diagnostics.str(), "");
   EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kUnpack2x16Float);
   EXPECT_THAT(result.intrinsic->ReturnType(), ty.vec2<f32>());
   EXPECT_THAT(result.intrinsic->Parameters(), ElementsAre(Parameter{ty.u32()}));
 }
 
 TEST_F(IntrinsicTableTest, MismatchU32) {
-  auto result =
-      table->Lookup(*this, IntrinsicType::kUnpack2x16Float, {ty.f32()});
+  auto result = table->Lookup(*this, IntrinsicType::kUnpack2x16Float,
+                              {ty.f32()}, Source{});
   ASSERT_EQ(result.intrinsic, nullptr);
-  ASSERT_THAT(result.error, HasSubstr("no matching call"));
+  ASSERT_THAT(result.diagnostics.str(), HasSubstr("no matching call"));
 }
 
 TEST_F(IntrinsicTableTest, MatchI32) {
   auto* tex =
       create<type::SampledTexture>(type::TextureDimension::k1d, ty.f32());
-  auto result =
-      table->Lookup(*this, IntrinsicType::kTextureLoad, {tex, ty.i32()});
+  auto result = table->Lookup(*this, IntrinsicType::kTextureLoad,
+                              {tex, ty.i32()}, Source{});
   ASSERT_NE(result.intrinsic, nullptr);
-  ASSERT_EQ(result.error, "");
+  ASSERT_EQ(result.diagnostics.str(), "");
   EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kTextureLoad);
   EXPECT_THAT(result.intrinsic->ReturnType(), ty.vec4<f32>());
   EXPECT_THAT(result.intrinsic->Parameters(),
@@ -86,41 +86,44 @@
 TEST_F(IntrinsicTableTest, MismatchI32) {
   auto* tex =
       create<type::SampledTexture>(type::TextureDimension::k1d, ty.f32());
-  auto result =
-      table->Lookup(*this, IntrinsicType::kTextureLoad, {tex, ty.f32()});
+  auto result = table->Lookup(*this, IntrinsicType::kTextureLoad,
+                              {tex, ty.f32()}, Source{});
   ASSERT_EQ(result.intrinsic, nullptr);
-  ASSERT_THAT(result.error, HasSubstr("no matching call"));
+  ASSERT_THAT(result.diagnostics.str(), HasSubstr("no matching call"));
 }
 
 TEST_F(IntrinsicTableTest, MatchIU32AsI32) {
-  auto result = table->Lookup(*this, IntrinsicType::kCountOneBits, {ty.i32()});
+  auto result =
+      table->Lookup(*this, IntrinsicType::kCountOneBits, {ty.i32()}, Source{});
   ASSERT_NE(result.intrinsic, nullptr);
-  ASSERT_EQ(result.error, "");
+  ASSERT_EQ(result.diagnostics.str(), "");
   EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kCountOneBits);
   EXPECT_THAT(result.intrinsic->ReturnType(), ty.i32());
   EXPECT_THAT(result.intrinsic->Parameters(), ElementsAre(Parameter{ty.i32()}));
 }
 
 TEST_F(IntrinsicTableTest, MatchIU32AsU32) {
-  auto result = table->Lookup(*this, IntrinsicType::kCountOneBits, {ty.u32()});
+  auto result =
+      table->Lookup(*this, IntrinsicType::kCountOneBits, {ty.u32()}, Source{});
   ASSERT_NE(result.intrinsic, nullptr);
-  ASSERT_EQ(result.error, "");
+  ASSERT_EQ(result.diagnostics.str(), "");
   EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kCountOneBits);
   EXPECT_THAT(result.intrinsic->ReturnType(), ty.u32());
   EXPECT_THAT(result.intrinsic->Parameters(), ElementsAre(Parameter{ty.u32()}));
 }
 
 TEST_F(IntrinsicTableTest, MismatchIU32) {
-  auto result = table->Lookup(*this, IntrinsicType::kCountOneBits, {ty.f32()});
+  auto result =
+      table->Lookup(*this, IntrinsicType::kCountOneBits, {ty.f32()}, Source{});
   ASSERT_EQ(result.intrinsic, nullptr);
-  ASSERT_THAT(result.error, HasSubstr("no matching call"));
+  ASSERT_THAT(result.diagnostics.str(), HasSubstr("no matching call"));
 }
 
 TEST_F(IntrinsicTableTest, MatchFIU32AsI32) {
   auto result = table->Lookup(*this, IntrinsicType::kClamp,
-                              {ty.i32(), ty.i32(), ty.i32()});
+                              {ty.i32(), ty.i32(), ty.i32()}, Source{});
   ASSERT_NE(result.intrinsic, nullptr);
-  ASSERT_EQ(result.error, "");
+  ASSERT_EQ(result.diagnostics.str(), "");
   EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kClamp);
   EXPECT_THAT(result.intrinsic->ReturnType(), ty.i32());
   EXPECT_THAT(result.intrinsic->Parameters(),
@@ -130,9 +133,9 @@
 
 TEST_F(IntrinsicTableTest, MatchFIU32AsU32) {
   auto result = table->Lookup(*this, IntrinsicType::kClamp,
-                              {ty.u32(), ty.u32(), ty.u32()});
+                              {ty.u32(), ty.u32(), ty.u32()}, Source{});
   ASSERT_NE(result.intrinsic, nullptr);
-  ASSERT_EQ(result.error, "");
+  ASSERT_EQ(result.diagnostics.str(), "");
   EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kClamp);
   EXPECT_THAT(result.intrinsic->ReturnType(), ty.u32());
   EXPECT_THAT(result.intrinsic->Parameters(),
@@ -142,9 +145,9 @@
 
 TEST_F(IntrinsicTableTest, MatchFIU32AsF32) {
   auto result = table->Lookup(*this, IntrinsicType::kClamp,
-                              {ty.f32(), ty.f32(), ty.f32()});
+                              {ty.f32(), ty.f32(), ty.f32()}, Source{});
   ASSERT_NE(result.intrinsic, nullptr);
-  ASSERT_EQ(result.error, "");
+  ASSERT_EQ(result.diagnostics.str(), "");
   EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kClamp);
   EXPECT_THAT(result.intrinsic->ReturnType(), ty.f32());
   EXPECT_THAT(result.intrinsic->Parameters(),
@@ -154,16 +157,16 @@
 
 TEST_F(IntrinsicTableTest, MismatchFIU32) {
   auto result = table->Lookup(*this, IntrinsicType::kClamp,
-                              {ty.bool_(), ty.bool_(), ty.bool_()});
+                              {ty.bool_(), ty.bool_(), ty.bool_()}, Source{});
   ASSERT_EQ(result.intrinsic, nullptr);
-  ASSERT_THAT(result.error, HasSubstr("no matching call"));
+  ASSERT_THAT(result.diagnostics.str(), HasSubstr("no matching call"));
 }
 
 TEST_F(IntrinsicTableTest, MatchBool) {
   auto result = table->Lookup(*this, IntrinsicType::kSelect,
-                              {ty.f32(), ty.f32(), ty.bool_()});
+                              {ty.f32(), ty.f32(), ty.bool_()}, Source{});
   ASSERT_NE(result.intrinsic, nullptr);
-  ASSERT_EQ(result.error, "");
+  ASSERT_EQ(result.diagnostics.str(), "");
   EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kSelect);
   EXPECT_THAT(result.intrinsic->ReturnType(), ty.f32());
   EXPECT_THAT(result.intrinsic->Parameters(),
@@ -173,17 +176,17 @@
 
 TEST_F(IntrinsicTableTest, MismatchBool) {
   auto result = table->Lookup(*this, IntrinsicType::kSelect,
-                              {ty.f32(), ty.f32(), ty.f32()});
+                              {ty.f32(), ty.f32(), ty.f32()}, Source{});
   ASSERT_EQ(result.intrinsic, nullptr);
-  ASSERT_THAT(result.error, HasSubstr("no matching call"));
+  ASSERT_THAT(result.diagnostics.str(), HasSubstr("no matching call"));
 }
 
 TEST_F(IntrinsicTableTest, MatchPointer) {
-  auto result =
-      table->Lookup(*this, IntrinsicType::kModf,
-                    {ty.f32(), ty.pointer<f32>(ast::StorageClass::kNone)});
+  auto result = table->Lookup(
+      *this, IntrinsicType::kModf,
+      {ty.f32(), ty.pointer<f32>(ast::StorageClass::kNone)}, Source{});
   ASSERT_NE(result.intrinsic, nullptr);
-  ASSERT_EQ(result.error, "");
+  ASSERT_EQ(result.diagnostics.str(), "");
   EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kModf);
   EXPECT_THAT(result.intrinsic->ReturnType(), ty.f32());
   EXPECT_THAT(
@@ -193,17 +196,17 @@
 }
 
 TEST_F(IntrinsicTableTest, MismatchPointer) {
-  auto result =
-      table->Lookup(*this, IntrinsicType::kModf, {ty.f32(), ty.f32()});
+  auto result = table->Lookup(*this, IntrinsicType::kModf, {ty.f32(), ty.f32()},
+                              Source{});
   ASSERT_EQ(result.intrinsic, nullptr);
-  ASSERT_THAT(result.error, HasSubstr("no matching call"));
+  ASSERT_THAT(result.diagnostics.str(), HasSubstr("no matching call"));
 }
 
 TEST_F(IntrinsicTableTest, MatchArray) {
-  auto result =
-      table->Lookup(*this, IntrinsicType::kArrayLength, {ty.array<f32>()});
+  auto result = table->Lookup(*this, IntrinsicType::kArrayLength,
+                              {ty.array<f32>()}, Source{});
   ASSERT_NE(result.intrinsic, nullptr);
-  ASSERT_EQ(result.error, "");
+  ASSERT_EQ(result.diagnostics.str(), "");
   EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kArrayLength);
   EXPECT_THAT(result.intrinsic->ReturnType(), ty.u32());
   EXPECT_THAT(result.intrinsic->Parameters(),
@@ -211,9 +214,10 @@
 }
 
 TEST_F(IntrinsicTableTest, MismatchArray) {
-  auto result = table->Lookup(*this, IntrinsicType::kArrayLength, {ty.f32()});
+  auto result =
+      table->Lookup(*this, IntrinsicType::kArrayLength, {ty.f32()}, Source{});
   ASSERT_EQ(result.intrinsic, nullptr);
-  ASSERT_THAT(result.error, HasSubstr("no matching call"));
+  ASSERT_THAT(result.diagnostics.str(), HasSubstr("no matching call"));
 }
 
 TEST_F(IntrinsicTableTest, MatchSampler) {
@@ -221,9 +225,9 @@
       create<type::SampledTexture>(type::TextureDimension::k2d, ty.f32());
   auto* sampler = create<type::Sampler>(type::SamplerKind::kSampler);
   auto result = table->Lookup(*this, IntrinsicType::kTextureSample,
-                              {tex, sampler, ty.vec2<f32>()});
+                              {tex, sampler, ty.vec2<f32>()}, Source{});
   ASSERT_NE(result.intrinsic, nullptr);
-  ASSERT_EQ(result.error, "");
+  ASSERT_EQ(result.diagnostics.str(), "");
   EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kTextureSample);
   EXPECT_THAT(result.intrinsic->ReturnType(), ty.vec4<f32>());
   EXPECT_THAT(
@@ -237,18 +241,18 @@
   auto* tex =
       create<type::SampledTexture>(type::TextureDimension::k2d, ty.f32());
   auto result = table->Lookup(*this, IntrinsicType::kTextureSample,
-                              {tex, ty.f32(), ty.vec2<f32>()});
+                              {tex, ty.f32(), ty.vec2<f32>()}, Source{});
   ASSERT_EQ(result.intrinsic, nullptr);
-  ASSERT_THAT(result.error, HasSubstr("no matching call"));
+  ASSERT_THAT(result.diagnostics.str(), HasSubstr("no matching call"));
 }
 
 TEST_F(IntrinsicTableTest, MatchSampledTexture) {
   auto* tex =
       create<type::SampledTexture>(type::TextureDimension::k2d, ty.f32());
-  auto result =
-      table->Lookup(*this, IntrinsicType::kTextureLoad, {tex, ty.vec2<i32>()});
+  auto result = table->Lookup(*this, IntrinsicType::kTextureLoad,
+                              {tex, ty.vec2<i32>()}, Source{});
   ASSERT_NE(result.intrinsic, nullptr);
-  ASSERT_EQ(result.error, "");
+  ASSERT_EQ(result.diagnostics.str(), "");
   EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kTextureLoad);
   EXPECT_THAT(result.intrinsic->ReturnType(), ty.vec4<f32>());
   EXPECT_THAT(
@@ -261,9 +265,9 @@
   auto* tex =
       create<type::MultisampledTexture>(type::TextureDimension::k2d, ty.f32());
   auto result = table->Lookup(*this, IntrinsicType::kTextureLoad,
-                              {tex, ty.vec2<i32>(), ty.i32()});
+                              {tex, ty.vec2<i32>(), ty.i32()}, Source{});
   ASSERT_NE(result.intrinsic, nullptr);
-  ASSERT_EQ(result.error, "");
+  ASSERT_EQ(result.diagnostics.str(), "");
   EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kTextureLoad);
   EXPECT_THAT(result.intrinsic->ReturnType(), ty.vec4<f32>());
   EXPECT_THAT(result.intrinsic->Parameters(),
@@ -274,10 +278,10 @@
 
 TEST_F(IntrinsicTableTest, MatchDepthTexture) {
   auto* tex = create<type::DepthTexture>(type::TextureDimension::k2d);
-  auto result =
-      table->Lookup(*this, IntrinsicType::kTextureLoad, {tex, ty.vec2<i32>()});
+  auto result = table->Lookup(*this, IntrinsicType::kTextureLoad,
+                              {tex, ty.vec2<i32>()}, Source{});
   ASSERT_NE(result.intrinsic, nullptr);
-  ASSERT_EQ(result.error, "");
+  ASSERT_EQ(result.diagnostics.str(), "");
   EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kTextureLoad);
   EXPECT_THAT(result.intrinsic->ReturnType(), ty.f32());
   EXPECT_THAT(
@@ -293,9 +297,9 @@
   auto* tex_ac =
       create<type::AccessControl>(ast::AccessControl::kReadOnly, tex);
   auto result = table->Lookup(*this, IntrinsicType::kTextureLoad,
-                              {tex_ac, ty.vec2<i32>()});
+                              {tex_ac, ty.vec2<i32>()}, Source{});
   ASSERT_NE(result.intrinsic, nullptr);
-  ASSERT_EQ(result.error, "");
+  ASSERT_EQ(result.diagnostics.str(), "");
   EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kTextureLoad);
   EXPECT_THAT(result.intrinsic->ReturnType(), ty.vec4<f32>());
   EXPECT_THAT(
@@ -310,10 +314,11 @@
       type::StorageTexture::SubtypeFor(type::ImageFormat::kR16Float, Types()));
   auto* tex_ac =
       create<type::AccessControl>(ast::AccessControl::kWriteOnly, tex);
-  auto result = table->Lookup(*this, IntrinsicType::kTextureStore,
-                              {tex_ac, ty.vec2<i32>(), ty.vec4<f32>()});
+  auto result =
+      table->Lookup(*this, IntrinsicType::kTextureStore,
+                    {tex_ac, ty.vec2<i32>(), ty.vec4<f32>()}, Source{});
   ASSERT_NE(result.intrinsic, nullptr);
-  ASSERT_EQ(result.error, "");
+  ASSERT_EQ(result.diagnostics.str(), "");
   EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kTextureStore);
   EXPECT_THAT(result.intrinsic->ReturnType(), ty.void_());
   EXPECT_THAT(result.intrinsic->Parameters(),
@@ -324,16 +329,17 @@
 
 TEST_F(IntrinsicTableTest, MismatchTexture) {
   auto result = table->Lookup(*this, IntrinsicType::kTextureLoad,
-                              {ty.f32(), ty.vec2<i32>()});
+                              {ty.f32(), ty.vec2<i32>()}, Source{});
   ASSERT_EQ(result.intrinsic, nullptr);
-  ASSERT_THAT(result.error, HasSubstr("no matching call"));
+  ASSERT_THAT(result.diagnostics.str(), HasSubstr("no matching call"));
 }
 
 TEST_F(IntrinsicTableTest, MatchAutoPointerDereference) {
-  auto result = table->Lookup(*this, IntrinsicType::kCos,
-                              {ty.pointer<f32>(ast::StorageClass::kNone)});
+  auto result =
+      table->Lookup(*this, IntrinsicType::kCos,
+                    {ty.pointer<f32>(ast::StorageClass::kNone)}, Source{});
   ASSERT_NE(result.intrinsic, nullptr);
-  ASSERT_EQ(result.error, "");
+  ASSERT_EQ(result.diagnostics.str(), "");
   EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kCos);
   EXPECT_THAT(result.intrinsic->ReturnType(), ty.f32());
   EXPECT_THAT(result.intrinsic->Parameters(), ElementsAre(Parameter{ty.f32()}));
@@ -343,9 +349,9 @@
   auto* alias_a = ty.alias("alias_a", ty.f32());
   auto* alias_b = ty.alias("alias_b", alias_a);
   auto* alias_c = ty.alias("alias_c", alias_b);
-  auto result = table->Lookup(*this, IntrinsicType::kCos, {alias_c});
+  auto result = table->Lookup(*this, IntrinsicType::kCos, {alias_c}, Source{});
   ASSERT_NE(result.intrinsic, nullptr);
-  ASSERT_EQ(result.error, "");
+  ASSERT_EQ(result.diagnostics.str(), "");
   EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kCos);
   EXPECT_THAT(result.intrinsic->ReturnType(), ty.f32());
   EXPECT_THAT(result.intrinsic->Parameters(), ElementsAre(Parameter{ty.f32()}));
@@ -353,9 +359,9 @@
 
 TEST_F(IntrinsicTableTest, MatchOpenType) {
   auto result = table->Lookup(*this, IntrinsicType::kClamp,
-                              {ty.f32(), ty.f32(), ty.f32()});
+                              {ty.f32(), ty.f32(), ty.f32()}, Source{});
   ASSERT_NE(result.intrinsic, nullptr);
-  ASSERT_EQ(result.error, "");
+  ASSERT_EQ(result.diagnostics.str(), "");
   EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kClamp);
   EXPECT_THAT(result.intrinsic->ReturnType(), ty.f32());
   EXPECT_THAT(result.intrinsic->Parameters(),
@@ -365,16 +371,17 @@
 
 TEST_F(IntrinsicTableTest, MismatchOpenType) {
   auto result = table->Lookup(*this, IntrinsicType::kClamp,
-                              {ty.f32(), ty.u32(), ty.f32()});
+                              {ty.f32(), ty.u32(), ty.f32()}, Source{});
   ASSERT_EQ(result.intrinsic, nullptr);
-  ASSERT_THAT(result.error, HasSubstr("no matching call"));
+  ASSERT_THAT(result.diagnostics.str(), HasSubstr("no matching call"));
 }
 
 TEST_F(IntrinsicTableTest, MatchOpenSizeVector) {
-  auto result = table->Lookup(*this, IntrinsicType::kClamp,
-                              {ty.vec2<f32>(), ty.vec2<f32>(), ty.vec2<f32>()});
+  auto result =
+      table->Lookup(*this, IntrinsicType::kClamp,
+                    {ty.vec2<f32>(), ty.vec2<f32>(), ty.vec2<f32>()}, Source{});
   ASSERT_NE(result.intrinsic, nullptr);
-  ASSERT_EQ(result.error, "");
+  ASSERT_EQ(result.diagnostics.str(), "");
   EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kClamp);
   EXPECT_THAT(result.intrinsic->ReturnType(), ty.vec2<f32>());
   EXPECT_THAT(result.intrinsic->Parameters(),
@@ -383,17 +390,18 @@
 }
 
 TEST_F(IntrinsicTableTest, MismatchOpenSizeVector) {
-  auto result = table->Lookup(*this, IntrinsicType::kClamp,
-                              {ty.vec2<f32>(), ty.vec2<u32>(), ty.vec2<f32>()});
+  auto result =
+      table->Lookup(*this, IntrinsicType::kClamp,
+                    {ty.vec2<f32>(), ty.vec2<u32>(), ty.vec2<f32>()}, Source{});
   ASSERT_EQ(result.intrinsic, nullptr);
-  ASSERT_THAT(result.error, HasSubstr("no matching call"));
+  ASSERT_THAT(result.diagnostics.str(), HasSubstr("no matching call"));
 }
 
 TEST_F(IntrinsicTableTest, MatchOpenSizeMatrix) {
-  auto result =
-      table->Lookup(*this, IntrinsicType::kDeterminant, {ty.mat3x3<f32>()});
+  auto result = table->Lookup(*this, IntrinsicType::kDeterminant,
+                              {ty.mat3x3<f32>()}, Source{});
   ASSERT_NE(result.intrinsic, nullptr);
-  ASSERT_EQ(result.error, "");
+  ASSERT_EQ(result.diagnostics.str(), "");
   EXPECT_THAT(result.intrinsic->Type(), IntrinsicType::kDeterminant);
   EXPECT_THAT(result.intrinsic->ReturnType(), ty.f32());
   EXPECT_THAT(result.intrinsic->Parameters(),
@@ -401,19 +409,19 @@
 }
 
 TEST_F(IntrinsicTableTest, MismatchOpenSizeMatrix) {
-  auto result =
-      table->Lookup(*this, IntrinsicType::kDeterminant, {ty.mat3x2<f32>()});
+  auto result = table->Lookup(*this, IntrinsicType::kDeterminant,
+                              {ty.mat3x2<f32>()}, Source{});
   ASSERT_EQ(result.intrinsic, nullptr);
-  ASSERT_THAT(result.error, HasSubstr("no matching call"));
+  ASSERT_THAT(result.diagnostics.str(), HasSubstr("no matching call"));
 }
 
 TEST_F(IntrinsicTableTest, OverloadOrderByNumberOfParameters) {
   // None of the arguments match, so expect the overloads with 2 parameters to
   // come first
   auto result = table->Lookup(*this, IntrinsicType::kTextureDimensions,
-                              {ty.bool_(), ty.bool_()});
-  ASSERT_EQ(result.error,
-            R"(no matching call to textureDimensions(bool, bool)
+                              {ty.bool_(), ty.bool_()}, Source{});
+  ASSERT_EQ(result.diagnostics.str(),
+            R"(error: no matching call to textureDimensions(bool, bool)
 
 27 candidate functions:
   textureDimensions(texture : texture_2d<T>, level : i32) -> vec2<i32>
@@ -449,9 +457,10 @@
 TEST_F(IntrinsicTableTest, OverloadOrderByMatchingParameter) {
   auto* tex = create<type::DepthTexture>(type::TextureDimension::k2d);
   auto result = table->Lookup(*this, IntrinsicType::kTextureDimensions,
-                              {tex, ty.bool_()});
-  ASSERT_EQ(result.error,
-            R"(no matching call to textureDimensions(texture_depth_2d, bool)
+                              {tex, ty.bool_()}, Source{});
+  ASSERT_EQ(
+      result.diagnostics.str(),
+      R"(error: no matching call to textureDimensions(texture_depth_2d, bool)
 
 27 candidate functions:
   textureDimensions(texture : texture_depth_2d, level : i32) -> vec2<i32>