[tint][wgsl] Migrate more resolver diagnostics over to StyledText
Change-Id: I1ab81074215171650227a77d51b4362e9c1b3e4c
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/176040
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
diff --git a/src/tint/lang/core/intrinsic/table.cc b/src/tint/lang/core/intrinsic/table.cc
index dd96db5..b888362 100644
--- a/src/tint/lang/core/intrinsic/table.cc
+++ b/src/tint/lang/core/intrinsic/table.cc
@@ -205,9 +205,9 @@
}
out << "(";
PrintTypeList(out, args);
- out << ")" << style::Plain;
+ out << ")";
- return out;
+ return out << style::Plain;
}
Result<Overload, StyledText> MatchIntrinsic(Context& context,
diff --git a/src/tint/lang/core/ir/validator.cc b/src/tint/lang/core/ir/validator.cc
index e0feca2..3fd6ae4 100644
--- a/src/tint/lang/core/ir/validator.cc
+++ b/src/tint/lang/core/ir/validator.cc
@@ -72,6 +72,7 @@
#include "src/tint/utils/containers/transform.h"
#include "src/tint/utils/macros/scoped_assignment.h"
#include "src/tint/utils/rtti/switch.h"
+#include "src/tint/utils/text/text_style.h"
/// If set to 1 then the Tint will dump the IR when validating.
#define TINT_DUMP_IR_WHEN_VALIDATING 0
@@ -307,8 +308,8 @@
for (auto& func : mod_.functions) {
if (!all_functions_.Add(func.Get())) {
- AddError(Source{}) << "function '" << Name(func.Get())
- << "' added to module multiple times";
+ AddError(Source{}) << "function " << style::Function << Name(func.Get()) << style::Plain
+ << " added to module multiple times";
}
}
diff --git a/src/tint/lang/wgsl/resolver/address_space_layout_validation_test.cc b/src/tint/lang/wgsl/resolver/address_space_layout_validation_test.cc
index a1bfe87..4fe832a 100644
--- a/src/tint/lang/wgsl/resolver/address_space_layout_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/address_space_layout_validation_test.cc
@@ -59,7 +59,7 @@
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(34:56 error: the offset of a struct member of type 'f32' in address space 'storage' must be a multiple of 4 bytes, but 'b' is currently at offset 5. Consider setting @align(4) on this member
+ R"(34:56 error: the offset of a struct member of type 'f32' in address space 'storage' must be a multiple of 4 bytes, but 'b' is currently at offset 5. Consider setting '@align(4)' on this member
12:34 note: see layout of struct:
/* align(4) size(12) */ struct S {
/* offset(0) align(4) size( 5) */ a : f32;
@@ -120,7 +120,7 @@
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(56:78 error: the offset of a struct member of type 'Inner' in address space 'uniform' must be a multiple of 16 bytes, but 'inner' is currently at offset 4. Consider setting @align(16) on this member
+ R"(56:78 error: the offset of a struct member of type 'Inner' in address space 'uniform' must be a multiple of 16 bytes, but 'inner' is currently at offset 4. Consider setting '@align(16)' on this member
34:56 note: see layout of struct:
/* align(4) size(8) */ struct Outer {
/* offset(0) align(4) size(4) */ scalar : f32;
@@ -189,7 +189,7 @@
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(56:78 error: the offset of a struct member of type '@stride(16) array<f32, 10>' in address space 'uniform' must be a multiple of 16 bytes, but 'inner' is currently at offset 4. Consider setting @align(16) on this member
+ R"(56:78 error: the offset of a struct member of type '@stride(16) array<f32, 10>' in address space 'uniform' must be a multiple of 16 bytes, but 'inner' is currently at offset 4. Consider setting '@align(16)' on this member
12:34 note: see layout of struct:
/* align(4) size(164) */ struct Outer {
/* offset( 0) align(4) size( 4) */ scalar : f32;
@@ -254,7 +254,7 @@
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(78:90 error: uniform storage requires that the number of bytes between the start of the previous member of type struct and the current member be a multiple of 16 bytes, but there are currently 8 bytes between 'inner' and 'scalar'. Consider setting @align(16) on this member
+ R"(78:90 error: 'uniform' storage requires that the number of bytes between the start of the previous member of type struct and the current member be a multiple of 16 bytes, but there are currently 8 bytes between 'inner' and 'scalar'. Consider setting '@align(16)' on this member
34:56 note: see layout of struct:
/* align(4) size(12) */ struct Outer {
/* offset( 0) align(1) size( 5) */ inner : Inner;
@@ -306,7 +306,7 @@
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(78:90 error: uniform storage requires that the number of bytes between the start of the previous member of type struct and the current member be a multiple of 16 bytes, but there are currently 20 bytes between 'inner' and 'scalar'. Consider setting @align(16) on this member
+ R"(78:90 error: 'uniform' storage requires that the number of bytes between the start of the previous member of type struct and the current member be a multiple of 16 bytes, but there are currently 20 bytes between 'inner' and 'scalar'. Consider setting '@align(16)' on this member
34:56 note: see layout of struct:
/* align(4) size(24) */ struct Outer {
/* offset( 0) align(4) size(20) */ inner : Inner;
@@ -424,7 +424,7 @@
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(34:56 error: uniform storage requires that array elements are aligned to 16 bytes, but array element of type 'f32' has a stride of 4 bytes. Consider using a vector or struct as the element type instead.
+ R"(34:56 error: 'uniform' storage requires that array elements are aligned to 16 bytes, but array element of type 'f32' has a stride of 4 bytes. Consider using a vector or struct as the element type instead.
12:34 note: see layout of struct:
/* align(4) size(44) */ struct Outer {
/* offset( 0) align(4) size(40) */ inner : array<f32, 10>;
@@ -458,7 +458,7 @@
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(34:56 error: uniform storage requires that array elements are aligned to 16 bytes, but array element of type 'vec2<f32>' has a stride of 8 bytes. Consider using a vec4 instead.
+ R"(34:56 error: 'uniform' storage requires that array elements are aligned to 16 bytes, but array element of type 'vec2<f32>' has a stride of 8 bytes. Consider using a vec4 instead.
12:34 note: see layout of struct:
/* align(8) size(88) */ struct Outer {
/* offset( 0) align(8) size(80) */ inner : array<vec2<f32>, 10>;
@@ -501,7 +501,7 @@
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(34:56 error: uniform storage requires that array elements are aligned to 16 bytes, but array element of type 'ArrayElem' has a stride of 8 bytes. Consider using the @size attribute on the last struct member.
+ R"(34:56 error: 'uniform' storage requires that array elements are aligned to 16 bytes, but array element of type 'ArrayElem' has a stride of 8 bytes. Consider using the '@size' attribute on the last struct member.
12:34 note: see layout of struct:
/* align(4) size(84) */ struct Outer {
/* offset( 0) align(4) size(80) */ inner : array<ArrayElem, 10>;
@@ -519,7 +519,7 @@
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(78:90 error: uniform storage requires that array elements are aligned to 16 bytes, but array element of type 'f32' has a stride of 4 bytes. Consider using a vector or struct as the element type instead.)");
+ R"(78:90 error: 'uniform' storage requires that array elements are aligned to 16 bytes, but array element of type 'f32' has a stride of 4 bytes. Consider using a vector or struct as the element type instead.)");
}
TEST_F(ResolverAddressSpaceLayoutValidationTest, UniformBuffer_InvalidArrayStride_NestedArray) {
@@ -541,7 +541,7 @@
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(34:56 error: uniform storage requires that array elements are aligned to 16 bytes, but array element of type 'f32' has a stride of 4 bytes. Consider using a vector or struct as the element type instead.
+ R"(34:56 error: 'uniform' storage requires that array elements are aligned to 16 bytes, but array element of type 'f32' has a stride of 4 bytes. Consider using a vector or struct as the element type instead.
12:34 note: see layout of struct:
/* align(4) size(64) */ struct Outer {
/* offset( 0) align(4) size(64) */ inner : array<array<f32, 4>, 4>;
@@ -591,7 +591,7 @@
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(34:56 error: the offset of a struct member of type 'f32' in address space 'push_constant' must be a multiple of 4 bytes, but 'b' is currently at offset 5. Consider setting @align(4) on this member
+ R"(34:56 error: the offset of a struct member of type 'f32' in address space 'push_constant' must be a multiple of 4 bytes, but 'b' is currently at offset 5. Consider setting '@align(4)' on this member
12:34 note: see layout of struct:
/* align(4) size(12) */ struct S {
/* offset(0) align(4) size( 5) */ a : f32;
diff --git a/src/tint/lang/wgsl/resolver/address_space_validation_test.cc b/src/tint/lang/wgsl/resolver/address_space_validation_test.cc
index f8c2f27b..aacf005 100644
--- a/src/tint/lang/wgsl/resolver/address_space_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/address_space_validation_test.cc
@@ -171,7 +171,7 @@
EXPECT_EQ(
r()->error(),
- R"(12:34 error: Type 'bool' cannot be used in address space 'storage' as it is non-host-shareable
+ R"(12:34 error: type 'bool' cannot be used in address space 'storage' as it is non-host-shareable
56:78 note: while instantiating 'var' g)");
}
@@ -183,7 +183,7 @@
EXPECT_EQ(
r()->error(),
- R"(12:34 error: Type 'bool' cannot be used in address space 'storage' as it is non-host-shareable
+ R"(12:34 error: type 'bool' cannot be used in address space 'storage' as it is non-host-shareable
note: while instantiating ptr<storage, bool, read>)");
}
@@ -198,7 +198,7 @@
EXPECT_EQ(
r()->error(),
- R"(12:34 error: Type 'bool' cannot be used in address space 'storage' as it is non-host-shareable
+ R"(12:34 error: type 'bool' cannot be used in address space 'storage' as it is non-host-shareable
56:78 note: while instantiating 'var' g)");
}
@@ -212,7 +212,7 @@
EXPECT_EQ(
r()->error(),
- R"(12:34 error: Type 'bool' cannot be used in address space 'storage' as it is non-host-shareable
+ R"(12:34 error: type 'bool' cannot be used in address space 'storage' as it is non-host-shareable
note: while instantiating ptr<storage, bool, read>)");
}
@@ -225,7 +225,7 @@
EXPECT_EQ(
r()->error(),
- R"(12:34 error: Type 'ptr<private, f32, read_write>' cannot be used in address space 'storage' as it is non-host-shareable
+ R"(12:34 error: type 'ptr<private, f32, read_write>' cannot be used in address space 'storage' as it is non-host-shareable
56:78 note: while instantiating 'var' g)");
}
@@ -557,7 +557,7 @@
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(12:34 error: uniform storage requires that array elements are aligned to 16 bytes, but array element of type 'i32' has a stride of 4 bytes. Consider using a vector or struct as the element type instead.
+ R"(12:34 error: 'uniform' storage requires that array elements are aligned to 16 bytes, but array element of type 'i32' has a stride of 4 bytes. Consider using a vector or struct as the element type instead.
note: see layout of struct:
/* align(4) size(4) */ struct S {
/* offset(0) align(4) size(4) */ m : array<i32>;
@@ -574,7 +574,7 @@
EXPECT_EQ(
r()->error(),
- R"(12:34 error: Type 'bool' cannot be used in address space 'uniform' as it is non-host-shareable
+ R"(12:34 error: type 'bool' cannot be used in address space 'uniform' as it is non-host-shareable
56:78 note: while instantiating 'var' g)");
}
@@ -586,7 +586,7 @@
EXPECT_EQ(
r()->error(),
- R"(12:34 error: Type 'bool' cannot be used in address space 'uniform' as it is non-host-shareable
+ R"(12:34 error: type 'bool' cannot be used in address space 'uniform' as it is non-host-shareable
56:78 note: while instantiating ptr<uniform, bool, read>)");
}
@@ -601,7 +601,7 @@
EXPECT_EQ(
r()->error(),
- R"(12:34 error: Type 'bool' cannot be used in address space 'uniform' as it is non-host-shareable
+ R"(12:34 error: type 'bool' cannot be used in address space 'uniform' as it is non-host-shareable
56:78 note: while instantiating 'var' g)");
}
@@ -615,7 +615,7 @@
EXPECT_EQ(
r()->error(),
- R"(12:34 error: Type 'bool' cannot be used in address space 'uniform' as it is non-host-shareable
+ R"(12:34 error: type 'bool' cannot be used in address space 'uniform' as it is non-host-shareable
56:78 note: while instantiating ptr<uniform, bool, read>)");
}
@@ -628,7 +628,7 @@
EXPECT_EQ(
r()->error(),
- R"(12:34 error: Type 'ptr<private, f32, read_write>' cannot be used in address space 'uniform' as it is non-host-shareable
+ R"(12:34 error: type 'ptr<private, f32, read_write>' cannot be used in address space 'uniform' as it is non-host-shareable
56:78 note: while instantiating 'var' g)");
}
@@ -852,7 +852,7 @@
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(12:34 error: Type 'bool' cannot be used in address space 'push_constant' as it is non-host-shareable
+ R"(12:34 error: type 'bool' cannot be used in address space 'push_constant' as it is non-host-shareable
56:78 note: while instantiating 'var' g)");
}
@@ -865,7 +865,7 @@
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(12:34 error: Type 'bool' cannot be used in address space 'push_constant' as it is non-host-shareable
+ R"(12:34 error: type 'bool' cannot be used in address space 'push_constant' as it is non-host-shareable
note: while instantiating ptr<push_constant, bool, read_write>)");
}
@@ -879,7 +879,7 @@
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "error: using f16 types in 'push_constant' address space is not implemented yet");
+ "error: using 'f16' in 'push_constant' address space is not implemented yet");
}
TEST_F(ResolverAddressSpaceValidationTest, PointerAlias_PushConstantF16) {
@@ -892,7 +892,7 @@
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "error: using f16 types in 'push_constant' address space is not implemented yet");
+ "error: using 'f16' in 'push_constant' address space is not implemented yet");
}
TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_PushConstantPointer) {
@@ -905,7 +905,7 @@
ASSERT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(12:34 error: Type 'ptr<private, f32, read_write>' cannot be used in address space 'push_constant' as it is non-host-shareable
+ R"(12:34 error: type 'ptr<private, f32, read_write>' cannot be used in address space 'push_constant' as it is non-host-shareable
56:78 note: while instantiating 'var' g)");
}
diff --git a/src/tint/lang/wgsl/resolver/assignment_validation_test.cc b/src/tint/lang/wgsl/resolver/assignment_validation_test.cc
index 1df19ab..61eb5a5 100644
--- a/src/tint/lang/wgsl/resolver/assignment_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/assignment_validation_test.cc
@@ -365,10 +365,9 @@
WrapInFunction(Assign(Phony(), Expr(Source{{12, 34}}, "s")));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: cannot assign 'S' to '_'. "
- "'_' can only be assigned a constructible, pointer, texture or "
- "sampler type");
+ EXPECT_EQ(
+ r()->error(),
+ R"(12:34 error: cannot assign 'S' to '_'. '_' can only be assigned a constructible, pointer, texture or sampler type)");
}
TEST_F(ResolverAssignmentValidationTest, AssignToPhony_DynamicArray_Fail) {
@@ -387,10 +386,9 @@
WrapInFunction(Assign(Phony(), MemberAccessor(Source{{12, 34}}, "s", "arr")));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: cannot assign 'array<i32>' to '_'. "
- "'_' can only be assigned a constructible, pointer, texture or sampler "
- "type");
+ EXPECT_EQ(
+ r()->error(),
+ R"(12:34 error: cannot assign 'array<i32>' to '_'. '_' can only be assigned a constructible, pointer, texture or sampler type)");
}
TEST_F(ResolverAssignmentValidationTest, AssignToPhony_Pass) {
diff --git a/src/tint/lang/wgsl/resolver/atomics_validation_test.cc b/src/tint/lang/wgsl/resolver/atomics_validation_test.cc
index 890e076..bd8cf06 100644
--- a/src/tint/lang/wgsl/resolver/atomics_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/atomics_validation_test.cc
@@ -74,7 +74,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: atomic variables must have <storage> or <workgroup> address space");
+ "12:34 error: 'atomic' variables must have 'storage' or 'workgroup' address space");
}
TEST_F(ResolverAtomicValidationTest, InvalidAddressSpace_Array) {
@@ -82,7 +82,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: atomic variables must have <storage> or <workgroup> address space");
+ "12:34 error: 'atomic' variables must have 'storage' or 'workgroup' address space");
}
TEST_F(ResolverAtomicValidationTest, InvalidAddressSpace_Struct) {
@@ -91,8 +91,8 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "56:78 error: atomic variables must have <storage> or <workgroup> address space\n"
- "note: atomic sub-type of 's' is declared here");
+ R"(56:78 error: 'atomic' variables must have 'storage' or 'workgroup' address space
+note: atomic sub-type of 's' is declared here)");
}
TEST_F(ResolverAtomicValidationTest, InvalidAddressSpace_StructOfStruct) {
@@ -106,8 +106,8 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "56:78 error: atomic variables must have <storage> or <workgroup> address space\n"
- "note: atomic sub-type of 'Outer' is declared here");
+ R"(56:78 error: 'atomic' variables must have 'storage' or 'workgroup' address space
+note: atomic sub-type of 'Outer' is declared here)");
}
TEST_F(ResolverAtomicValidationTest, InvalidAddressSpace_StructOfStructOfArray) {
@@ -121,7 +121,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(56:78 error: atomic variables must have <storage> or <workgroup> address space
+ R"(56:78 error: 'atomic' variables must have 'storage' or 'workgroup' address space
12:34 note: atomic sub-type of 'Outer' is declared here)");
}
@@ -134,8 +134,9 @@
GlobalVar(Source{{56, 78}}, "v", ty.Of(atomic_array), core::AddressSpace::kPrivate);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "56:78 error: atomic variables must have <storage> or <workgroup> address space");
+ EXPECT_EQ(
+ r()->error(),
+ R"(56:78 error: 'atomic' variables must have 'storage' or 'workgroup' address space)");
}
TEST_F(ResolverAtomicValidationTest, InvalidAddressSpace_ArrayOfStruct) {
@@ -149,7 +150,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(56:78 error: atomic variables must have <storage> or <workgroup> address space
+ R"(56:78 error: 'atomic' variables must have 'storage' or 'workgroup' address space
12:34 note: atomic sub-type of 'array<S, 5>' is declared here)");
}
@@ -166,7 +167,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(56:78 error: atomic variables must have <storage> or <workgroup> address space
+ R"(56:78 error: 'atomic' variables must have 'storage' or 'workgroup' address space
12:34 note: atomic sub-type of 'array<S, 5>' is declared here)");
}
@@ -205,7 +206,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(56:78 error: atomic variables must have <storage> or <workgroup> address space
+ R"(56:78 error: 'atomic' variables must have 'storage' or 'workgroup' address space
12:34 note: atomic sub-type of 'S0' is declared here)");
}
@@ -217,7 +218,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(56:78 error: atomic variables in <storage> address space must have read_write access mode
+ R"(56:78 error: atomic variables in 'storage' address space must have 'read_write' access mode
12:34 note: atomic sub-type of 's' is declared here)");
}
@@ -229,7 +230,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(56:78 error: atomic variables in <storage> address space must have read_write access mode
+ R"(56:78 error: atomic variables in 'storage' address space must have 'read_write' access mode
12:34 note: atomic sub-type of 's' is declared here)");
}
@@ -246,7 +247,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(56:78 error: atomic variables in <storage> address space must have read_write access mode
+ R"(56:78 error: atomic variables in 'storage' address space must have 'read_write' access mode
12:34 note: atomic sub-type of 'Outer' is declared here)");
}
@@ -263,7 +264,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(56:78 error: atomic variables in <storage> address space must have read_write access mode
+ R"(56:78 error: atomic variables in 'storage' address space must have 'read_write' access mode
12:34 note: atomic sub-type of 'Outer' is declared here)");
}
@@ -304,7 +305,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(12:34 error: atomic variables in <storage> address space must have read_write access mode
+ R"(12:34 error: atomic variables in 'storage' address space must have 'read_write' access mode
56:78 note: atomic sub-type of 'S0' is declared here)");
}
diff --git a/src/tint/lang/wgsl/resolver/attribute_validation_test.cc b/src/tint/lang/wgsl/resolver/attribute_validation_test.cc
index 78a967d..a36e21f 100644
--- a/src/tint/lang/wgsl/resolver/attribute_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/attribute_validation_test.cc
@@ -136,23 +136,23 @@
static std::vector<TestParams> OnlyDiagnosticValidFor(std::string thing) {
return {TestParams{
{AttributeKind::kAlign},
- "1:2 error: @align is not valid for " + thing,
+ "1:2 error: '@align' is not valid for " + thing,
},
TestParams{
{AttributeKind::kBinding},
- "1:2 error: @binding is not valid for " + thing,
+ "1:2 error: '@binding' is not valid for " + thing,
},
TestParams{
{AttributeKind::kBlendSrc},
- "1:2 error: @blend_src is not valid for " + thing,
+ "1:2 error: '@blend_src' is not valid for " + thing,
},
TestParams{
{AttributeKind::kBuiltinPosition},
- "1:2 error: @builtin is not valid for " + thing,
+ "1:2 error: '@builtin' is not valid for " + thing,
},
TestParams{
{AttributeKind::kColor},
- "1:2 error: @color is not valid for " + thing,
+ "1:2 error: '@color' is not valid for " + thing,
},
TestParams{
{AttributeKind::kDiagnostic},
@@ -160,51 +160,51 @@
},
TestParams{
{AttributeKind::kGroup},
- "1:2 error: @group is not valid for " + thing,
+ "1:2 error: '@group' is not valid for " + thing,
},
TestParams{
{AttributeKind::kId},
- "1:2 error: @id is not valid for " + thing,
+ "1:2 error: '@id' is not valid for " + thing,
},
TestParams{
{AttributeKind::kInterpolate},
- "1:2 error: @interpolate is not valid for " + thing,
+ "1:2 error: '@interpolate' is not valid for " + thing,
},
TestParams{
{AttributeKind::kInvariant},
- "1:2 error: @invariant is not valid for " + thing,
+ "1:2 error: '@invariant' is not valid for " + thing,
},
TestParams{
{AttributeKind::kLocation},
- "1:2 error: @location is not valid for " + thing,
+ "1:2 error: '@location' is not valid for " + thing,
},
TestParams{
{AttributeKind::kMustUse},
- "1:2 error: @must_use is not valid for " + thing,
+ "1:2 error: '@must_use' is not valid for " + thing,
},
TestParams{
{AttributeKind::kOffset},
- "1:2 error: @offset is not valid for " + thing,
+ "1:2 error: '@offset' is not valid for " + thing,
},
TestParams{
{AttributeKind::kSize},
- "1:2 error: @size is not valid for " + thing,
+ "1:2 error: '@size' is not valid for " + thing,
},
TestParams{
{AttributeKind::kStageCompute},
- "1:2 error: @stage is not valid for " + thing,
+ "1:2 error: '@stage' is not valid for " + thing,
},
TestParams{
{AttributeKind::kStride},
- "1:2 error: @stride is not valid for " + thing,
+ "1:2 error: '@stride' is not valid for " + thing,
},
TestParams{
{AttributeKind::kWorkgroupSize},
- "1:2 error: @workgroup_size is not valid for " + thing,
+ "1:2 error: '@workgroup_size' is not valid for " + thing,
},
TestParams{
{AttributeKind::kBinding, AttributeKind::kGroup},
- "1:2 error: @binding is not valid for " + thing,
+ "1:2 error: '@binding' is not valid for " + thing,
}};
}
@@ -316,23 +316,23 @@
testing::Values(
TestParams{
{AttributeKind::kAlign},
- R"(1:2 error: @align is not valid for functions)",
+ R"(1:2 error: '@align' is not valid for functions)",
},
TestParams{
{AttributeKind::kBinding},
- R"(1:2 error: @binding is not valid for functions)",
+ R"(1:2 error: '@binding' is not valid for functions)",
},
TestParams{
{AttributeKind::kBlendSrc},
- R"(1:2 error: @blend_src is not valid for functions)",
+ R"(1:2 error: '@blend_src' is not valid for functions)",
},
TestParams{
{AttributeKind::kBuiltinPosition},
- R"(1:2 error: @builtin is not valid for functions)",
+ R"(1:2 error: '@builtin' is not valid for functions)",
},
TestParams{
{AttributeKind::kColor},
- R"(1:2 error: @color is not valid for functions)",
+ R"(1:2 error: '@color' is not valid for functions)",
},
TestParams{
{AttributeKind::kDiagnostic},
@@ -340,39 +340,39 @@
},
TestParams{
{AttributeKind::kGroup},
- R"(1:2 error: @group is not valid for functions)",
+ R"(1:2 error: '@group' is not valid for functions)",
},
TestParams{
{AttributeKind::kId},
- R"(1:2 error: @id is not valid for functions)",
+ R"(1:2 error: '@id' is not valid for functions)",
},
TestParams{
{AttributeKind::kInterpolate},
- R"(1:2 error: @interpolate is not valid for functions)",
+ R"(1:2 error: '@interpolate' is not valid for functions)",
},
TestParams{
{AttributeKind::kInvariant},
- R"(1:2 error: @invariant is not valid for functions)",
+ R"(1:2 error: '@invariant' is not valid for functions)",
},
TestParams{
{AttributeKind::kLocation},
- R"(1:2 error: @location is not valid for functions)",
+ R"(1:2 error: '@location' is not valid for functions)",
},
TestParams{
{AttributeKind::kMustUse},
- R"(1:2 error: @must_use can only be applied to functions that return a value)",
+ R"(1:2 error: '@must_use' can only be applied to functions that return a value)",
},
TestParams{
{AttributeKind::kOffset},
- R"(1:2 error: @offset is not valid for functions)",
+ R"(1:2 error: '@offset' is not valid for functions)",
},
TestParams{
{AttributeKind::kSize},
- R"(1:2 error: @size is not valid for functions)",
+ R"(1:2 error: '@size' is not valid for functions)",
},
TestParams{
{AttributeKind::kStageCompute},
- R"(9:9 error: a compute shader must include 'workgroup_size' in its attributes)",
+ R"(9:9 error: a compute shader must include '@workgroup_size' in its attributes)",
},
TestParams{
{AttributeKind::kStageCompute, AttributeKind::kWorkgroupSize},
@@ -380,11 +380,11 @@
},
TestParams{
{AttributeKind::kStride},
- R"(1:2 error: @stride is not valid for functions)",
+ R"(1:2 error: '@stride' is not valid for functions)",
},
TestParams{
{AttributeKind::kWorkgroupSize},
- R"(1:2 error: @workgroup_size is only valid for compute stages)",
+ R"(1:2 error: '@workgroup_size' is only valid for compute stages)",
}));
using NonVoidFunctionAttributeTest = TestWithParams;
@@ -400,23 +400,23 @@
testing::Values(
TestParams{
{AttributeKind::kAlign},
- R"(1:2 error: @align is not valid for functions)",
+ R"(1:2 error: '@align' is not valid for functions)",
},
TestParams{
{AttributeKind::kBinding},
- R"(1:2 error: @binding is not valid for functions)",
+ R"(1:2 error: '@binding' is not valid for functions)",
},
TestParams{
{AttributeKind::kBlendSrc},
- R"(1:2 error: @blend_src is not valid for functions)",
+ R"(1:2 error: '@blend_src' is not valid for functions)",
},
TestParams{
{AttributeKind::kBuiltinPosition},
- R"(1:2 error: @builtin is not valid for functions)",
+ R"(1:2 error: '@builtin' is not valid for functions)",
},
TestParams{
{AttributeKind::kColor},
- R"(1:2 error: @color is not valid for functions)",
+ R"(1:2 error: '@color' is not valid for functions)",
},
TestParams{
{AttributeKind::kDiagnostic},
@@ -424,23 +424,23 @@
},
TestParams{
{AttributeKind::kGroup},
- R"(1:2 error: @group is not valid for functions)",
+ R"(1:2 error: '@group' is not valid for functions)",
},
TestParams{
{AttributeKind::kId},
- R"(1:2 error: @id is not valid for functions)",
+ R"(1:2 error: '@id' is not valid for functions)",
},
TestParams{
{AttributeKind::kInterpolate},
- R"(1:2 error: @interpolate is not valid for functions)",
+ R"(1:2 error: '@interpolate' is not valid for functions)",
},
TestParams{
{AttributeKind::kInvariant},
- R"(1:2 error: @invariant is not valid for functions)",
+ R"(1:2 error: '@invariant' is not valid for functions)",
},
TestParams{
{AttributeKind::kLocation},
- R"(1:2 error: @location is not valid for functions)",
+ R"(1:2 error: '@location' is not valid for functions)",
},
TestParams{
{AttributeKind::kMustUse},
@@ -448,11 +448,11 @@
},
TestParams{
{AttributeKind::kOffset},
- R"(1:2 error: @offset is not valid for functions)",
+ R"(1:2 error: '@offset' is not valid for functions)",
},
TestParams{
{AttributeKind::kSize},
- R"(1:2 error: @size is not valid for functions)",
+ R"(1:2 error: '@size' is not valid for functions)",
},
TestParams{
{AttributeKind::kStageCompute},
@@ -464,11 +464,11 @@
},
TestParams{
{AttributeKind::kStride},
- R"(1:2 error: @stride is not valid for functions)",
+ R"(1:2 error: '@stride' is not valid for functions)",
},
TestParams{
{AttributeKind::kWorkgroupSize},
- R"(1:2 error: @workgroup_size is only valid for compute stages)",
+ R"(1:2 error: '@workgroup_size' is only valid for compute stages)",
}));
} // namespace FunctionTests
@@ -491,71 +491,71 @@
testing::Values(
TestParams{
{AttributeKind::kAlign},
- R"(1:2 error: @align is not valid for function parameters)",
+ R"(1:2 error: '@align' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kBinding},
- R"(1:2 error: @binding is not valid for function parameters)",
+ R"(1:2 error: '@binding' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kBlendSrc},
- R"(1:2 error: @blend_src is not valid for function parameters)",
+ R"(1:2 error: '@blend_src' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kBuiltinPosition},
- R"(1:2 error: @builtin is not valid for non-entry point function parameters)",
+ R"(1:2 error: '@builtin' is not valid for non-entry point function parameters)",
},
TestParams{
{AttributeKind::kColor},
- R"(1:2 error: @color is not valid for function parameters)",
+ R"(1:2 error: '@color' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kDiagnostic},
- R"(1:2 error: @diagnostic is not valid for function parameters)",
+ R"(1:2 error: '@diagnostic' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kGroup},
- R"(1:2 error: @group is not valid for function parameters)",
+ R"(1:2 error: '@group' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kId},
- R"(1:2 error: @id is not valid for function parameters)",
+ R"(1:2 error: '@id' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kInterpolate},
- R"(1:2 error: @interpolate is not valid for non-entry point function parameters)",
+ R"(1:2 error: '@interpolate' is not valid for non-entry point function parameters)",
},
TestParams{
{AttributeKind::kInvariant},
- R"(1:2 error: @invariant is not valid for non-entry point function parameters)",
+ R"(1:2 error: '@invariant' is not valid for non-entry point function parameters)",
},
TestParams{
{AttributeKind::kLocation},
- R"(1:2 error: @location is not valid for non-entry point function parameters)",
+ R"(1:2 error: '@location' is not valid for non-entry point function parameters)",
},
TestParams{
{AttributeKind::kMustUse},
- R"(1:2 error: @must_use is not valid for function parameters)",
+ R"(1:2 error: '@must_use' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kOffset},
- R"(1:2 error: @offset is not valid for function parameters)",
+ R"(1:2 error: '@offset' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kSize},
- R"(1:2 error: @size is not valid for function parameters)",
+ R"(1:2 error: '@size' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kStageCompute},
- R"(1:2 error: @stage is not valid for function parameters)",
+ R"(1:2 error: '@stage' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kStride},
- R"(1:2 error: @stride is not valid for function parameters)",
+ R"(1:2 error: '@stride' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kWorkgroupSize},
- R"(1:2 error: @workgroup_size is not valid for function parameters)",
+ R"(1:2 error: '@workgroup_size' is not valid for function parameters)",
}));
using FunctionReturnTypeAttributeTest = TestWithParams;
@@ -576,71 +576,71 @@
testing::Values(
TestParams{
{AttributeKind::kAlign},
- R"(1:2 error: @align is not valid for non-entry point function return types)",
+ R"(1:2 error: '@align' is not valid for non-entry point function return types)",
},
TestParams{
{AttributeKind::kBinding},
- R"(1:2 error: @binding is not valid for non-entry point function return types)",
+ R"(1:2 error: '@binding' is not valid for non-entry point function return types)",
},
TestParams{
{AttributeKind::kBlendSrc},
- R"(1:2 error: @blend_src is not valid for non-entry point function return types)",
+ R"(1:2 error: '@blend_src' is not valid for non-entry point function return types)",
},
TestParams{
{AttributeKind::kBuiltinPosition},
- R"(1:2 error: @builtin is not valid for non-entry point function return types)",
+ R"(1:2 error: '@builtin' is not valid for non-entry point function return types)",
},
TestParams{
{AttributeKind::kColor},
- R"(1:2 error: @color is not valid for non-entry point function return types)",
+ R"(1:2 error: '@color' is not valid for non-entry point function return types)",
},
TestParams{
{AttributeKind::kDiagnostic},
- R"(1:2 error: @diagnostic is not valid for non-entry point function return types)",
+ R"(1:2 error: '@diagnostic' is not valid for non-entry point function return types)",
},
TestParams{
{AttributeKind::kGroup},
- R"(1:2 error: @group is not valid for non-entry point function return types)",
+ R"(1:2 error: '@group' is not valid for non-entry point function return types)",
},
TestParams{
{AttributeKind::kId},
- R"(1:2 error: @id is not valid for non-entry point function return types)",
+ R"(1:2 error: '@id' is not valid for non-entry point function return types)",
},
TestParams{
{AttributeKind::kInterpolate},
- R"(1:2 error: @interpolate is not valid for non-entry point function return types)",
+ R"(1:2 error: '@interpolate' is not valid for non-entry point function return types)",
},
TestParams{
{AttributeKind::kInvariant},
- R"(1:2 error: @invariant is not valid for non-entry point function return types)",
+ R"(1:2 error: '@invariant' is not valid for non-entry point function return types)",
},
TestParams{
{AttributeKind::kLocation},
- R"(1:2 error: @location is not valid for non-entry point function return types)",
+ R"(1:2 error: '@location' is not valid for non-entry point function return types)",
},
TestParams{
{AttributeKind::kMustUse},
- R"(1:2 error: @must_use is not valid for non-entry point function return types)",
+ R"(1:2 error: '@must_use' is not valid for non-entry point function return types)",
},
TestParams{
{AttributeKind::kOffset},
- R"(1:2 error: @offset is not valid for non-entry point function return types)",
+ R"(1:2 error: '@offset' is not valid for non-entry point function return types)",
},
TestParams{
{AttributeKind::kSize},
- R"(1:2 error: @size is not valid for non-entry point function return types)",
+ R"(1:2 error: '@size' is not valid for non-entry point function return types)",
},
TestParams{
{AttributeKind::kStageCompute},
- R"(1:2 error: @stage is not valid for non-entry point function return types)",
+ R"(1:2 error: '@stage' is not valid for non-entry point function return types)",
},
TestParams{
{AttributeKind::kStride},
- R"(1:2 error: @stride is not valid for non-entry point function return types)",
+ R"(1:2 error: '@stride' is not valid for non-entry point function return types)",
},
TestParams{
{AttributeKind::kWorkgroupSize},
- R"(1:2 error: @workgroup_size is not valid for non-entry point function return types)",
+ R"(1:2 error: '@workgroup_size' is not valid for non-entry point function return types)",
}));
} // namespace FunctionInputAndOutputTests
@@ -666,71 +666,71 @@
testing::Values(
TestParams{
{AttributeKind::kAlign},
- R"(1:2 error: @align is not valid for function parameters)",
+ R"(1:2 error: '@align' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kBinding},
- R"(1:2 error: @binding is not valid for function parameters)",
+ R"(1:2 error: '@binding' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kBlendSrc},
- R"(1:2 error: @blend_src is not valid for function parameters)",
+ R"(1:2 error: '@blend_src' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kBuiltinPosition},
- R"(1:2 error: @builtin(position) cannot be used for compute shader input)",
+ R"(1:2 error: '@builtin(position)' cannot be used for compute shader input)",
},
TestParams{
{AttributeKind::kColor},
- R"(1:2 error: @color can only be used for fragment shader input)",
+ R"(1:2 error: '@color' can only be used for fragment shader input)",
},
TestParams{
{AttributeKind::kDiagnostic},
- R"(1:2 error: @diagnostic is not valid for function parameters)",
+ R"(1:2 error: '@diagnostic' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kGroup},
- R"(1:2 error: @group is not valid for function parameters)",
+ R"(1:2 error: '@group' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kId},
- R"(1:2 error: @id is not valid for function parameters)",
+ R"(1:2 error: '@id' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kInterpolate},
- R"(1:2 error: @interpolate cannot be used by compute shaders)",
+ R"(1:2 error: '@interpolate' cannot be used by compute shaders)",
},
TestParams{
{AttributeKind::kInvariant},
- R"(1:2 error: @invariant cannot be used by compute shaders)",
+ R"(1:2 error: '@invariant' cannot be used by compute shaders)",
},
TestParams{
{AttributeKind::kLocation},
- R"(1:2 error: @location cannot be used by compute shaders)",
+ R"(1:2 error: '@location' cannot be used by compute shaders)",
},
TestParams{
{AttributeKind::kMustUse},
- R"(1:2 error: @must_use is not valid for function parameters)",
+ R"(1:2 error: '@must_use' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kOffset},
- R"(1:2 error: @offset is not valid for function parameters)",
+ R"(1:2 error: '@offset' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kSize},
- R"(1:2 error: @size is not valid for function parameters)",
+ R"(1:2 error: '@size' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kStageCompute},
- R"(1:2 error: @stage is not valid for function parameters)",
+ R"(1:2 error: '@stage' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kStride},
- R"(1:2 error: @stride is not valid for function parameters)",
+ R"(1:2 error: '@stride' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kWorkgroupSize},
- R"(1:2 error: @workgroup_size is not valid for function parameters)",
+ R"(1:2 error: '@workgroup_size' is not valid for function parameters)",
}));
using FragmentShaderParameterAttributeTest = TestWithParams;
@@ -750,15 +750,15 @@
testing::Values(
TestParams{
{AttributeKind::kAlign},
- R"(1:2 error: @align is not valid for function parameters)",
+ R"(1:2 error: '@align' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kBinding},
- R"(1:2 error: @binding is not valid for function parameters)",
+ R"(1:2 error: '@binding' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kBlendSrc},
- R"(1:2 error: @blend_src is not valid for function parameters)",
+ R"(1:2 error: '@blend_src' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kBuiltinPosition},
@@ -771,19 +771,19 @@
TestParams{
{AttributeKind::kColor, AttributeKind::kLocation},
R"(3:4 error: multiple entry point IO attributes
-1:2 note: previously consumed @color)",
+1:2 note: previously consumed '@color')",
},
TestParams{
{AttributeKind::kDiagnostic},
- R"(1:2 error: @diagnostic is not valid for function parameters)",
+ R"(1:2 error: '@diagnostic' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kGroup},
- R"(1:2 error: @group is not valid for function parameters)",
+ R"(1:2 error: '@group' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kId},
- R"(1:2 error: @id is not valid for function parameters)",
+ R"(1:2 error: '@id' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kInterpolate},
@@ -791,7 +791,7 @@
},
TestParams{
{AttributeKind::kInterpolate, AttributeKind::kBuiltinPosition},
- R"(1:2 error: @interpolate can only be used with @location)",
+ R"(1:2 error: '@interpolate' can only be used with '@location')",
},
TestParams{
{AttributeKind::kInterpolate, AttributeKind::kLocation},
@@ -811,27 +811,27 @@
},
TestParams{
{AttributeKind::kMustUse},
- R"(1:2 error: @must_use is not valid for function parameters)",
+ R"(1:2 error: '@must_use' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kOffset},
- R"(1:2 error: @offset is not valid for function parameters)",
+ R"(1:2 error: '@offset' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kSize},
- R"(1:2 error: @size is not valid for function parameters)",
+ R"(1:2 error: '@size' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kStageCompute},
- R"(1:2 error: @stage is not valid for function parameters)",
+ R"(1:2 error: '@stage' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kStride},
- R"(1:2 error: @stride is not valid for function parameters)",
+ R"(1:2 error: '@stride' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kWorkgroupSize},
- R"(1:2 error: @workgroup_size is not valid for function parameters)",
+ R"(1:2 error: '@workgroup_size' is not valid for function parameters)",
}));
using VertexShaderParameterAttributeTest = TestWithParams;
@@ -858,35 +858,35 @@
testing::Values(
TestParams{
{AttributeKind::kAlign},
- R"(1:2 error: @align is not valid for function parameters)",
+ R"(1:2 error: '@align' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kBinding},
- R"(1:2 error: @binding is not valid for function parameters)",
+ R"(1:2 error: '@binding' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kBlendSrc},
- R"(1:2 error: @blend_src is not valid for function parameters)",
+ R"(1:2 error: '@blend_src' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kBuiltinPosition},
- R"(1:2 error: @builtin(position) cannot be used for vertex shader input)",
+ R"(1:2 error: '@builtin(position)' cannot be used for vertex shader input)",
},
TestParams{
{AttributeKind::kColor},
- R"(1:2 error: @color can only be used for fragment shader input)",
+ R"(1:2 error: '@color' can only be used for fragment shader input)",
},
TestParams{
{AttributeKind::kDiagnostic},
- R"(1:2 error: @diagnostic is not valid for function parameters)",
+ R"(1:2 error: '@diagnostic' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kGroup},
- R"(1:2 error: @group is not valid for function parameters)",
+ R"(1:2 error: '@group' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kId},
- R"(1:2 error: @id is not valid for function parameters)",
+ R"(1:2 error: '@id' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kInterpolate},
@@ -898,7 +898,7 @@
},
TestParams{
{AttributeKind::kInterpolate, AttributeKind::kBuiltinPosition},
- R"(3:4 error: @builtin(position) cannot be used for vertex shader input)",
+ R"(3:4 error: '@builtin(position)' cannot be used for vertex shader input)",
},
TestParams{
{AttributeKind::kInvariant},
@@ -906,11 +906,11 @@
},
TestParams{
{AttributeKind::kInvariant, AttributeKind::kLocation},
- R"(1:2 error: @invariant must be applied to a position builtin)",
+ R"(1:2 error: '@invariant' must be applied to a '@builtin(position)')",
},
TestParams{
{AttributeKind::kInvariant, AttributeKind::kBuiltinPosition},
- R"(3:4 error: @builtin(position) cannot be used for vertex shader input)",
+ R"(3:4 error: '@builtin(position)' cannot be used for vertex shader input)",
},
TestParams{
{AttributeKind::kLocation},
@@ -918,27 +918,27 @@
},
TestParams{
{AttributeKind::kMustUse},
- R"(1:2 error: @must_use is not valid for function parameters)",
+ R"(1:2 error: '@must_use' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kOffset},
- R"(1:2 error: @offset is not valid for function parameters)",
+ R"(1:2 error: '@offset' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kSize},
- R"(1:2 error: @size is not valid for function parameters)",
+ R"(1:2 error: '@size' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kStageCompute},
- R"(1:2 error: @stage is not valid for function parameters)",
+ R"(1:2 error: '@stage' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kStride},
- R"(1:2 error: @stride is not valid for function parameters)",
+ R"(1:2 error: '@stride' is not valid for function parameters)",
},
TestParams{
{AttributeKind::kWorkgroupSize},
- R"(1:2 error: @workgroup_size is not valid for function parameters)",
+ R"(1:2 error: '@workgroup_size' is not valid for function parameters)",
}));
using ComputeShaderReturnTypeAttributeTest = TestWithParams;
@@ -963,71 +963,71 @@
testing::Values(
TestParams{
{AttributeKind::kAlign},
- R"(1:2 error: @align is not valid for entry point return types)",
+ R"(1:2 error: '@align' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kBinding},
- R"(1:2 error: @binding is not valid for entry point return types)",
+ R"(1:2 error: '@binding' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kBlendSrc},
- R"(1:2 error: @blend_src can only be used for fragment shader output)",
+ R"(1:2 error: '@blend_src' can only be used for fragment shader output)",
},
TestParams{
{AttributeKind::kBuiltinPosition},
- R"(1:2 error: @builtin(position) cannot be used for compute shader output)",
+ R"(1:2 error: '@builtin(position)' cannot be used for compute shader output)",
},
TestParams{
{AttributeKind::kColor},
- R"(1:2 error: @color is not valid for entry point return types)",
+ R"(1:2 error: '@color' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kDiagnostic},
- R"(1:2 error: @diagnostic is not valid for entry point return types)",
+ R"(1:2 error: '@diagnostic' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kGroup},
- R"(1:2 error: @group is not valid for entry point return types)",
+ R"(1:2 error: '@group' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kId},
- R"(1:2 error: @id is not valid for entry point return types)",
+ R"(1:2 error: '@id' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kInterpolate},
- R"(1:2 error: @interpolate cannot be used by compute shaders)",
+ R"(1:2 error: '@interpolate' cannot be used by compute shaders)",
},
TestParams{
{AttributeKind::kInvariant},
- R"(1:2 error: @invariant cannot be used by compute shaders)",
+ R"(1:2 error: '@invariant' cannot be used by compute shaders)",
},
TestParams{
{AttributeKind::kLocation},
- R"(1:2 error: @location cannot be used by compute shaders)",
+ R"(1:2 error: '@location' cannot be used by compute shaders)",
},
TestParams{
{AttributeKind::kMustUse},
- R"(1:2 error: @must_use is not valid for entry point return types)",
+ R"(1:2 error: '@must_use' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kOffset},
- R"(1:2 error: @offset is not valid for entry point return types)",
+ R"(1:2 error: '@offset' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kSize},
- R"(1:2 error: @size is not valid for entry point return types)",
+ R"(1:2 error: '@size' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kStageCompute},
- R"(1:2 error: @stage is not valid for entry point return types)",
+ R"(1:2 error: '@stage' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kStride},
- R"(1:2 error: @stride is not valid for entry point return types)",
+ R"(1:2 error: '@stride' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kWorkgroupSize},
- R"(1:2 error: @workgroup_size is not valid for entry point return types)",
+ R"(1:2 error: '@workgroup_size' is not valid for entry point return types)",
}));
using FragmentShaderReturnTypeAttributeTest = TestWithParams;
@@ -1049,11 +1049,11 @@
testing::Values(
TestParams{
{AttributeKind::kAlign},
- R"(1:2 error: @align is not valid for entry point return types)",
+ R"(1:2 error: '@align' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kBinding},
- R"(1:2 error: @binding is not valid for entry point return types)",
+ R"(1:2 error: '@binding' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kBlendSrc},
@@ -1065,23 +1065,23 @@
},
TestParams{
{AttributeKind::kBuiltinPosition},
- R"(1:2 error: @builtin(position) cannot be used for fragment shader output)",
+ R"(1:2 error: '@builtin(position)' cannot be used for fragment shader output)",
},
TestParams{
{AttributeKind::kColor},
- R"(1:2 error: @color is not valid for entry point return types)",
+ R"(1:2 error: '@color' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kDiagnostic},
- R"(1:2 error: @diagnostic is not valid for entry point return types)",
+ R"(1:2 error: '@diagnostic' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kGroup},
- R"(1:2 error: @group is not valid for entry point return types)",
+ R"(1:2 error: '@group' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kId},
- R"(1:2 error: @id is not valid for entry point return types)",
+ R"(1:2 error: '@id' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kInterpolate},
@@ -1097,7 +1097,7 @@
},
TestParams{
{AttributeKind::kInvariant, AttributeKind::kLocation},
- R"(1:2 error: @invariant must be applied to a position builtin)",
+ R"(1:2 error: '@invariant' must be applied to a '@builtin(position)')",
},
TestParams{
{AttributeKind::kLocation},
@@ -1105,31 +1105,31 @@
},
TestParams{
{AttributeKind::kMustUse},
- R"(1:2 error: @must_use is not valid for entry point return types)",
+ R"(1:2 error: '@must_use' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kOffset},
- R"(1:2 error: @offset is not valid for entry point return types)",
+ R"(1:2 error: '@offset' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kSize},
- R"(1:2 error: @size is not valid for entry point return types)",
+ R"(1:2 error: '@size' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kStageCompute},
- R"(1:2 error: @stage is not valid for entry point return types)",
+ R"(1:2 error: '@stage' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kStride},
- R"(1:2 error: @stride is not valid for entry point return types)",
+ R"(1:2 error: '@stride' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kWorkgroupSize},
- R"(1:2 error: @workgroup_size is not valid for entry point return types)",
+ R"(1:2 error: '@workgroup_size' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kBinding, AttributeKind::kGroup},
- R"(1:2 error: @binding is not valid for entry point return types)",
+ R"(1:2 error: '@binding' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kBlendSrc, AttributeKind::kLocation},
@@ -1161,15 +1161,15 @@
testing::Values(
TestParams{
{AttributeKind::kAlign},
- R"(1:2 error: @align is not valid for entry point return types)",
+ R"(1:2 error: '@align' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kBinding},
- R"(1:2 error: @binding is not valid for entry point return types)",
+ R"(1:2 error: '@binding' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kBlendSrc},
- R"(1:2 error: @blend_src can only be used for fragment shader output)",
+ R"(1:2 error: '@blend_src' can only be used for fragment shader output)",
},
TestParams{
{AttributeKind::kBuiltinPosition},
@@ -1177,23 +1177,23 @@
},
TestParams{
{AttributeKind::kColor},
- R"(1:2 error: @color is not valid for entry point return types)",
+ R"(1:2 error: '@color' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kDiagnostic},
- R"(1:2 error: @diagnostic is not valid for entry point return types)",
+ R"(1:2 error: '@diagnostic' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kGroup},
- R"(1:2 error: @group is not valid for entry point return types)",
+ R"(1:2 error: '@group' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kId},
- R"(1:2 error: @id is not valid for entry point return types)",
+ R"(1:2 error: '@id' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kInterpolate},
- R"(1:2 error: @interpolate can only be used with @location)",
+ R"(1:2 error: '@interpolate' can only be used with '@location')",
},
TestParams{
{AttributeKind::kInvariant},
@@ -1202,35 +1202,35 @@
TestParams{
{AttributeKind::kLocation},
R"(9:9 error: multiple entry point IO attributes
-1:2 note: previously consumed @location)",
+1:2 note: previously consumed '@location')",
},
TestParams{
{AttributeKind::kMustUse},
- R"(1:2 error: @must_use is not valid for entry point return types)",
+ R"(1:2 error: '@must_use' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kOffset},
- R"(1:2 error: @offset is not valid for entry point return types)",
+ R"(1:2 error: '@offset' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kSize},
- R"(1:2 error: @size is not valid for entry point return types)",
+ R"(1:2 error: '@size' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kStageCompute},
- R"(1:2 error: @stage is not valid for entry point return types)",
+ R"(1:2 error: '@stage' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kStride},
- R"(1:2 error: @stride is not valid for entry point return types)",
+ R"(1:2 error: '@stride' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kWorkgroupSize},
- R"(1:2 error: @workgroup_size is not valid for entry point return types)",
+ R"(1:2 error: '@workgroup_size' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kBinding, AttributeKind::kGroup},
- R"(1:2 error: @binding is not valid for entry point return types)",
+ R"(1:2 error: '@binding' is not valid for entry point return types)",
},
TestParams{
{AttributeKind::kLocation, AttributeKind::kLocation},
@@ -1286,75 +1286,75 @@
testing::Values(
TestParams{
{AttributeKind::kAlign},
- R"(1:2 error: @align is not valid for struct declarations)",
+ R"(1:2 error: '@align' is not valid for 'struct' declarations)",
},
TestParams{
{AttributeKind::kBinding},
- R"(1:2 error: @binding is not valid for struct declarations)",
+ R"(1:2 error: '@binding' is not valid for 'struct' declarations)",
},
TestParams{
{AttributeKind::kBlendSrc},
- R"(1:2 error: @blend_src is not valid for struct declarations)",
+ R"(1:2 error: '@blend_src' is not valid for 'struct' declarations)",
},
TestParams{
{AttributeKind::kBuiltinPosition},
- R"(1:2 error: @builtin is not valid for struct declarations)",
+ R"(1:2 error: '@builtin' is not valid for 'struct' declarations)",
},
TestParams{
{AttributeKind::kDiagnostic},
- R"(1:2 error: @diagnostic is not valid for struct declarations)",
+ R"(1:2 error: '@diagnostic' is not valid for 'struct' declarations)",
},
TestParams{
{AttributeKind::kColor},
- R"(1:2 error: @color is not valid for struct declarations)",
+ R"(1:2 error: '@color' is not valid for 'struct' declarations)",
},
TestParams{
{AttributeKind::kGroup},
- R"(1:2 error: @group is not valid for struct declarations)",
+ R"(1:2 error: '@group' is not valid for 'struct' declarations)",
},
TestParams{
{AttributeKind::kId},
- R"(1:2 error: @id is not valid for struct declarations)",
+ R"(1:2 error: '@id' is not valid for 'struct' declarations)",
},
TestParams{
{AttributeKind::kInterpolate},
- R"(1:2 error: @interpolate is not valid for struct declarations)",
+ R"(1:2 error: '@interpolate' is not valid for 'struct' declarations)",
},
TestParams{
{AttributeKind::kInvariant},
- R"(1:2 error: @invariant is not valid for struct declarations)",
+ R"(1:2 error: '@invariant' is not valid for 'struct' declarations)",
},
TestParams{
{AttributeKind::kLocation},
- R"(1:2 error: @location is not valid for struct declarations)",
+ R"(1:2 error: '@location' is not valid for 'struct' declarations)",
},
TestParams{
{AttributeKind::kMustUse},
- R"(1:2 error: @must_use is not valid for struct declarations)",
+ R"(1:2 error: '@must_use' is not valid for 'struct' declarations)",
},
TestParams{
{AttributeKind::kOffset},
- R"(1:2 error: @offset is not valid for struct declarations)",
+ R"(1:2 error: '@offset' is not valid for 'struct' declarations)",
},
TestParams{
{AttributeKind::kSize},
- R"(1:2 error: @size is not valid for struct declarations)",
+ R"(1:2 error: '@size' is not valid for 'struct' declarations)",
},
TestParams{
{AttributeKind::kStageCompute},
- R"(1:2 error: @stage is not valid for struct declarations)",
+ R"(1:2 error: '@stage' is not valid for 'struct' declarations)",
},
TestParams{
{AttributeKind::kStride},
- R"(1:2 error: @stride is not valid for struct declarations)",
+ R"(1:2 error: '@stride' is not valid for 'struct' declarations)",
},
TestParams{
{AttributeKind::kWorkgroupSize},
- R"(1:2 error: @workgroup_size is not valid for struct declarations)",
+ R"(1:2 error: '@workgroup_size' is not valid for 'struct' declarations)",
},
TestParams{
{AttributeKind::kBinding, AttributeKind::kGroup},
- R"(1:2 error: @binding is not valid for struct declarations)",
+ R"(1:2 error: '@binding' is not valid for 'struct' declarations)",
}));
using StructMemberAttributeTest = TestWithParams;
@@ -1364,94 +1364,95 @@
CHECK();
}
-INSTANTIATE_TEST_SUITE_P(ResolverAttributeValidationTest,
- StructMemberAttributeTest,
- testing::Values(
- TestParams{
- {AttributeKind::kAlign},
- Pass,
- },
- TestParams{
- {AttributeKind::kBinding},
- R"(1:2 error: @binding is not valid for struct members)",
- },
- TestParams{
- {AttributeKind::kBlendSrc},
- R"(1:2 error: @blend_src can only be used with @location(0))",
- },
- TestParams{
- {AttributeKind::kBuiltinPosition},
- Pass,
- },
- TestParams{
- {AttributeKind::kColor},
- Pass,
- },
- TestParams{
- {AttributeKind::kDiagnostic},
- R"(1:2 error: @diagnostic is not valid for struct members)",
- },
- TestParams{
- {AttributeKind::kGroup},
- R"(1:2 error: @group is not valid for struct members)",
- },
- TestParams{
- {AttributeKind::kId},
- R"(1:2 error: @id is not valid for struct members)",
- },
- TestParams{
- {AttributeKind::kInterpolate},
- R"(1:2 error: @interpolate can only be used with @location)",
- },
- TestParams{
- {AttributeKind::kInterpolate, AttributeKind::kLocation},
- Pass,
- },
- TestParams{
- {AttributeKind::kInvariant},
- R"(1:2 error: @invariant must be applied to a position builtin)",
- },
- TestParams{
- {AttributeKind::kInvariant, AttributeKind::kBuiltinPosition},
- Pass,
- },
- TestParams{
- {AttributeKind::kLocation},
- Pass,
- },
- TestParams{
- {AttributeKind::kMustUse},
- R"(1:2 error: @must_use is not valid for struct members)",
- },
- TestParams{
- {AttributeKind::kOffset},
- Pass,
- },
- TestParams{
- {AttributeKind::kSize},
- Pass,
- },
- TestParams{
- {AttributeKind::kStageCompute},
- R"(1:2 error: @stage is not valid for struct members)",
- },
- TestParams{
- {AttributeKind::kStride},
- R"(1:2 error: @stride is not valid for struct members)",
- },
- TestParams{
- {AttributeKind::kWorkgroupSize},
- R"(1:2 error: @workgroup_size is not valid for struct members)",
- },
- TestParams{
- {AttributeKind::kBinding, AttributeKind::kGroup},
- R"(1:2 error: @binding is not valid for struct members)",
- },
- TestParams{
- {AttributeKind::kAlign, AttributeKind::kAlign},
- R"(3:4 error: duplicate align attribute
+INSTANTIATE_TEST_SUITE_P(
+ ResolverAttributeValidationTest,
+ StructMemberAttributeTest,
+ testing::Values(
+ TestParams{
+ {AttributeKind::kAlign},
+ Pass,
+ },
+ TestParams{
+ {AttributeKind::kBinding},
+ R"(1:2 error: '@binding' is not valid for 'struct' members)",
+ },
+ TestParams{
+ {AttributeKind::kBlendSrc},
+ R"(1:2 error: '@blend_src' can only be used with '@location(0)')",
+ },
+ TestParams{
+ {AttributeKind::kBuiltinPosition},
+ Pass,
+ },
+ TestParams{
+ {AttributeKind::kColor},
+ Pass,
+ },
+ TestParams{
+ {AttributeKind::kDiagnostic},
+ R"(1:2 error: '@diagnostic' is not valid for 'struct' members)",
+ },
+ TestParams{
+ {AttributeKind::kGroup},
+ R"(1:2 error: '@group' is not valid for 'struct' members)",
+ },
+ TestParams{
+ {AttributeKind::kId},
+ R"(1:2 error: '@id' is not valid for 'struct' members)",
+ },
+ TestParams{
+ {AttributeKind::kInterpolate},
+ R"(1:2 error: '@interpolate' can only be used with '@location')",
+ },
+ TestParams{
+ {AttributeKind::kInterpolate, AttributeKind::kLocation},
+ Pass,
+ },
+ TestParams{
+ {AttributeKind::kInvariant},
+ R"(1:2 error: '@invariant' must be applied to a position builtin)",
+ },
+ TestParams{
+ {AttributeKind::kInvariant, AttributeKind::kBuiltinPosition},
+ Pass,
+ },
+ TestParams{
+ {AttributeKind::kLocation},
+ Pass,
+ },
+ TestParams{
+ {AttributeKind::kMustUse},
+ R"(1:2 error: '@must_use' is not valid for 'struct' members)",
+ },
+ TestParams{
+ {AttributeKind::kOffset},
+ Pass,
+ },
+ TestParams{
+ {AttributeKind::kSize},
+ Pass,
+ },
+ TestParams{
+ {AttributeKind::kStageCompute},
+ R"(1:2 error: '@stage' is not valid for 'struct' members)",
+ },
+ TestParams{
+ {AttributeKind::kStride},
+ R"(1:2 error: '@stride' is not valid for 'struct' members)",
+ },
+ TestParams{
+ {AttributeKind::kWorkgroupSize},
+ R"(1:2 error: '@workgroup_size' is not valid for 'struct' members)",
+ },
+ TestParams{
+ {AttributeKind::kBinding, AttributeKind::kGroup},
+ R"(1:2 error: '@binding' is not valid for 'struct' members)",
+ },
+ TestParams{
+ {AttributeKind::kAlign, AttributeKind::kAlign},
+ R"(3:4 error: duplicate align attribute
1:2 note: first attribute declared here)",
- }));
+ }));
TEST_F(StructMemberAttributeTest, Align_Attribute_Const) {
GlobalConst("val", ty.i32(), Expr(1_i));
@@ -1467,7 +1468,7 @@
Vector{Member("a", ty.f32(), Vector{MemberAlign(Source{{12, 34}}, "val")})});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(12:34 error: @align value must be a positive, power-of-two integer)");
+ R"(12:34 error: '@align' value must be a positive, power-of-two integer)");
}
TEST_F(StructMemberAttributeTest, Align_Attribute_ConstPowerOfTwo) {
@@ -1477,7 +1478,7 @@
Vector{Member("a", ty.f32(), Vector{MemberAlign(Source{{12, 34}}, "val")})});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(12:34 error: @align value must be a positive, power-of-two integer)");
+ R"(12:34 error: '@align' value must be a positive, power-of-two integer)");
}
TEST_F(StructMemberAttributeTest, Align_Attribute_ConstF32) {
@@ -1486,7 +1487,7 @@
Structure("mystruct",
Vector{Member("a", ty.f32(), Vector{MemberAlign(Source{{12, 34}}, "val")})});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: @align must be an i32 or u32 value)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@align' value must be an 'i32' or 'u32')");
}
TEST_F(StructMemberAttributeTest, Align_Attribute_ConstU32) {
@@ -1511,7 +1512,7 @@
Structure("mystruct",
Vector{Member("a", ty.f32(), Vector{MemberAlign(Source{{12, 34}}, "val")})});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: @align must be an i32 or u32 value)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@align' value must be an 'i32' or 'u32')");
}
TEST_F(StructMemberAttributeTest, Align_Attribute_Var) {
@@ -1550,7 +1551,7 @@
Structure("mystruct",
Vector{Member("a", ty.f32(), Vector{MemberSize(Source{{12, 34}}, "val")})});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: @size must be a positive integer)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@size' value must be a positive integer)");
}
TEST_F(StructMemberAttributeTest, Size_Attribute_ConstF32) {
@@ -1559,7 +1560,7 @@
Structure("mystruct",
Vector{Member("a", ty.f32(), Vector{MemberSize(Source{{12, 34}}, "val")})});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: @size must be an i32 or u32 value)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@size' value must be an 'i32' or 'u32')");
}
TEST_F(StructMemberAttributeTest, Size_Attribute_ConstU32) {
@@ -1584,7 +1585,7 @@
Structure("mystruct",
Vector{Member("a", ty.f32(), Vector{MemberSize(Source{{12, 34}}, "val")})});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: @size must be an i32 or u32 value)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@size' value must be an 'i32' or 'u32')");
}
TEST_F(StructMemberAttributeTest, Size_Attribute_Var) {
@@ -1620,7 +1621,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(12:34 error: @size can only be applied to members where the member's type size can be fully determined at shader creation time)");
+ R"(12:34 error: '@size' can only be applied to members where the member's type size can be fully determined at shader creation time)");
}
} // namespace StructAndStructMemberTests
@@ -1641,59 +1642,59 @@
testing::Values(
TestParams{
{AttributeKind::kAlign},
- R"(1:2 error: @align is not valid for array types)",
+ R"(1:2 error: '@align' is not valid for 'array' types)",
},
TestParams{
{AttributeKind::kBinding},
- R"(1:2 error: @binding is not valid for array types)",
+ R"(1:2 error: '@binding' is not valid for 'array' types)",
},
TestParams{
{AttributeKind::kBlendSrc},
- R"(1:2 error: @blend_src is not valid for array types)",
+ R"(1:2 error: '@blend_src' is not valid for 'array' types)",
},
TestParams{
{AttributeKind::kBuiltinPosition},
- R"(1:2 error: @builtin is not valid for array types)",
+ R"(1:2 error: '@builtin' is not valid for 'array' types)",
},
TestParams{
{AttributeKind::kDiagnostic},
- R"(1:2 error: @diagnostic is not valid for array types)",
+ R"(1:2 error: '@diagnostic' is not valid for 'array' types)",
},
TestParams{
{AttributeKind::kGroup},
- R"(1:2 error: @group is not valid for array types)",
+ R"(1:2 error: '@group' is not valid for 'array' types)",
},
TestParams{
{AttributeKind::kId},
- R"(1:2 error: @id is not valid for array types)",
+ R"(1:2 error: '@id' is not valid for 'array' types)",
},
TestParams{
{AttributeKind::kInterpolate},
- R"(1:2 error: @interpolate is not valid for array types)",
+ R"(1:2 error: '@interpolate' is not valid for 'array' types)",
},
TestParams{
{AttributeKind::kInvariant},
- R"(1:2 error: @invariant is not valid for array types)",
+ R"(1:2 error: '@invariant' is not valid for 'array' types)",
},
TestParams{
{AttributeKind::kLocation},
- R"(1:2 error: @location is not valid for array types)",
+ R"(1:2 error: '@location' is not valid for 'array' types)",
},
TestParams{
{AttributeKind::kMustUse},
- R"(1:2 error: @must_use is not valid for array types)",
+ R"(1:2 error: '@must_use' is not valid for 'array' types)",
},
TestParams{
{AttributeKind::kOffset},
- R"(1:2 error: @offset is not valid for array types)",
+ R"(1:2 error: '@offset' is not valid for 'array' types)",
},
TestParams{
{AttributeKind::kSize},
- R"(1:2 error: @size is not valid for array types)",
+ R"(1:2 error: '@size' is not valid for 'array' types)",
},
TestParams{
{AttributeKind::kStageCompute},
- R"(1:2 error: @stage is not valid for array types)",
+ R"(1:2 error: '@stage' is not valid for 'array' types)",
},
TestParams{
{AttributeKind::kStride},
@@ -1701,11 +1702,11 @@
},
TestParams{
{AttributeKind::kWorkgroupSize},
- R"(1:2 error: @workgroup_size is not valid for array types)",
+ R"(1:2 error: '@workgroup_size' is not valid for 'array' types)",
},
TestParams{
{AttributeKind::kBinding, AttributeKind::kGroup},
- R"(1:2 error: @binding is not valid for array types)",
+ R"(1:2 error: '@binding' is not valid for 'array' types)",
},
TestParams{
{AttributeKind::kStride, AttributeKind::kStride},
@@ -1732,67 +1733,67 @@
testing::Values(
TestParams{
{AttributeKind::kAlign},
- R"(1:2 error: @align is not valid for module-scope 'var')",
+ R"(1:2 error: '@align' is not valid for module-scope 'var')",
},
TestParams{
{AttributeKind::kBinding},
- R"(9:9 error: resource variables require @group and @binding attributes)",
+ R"(9:9 error: resource variables require '@group' and '@binding' attributes)",
},
TestParams{
{AttributeKind::kBlendSrc},
- R"(1:2 error: @blend_src is not valid for module-scope 'var')",
+ R"(1:2 error: '@blend_src' is not valid for module-scope 'var')",
},
TestParams{
{AttributeKind::kBuiltinPosition},
- R"(1:2 error: @builtin is not valid for module-scope 'var')",
+ R"(1:2 error: '@builtin' is not valid for module-scope 'var')",
},
TestParams{
{AttributeKind::kDiagnostic},
- R"(1:2 error: @diagnostic is not valid for module-scope 'var')",
+ R"(1:2 error: '@diagnostic' is not valid for module-scope 'var')",
},
TestParams{
{AttributeKind::kGroup},
- R"(9:9 error: resource variables require @group and @binding attributes)",
+ R"(9:9 error: resource variables require '@group' and '@binding' attributes)",
},
TestParams{
{AttributeKind::kId},
- R"(1:2 error: @id is not valid for module-scope 'var')",
+ R"(1:2 error: '@id' is not valid for module-scope 'var')",
},
TestParams{
{AttributeKind::kInterpolate},
- R"(1:2 error: @interpolate is not valid for module-scope 'var')",
+ R"(1:2 error: '@interpolate' is not valid for module-scope 'var')",
},
TestParams{
{AttributeKind::kInvariant},
- R"(1:2 error: @invariant is not valid for module-scope 'var')",
+ R"(1:2 error: '@invariant' is not valid for module-scope 'var')",
},
TestParams{
{AttributeKind::kLocation},
- R"(1:2 error: @location is not valid for module-scope 'var')",
+ R"(1:2 error: '@location' is not valid for module-scope 'var')",
},
TestParams{
{AttributeKind::kMustUse},
- R"(1:2 error: @must_use is not valid for module-scope 'var')",
+ R"(1:2 error: '@must_use' is not valid for module-scope 'var')",
},
TestParams{
{AttributeKind::kOffset},
- R"(1:2 error: @offset is not valid for module-scope 'var')",
+ R"(1:2 error: '@offset' is not valid for module-scope 'var')",
},
TestParams{
{AttributeKind::kSize},
- R"(1:2 error: @size is not valid for module-scope 'var')",
+ R"(1:2 error: '@size' is not valid for module-scope 'var')",
},
TestParams{
{AttributeKind::kStageCompute},
- R"(1:2 error: @stage is not valid for module-scope 'var')",
+ R"(1:2 error: '@stage' is not valid for module-scope 'var')",
},
TestParams{
{AttributeKind::kStride},
- R"(1:2 error: @stride is not valid for module-scope 'var')",
+ R"(1:2 error: '@stride' is not valid for module-scope 'var')",
},
TestParams{
{AttributeKind::kWorkgroupSize},
- R"(1:2 error: @workgroup_size is not valid for module-scope 'var')",
+ R"(1:2 error: '@workgroup_size' is not valid for module-scope 'var')",
},
TestParams{
{AttributeKind::kBinding, AttributeKind::kGroup},
@@ -1810,7 +1811,7 @@
WrapInFunction(v);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: @binding is not valid for function-scope 'var'");
+ EXPECT_EQ(r()->error(), "12:34 error: '@binding' is not valid for function-scope 'var'");
}
TEST_F(VariableAttributeTest, LocalLet) {
@@ -1819,7 +1820,7 @@
WrapInFunction(v);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: @binding is not valid for 'let' declaration");
+ EXPECT_EQ(r()->error(), "12:34 error: '@binding' is not valid for 'let' declaration");
}
using ConstantAttributeTest = TestWithParams;
@@ -1836,71 +1837,71 @@
testing::Values(
TestParams{
{AttributeKind::kAlign},
- R"(1:2 error: @align is not valid for 'const' declaration)",
+ R"(1:2 error: '@align' is not valid for 'const' declaration)",
},
TestParams{
{AttributeKind::kBinding},
- R"(1:2 error: @binding is not valid for 'const' declaration)",
+ R"(1:2 error: '@binding' is not valid for 'const' declaration)",
},
TestParams{
{AttributeKind::kBlendSrc},
- R"(1:2 error: @blend_src is not valid for 'const' declaration)",
+ R"(1:2 error: '@blend_src' is not valid for 'const' declaration)",
},
TestParams{
{AttributeKind::kBuiltinPosition},
- R"(1:2 error: @builtin is not valid for 'const' declaration)",
+ R"(1:2 error: '@builtin' is not valid for 'const' declaration)",
},
TestParams{
{AttributeKind::kDiagnostic},
- R"(1:2 error: @diagnostic is not valid for 'const' declaration)",
+ R"(1:2 error: '@diagnostic' is not valid for 'const' declaration)",
},
TestParams{
{AttributeKind::kGroup},
- R"(1:2 error: @group is not valid for 'const' declaration)",
+ R"(1:2 error: '@group' is not valid for 'const' declaration)",
},
TestParams{
{AttributeKind::kId},
- R"(1:2 error: @id is not valid for 'const' declaration)",
+ R"(1:2 error: '@id' is not valid for 'const' declaration)",
},
TestParams{
{AttributeKind::kInterpolate},
- R"(1:2 error: @interpolate is not valid for 'const' declaration)",
+ R"(1:2 error: '@interpolate' is not valid for 'const' declaration)",
},
TestParams{
{AttributeKind::kInvariant},
- R"(1:2 error: @invariant is not valid for 'const' declaration)",
+ R"(1:2 error: '@invariant' is not valid for 'const' declaration)",
},
TestParams{
{AttributeKind::kLocation},
- R"(1:2 error: @location is not valid for 'const' declaration)",
+ R"(1:2 error: '@location' is not valid for 'const' declaration)",
},
TestParams{
{AttributeKind::kMustUse},
- R"(1:2 error: @must_use is not valid for 'const' declaration)",
+ R"(1:2 error: '@must_use' is not valid for 'const' declaration)",
},
TestParams{
{AttributeKind::kOffset},
- R"(1:2 error: @offset is not valid for 'const' declaration)",
+ R"(1:2 error: '@offset' is not valid for 'const' declaration)",
},
TestParams{
{AttributeKind::kSize},
- R"(1:2 error: @size is not valid for 'const' declaration)",
+ R"(1:2 error: '@size' is not valid for 'const' declaration)",
},
TestParams{
{AttributeKind::kStageCompute},
- R"(1:2 error: @stage is not valid for 'const' declaration)",
+ R"(1:2 error: '@stage' is not valid for 'const' declaration)",
},
TestParams{
{AttributeKind::kStride},
- R"(1:2 error: @stride is not valid for 'const' declaration)",
+ R"(1:2 error: '@stride' is not valid for 'const' declaration)",
},
TestParams{
{AttributeKind::kWorkgroupSize},
- R"(1:2 error: @workgroup_size is not valid for 'const' declaration)",
+ R"(1:2 error: '@workgroup_size' is not valid for 'const' declaration)",
},
TestParams{
{AttributeKind::kBinding, AttributeKind::kGroup},
- R"(1:2 error: @binding is not valid for 'const' declaration)",
+ R"(1:2 error: '@binding' is not valid for 'const' declaration)",
}));
using OverrideAttributeTest = TestWithParams;
@@ -1917,27 +1918,27 @@
testing::Values(
TestParams{
{AttributeKind::kAlign},
- R"(1:2 error: @align is not valid for 'override' declaration)",
+ R"(1:2 error: '@align' is not valid for 'override' declaration)",
},
TestParams{
{AttributeKind::kBinding},
- R"(1:2 error: @binding is not valid for 'override' declaration)",
+ R"(1:2 error: '@binding' is not valid for 'override' declaration)",
},
TestParams{
{AttributeKind::kBlendSrc},
- R"(1:2 error: @blend_src is not valid for 'override' declaration)",
+ R"(1:2 error: '@blend_src' is not valid for 'override' declaration)",
},
TestParams{
{AttributeKind::kBuiltinPosition},
- R"(1:2 error: @builtin is not valid for 'override' declaration)",
+ R"(1:2 error: '@builtin' is not valid for 'override' declaration)",
},
TestParams{
{AttributeKind::kDiagnostic},
- R"(1:2 error: @diagnostic is not valid for 'override' declaration)",
+ R"(1:2 error: '@diagnostic' is not valid for 'override' declaration)",
},
TestParams{
{AttributeKind::kGroup},
- R"(1:2 error: @group is not valid for 'override' declaration)",
+ R"(1:2 error: '@group' is not valid for 'override' declaration)",
},
TestParams{
{AttributeKind::kId},
@@ -1945,43 +1946,43 @@
},
TestParams{
{AttributeKind::kInterpolate},
- R"(1:2 error: @interpolate is not valid for 'override' declaration)",
+ R"(1:2 error: '@interpolate' is not valid for 'override' declaration)",
},
TestParams{
{AttributeKind::kInvariant},
- R"(1:2 error: @invariant is not valid for 'override' declaration)",
+ R"(1:2 error: '@invariant' is not valid for 'override' declaration)",
},
TestParams{
{AttributeKind::kLocation},
- R"(1:2 error: @location is not valid for 'override' declaration)",
+ R"(1:2 error: '@location' is not valid for 'override' declaration)",
},
TestParams{
{AttributeKind::kMustUse},
- R"(1:2 error: @must_use is not valid for 'override' declaration)",
+ R"(1:2 error: '@must_use' is not valid for 'override' declaration)",
},
TestParams{
{AttributeKind::kOffset},
- R"(1:2 error: @offset is not valid for 'override' declaration)",
+ R"(1:2 error: '@offset' is not valid for 'override' declaration)",
},
TestParams{
{AttributeKind::kSize},
- R"(1:2 error: @size is not valid for 'override' declaration)",
+ R"(1:2 error: '@size' is not valid for 'override' declaration)",
},
TestParams{
{AttributeKind::kStageCompute},
- R"(1:2 error: @stage is not valid for 'override' declaration)",
+ R"(1:2 error: '@stage' is not valid for 'override' declaration)",
},
TestParams{
{AttributeKind::kStride},
- R"(1:2 error: @stride is not valid for 'override' declaration)",
+ R"(1:2 error: '@stride' is not valid for 'override' declaration)",
},
TestParams{
{AttributeKind::kWorkgroupSize},
- R"(1:2 error: @workgroup_size is not valid for 'override' declaration)",
+ R"(1:2 error: '@workgroup_size' is not valid for 'override' declaration)",
},
TestParams{
{AttributeKind::kBinding, AttributeKind::kGroup},
- R"(1:2 error: @binding is not valid for 'override' declaration)",
+ R"(1:2 error: '@binding' is not valid for 'override' declaration)",
},
TestParams{
{AttributeKind::kId, AttributeKind::kId},
@@ -2011,7 +2012,7 @@
}
INSTANTIATE_TEST_SUITE_P(ResolverAttributeValidationTest,
SwitchBodyAttributeTest,
- testing::ValuesIn(OnlyDiagnosticValidFor("switch body")));
+ testing::ValuesIn(OnlyDiagnosticValidFor("'switch' body")));
using IfStatementAttributeTest = TestWithParams;
TEST_P(IfStatementAttributeTest, IsValid) {
@@ -2278,7 +2279,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(12:34 error: resource variables require @group and @binding attributes)");
+ R"(12:34 error: resource variables require '@group' and '@binding' attributes)");
}
TEST_F(ResourceAttributeTest, StorageBufferMissingBinding) {
@@ -2289,7 +2290,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(12:34 error: resource variables require @group and @binding attributes)");
+ R"(12:34 error: resource variables require '@group' and '@binding' attributes)");
}
TEST_F(ResourceAttributeTest, TextureMissingBinding) {
@@ -2297,7 +2298,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(12:34 error: resource variables require @group and @binding attributes)");
+ R"(12:34 error: resource variables require '@group' and '@binding' attributes)");
}
TEST_F(ResourceAttributeTest, SamplerMissingBinding) {
@@ -2305,7 +2306,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(12:34 error: resource variables require @group and @binding attributes)");
+ R"(12:34 error: resource variables require '@group' and '@binding' attributes)");
}
TEST_F(ResourceAttributeTest, BindingPairMissingBinding) {
@@ -2313,7 +2314,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(12:34 error: resource variables require @group and @binding attributes)");
+ R"(12:34 error: resource variables require '@group' and '@binding' attributes)");
}
TEST_F(ResourceAttributeTest, BindingPairMissingGroup) {
@@ -2321,7 +2322,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(12:34 error: resource variables require @group and @binding attributes)");
+ R"(12:34 error: resource variables require '@group' and '@binding' attributes)");
}
TEST_F(ResourceAttributeTest, BindingPointUsedTwiceByEntryPoint) {
@@ -2346,7 +2347,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(56:78 error: entry point 'F' references multiple variables that use the same resource binding @group(2), @binding(1)
+ R"(56:78 error: entry point 'F' references multiple variables that use the same resource binding '@group(2)', '@binding(1)'
12:34 note: first resource binding usage declared here)");
}
@@ -2383,8 +2384,9 @@
Group(2_a));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- R"(12:34 error: non-resource variables must not have @group or @binding attributes)");
+ EXPECT_EQ(
+ r()->error(),
+ R"(12:34 error: non-resource variables must not have '@group' or '@binding' attributes)");
}
} // namespace
@@ -2401,7 +2403,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: @workgroup_size is only valid for compute stages)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@workgroup_size' is only valid for compute stages)");
}
TEST_F(WorkgroupAttribute, NotAComputeShader) {
@@ -2412,7 +2414,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: @workgroup_size is only valid for compute stages)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@workgroup_size' is only valid for compute stages)");
}
TEST_F(WorkgroupAttribute, DuplicateAttribute) {
@@ -2560,7 +2562,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(12:34 error: integral user-defined fragment inputs must have a flat interpolation attribute)");
+ R"(12:34 error: integral user-defined fragment inputs must have a '@interpolate(flat)' attribute)");
}
TEST_F(InterpolateTest, VertexOutput_Integer_MissingFlatInterpolation) {
@@ -2580,7 +2582,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(12:34 error: integral user-defined vertex outputs must have a flat interpolation attribute
+ R"(12:34 error: integral user-defined vertex outputs must have a '@interpolate(flat)' attribute
note: while analyzing entry point 'main')");
}
@@ -2628,7 +2630,7 @@
Binding(Source{{12, 34}}, -2_i), Group(1_i));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: @binding value must be non-negative)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@binding' value must be non-negative)");
}
TEST_F(GroupAndBindingTest, Binding_F32) {
@@ -2636,7 +2638,7 @@
Binding(Source{{12, 34}}, 2.0_f), Group(1_u));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: @binding must be an i32 or u32 value)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@binding' must be an 'i32' or 'u32' value)");
}
TEST_F(GroupAndBindingTest, Binding_AFloat) {
@@ -2644,7 +2646,7 @@
Binding(Source{{12, 34}}, 2.0_a), Group(1_u));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: @binding must be an i32 or u32 value)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@binding' must be an 'i32' or 'u32' value)");
}
TEST_F(GroupAndBindingTest, Group_NonConstant) {
@@ -2662,7 +2664,7 @@
Group(Source{{12, 34}}, -1_i));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: @group value must be non-negative)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@group' value must be non-negative)");
}
TEST_F(GroupAndBindingTest, Group_F32) {
@@ -2670,7 +2672,7 @@
Group(Source{{12, 34}}, 1.0_f));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: @group must be an i32 or u32 value)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@group' must be an 'i32' or 'u32' value)");
}
TEST_F(GroupAndBindingTest, Group_AFloat) {
@@ -2678,7 +2680,7 @@
Group(Source{{12, 34}}, 1.0_a));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: @group must be an i32 or u32 value)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@group' must be an 'i32' or 'u32' value)");
}
using IdTest = ResolverTest;
@@ -2709,19 +2711,19 @@
TEST_F(IdTest, Negative) {
Override("val", ty.f32(), Vector{Id(Source{{12, 34}}, -1_i)});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: @id value must be non-negative)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@id' value must be non-negative)");
}
TEST_F(IdTest, F32) {
Override("val", ty.f32(), Vector{Id(Source{{12, 34}}, 1_f)});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: @id must be an i32 or u32 value)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@id' must be an 'i32' or 'u32' value)");
}
TEST_F(IdTest, AFloat) {
Override("val", ty.f32(), Vector{Id(Source{{12, 34}}, 1.0_a)});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: @id must be an i32 or u32 value)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@id' must be an 'i32' or 'u32' value)");
}
enum class LocationAttributeType {
@@ -2795,19 +2797,19 @@
TEST_P(LocationTest, Negative) {
Build(Expr(-1_a));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: @location value must be non-negative)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@location' value must be non-negative)");
}
TEST_P(LocationTest, F32) {
Build(Expr(1_f));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: @location must be an i32 or u32 value)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@location' must be an 'i32' or 'u32' value)");
}
TEST_P(LocationTest, AFloat) {
Build(Expr(1.0_a));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: @location must be an i32 or u32 value)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@location' must be an 'i32' or 'u32' value)");
}
INSTANTIATE_TEST_SUITE_P(LocationTest,
diff --git a/src/tint/lang/wgsl/resolver/builtin_validation_test.cc b/src/tint/lang/wgsl/resolver/builtin_validation_test.cc
index a6ff7e1..0c063d8 100644
--- a/src/tint/lang/wgsl/resolver/builtin_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/builtin_validation_test.cc
@@ -572,7 +572,7 @@
EXPECT_FALSE(resolver.Resolve());
EXPECT_EQ(resolver.error(),
"12:34 error: built-in function 'dot4I8Packed' requires the "
- "packed_4x8_integer_dot_product language feature, which is not allowed in the "
+ "'packed_4x8_integer_dot_product' language feature, which is not allowed in the "
"current environment");
}
@@ -601,7 +601,7 @@
EXPECT_FALSE(resolver.Resolve());
EXPECT_EQ(resolver.error(),
"12:34 error: built-in function 'dot4U8Packed' requires the "
- "packed_4x8_integer_dot_product language feature, which is not allowed in the "
+ "'packed_4x8_integer_dot_product' language feature, which is not allowed in the "
"current environment");
}
@@ -628,7 +628,7 @@
EXPECT_FALSE(resolver.Resolve());
EXPECT_EQ(resolver.error(),
"12:34 error: built-in function 'pack4xI8' requires the "
- "packed_4x8_integer_dot_product language feature, which is not allowed in the "
+ "'packed_4x8_integer_dot_product' language feature, which is not allowed in the "
"current environment");
}
@@ -655,7 +655,7 @@
EXPECT_FALSE(resolver.Resolve());
EXPECT_EQ(resolver.error(),
"12:34 error: built-in function 'pack4xU8' requires the "
- "packed_4x8_integer_dot_product language feature, which is not allowed in the "
+ "'packed_4x8_integer_dot_product' language feature, which is not allowed in the "
"current environment");
}
@@ -682,7 +682,7 @@
EXPECT_FALSE(resolver.Resolve());
EXPECT_EQ(resolver.error(),
"12:34 error: built-in function 'pack4xI8Clamp' requires the "
- "packed_4x8_integer_dot_product language feature, which is not allowed in the "
+ "'packed_4x8_integer_dot_product' language feature, which is not allowed in the "
"current environment");
}
@@ -709,7 +709,7 @@
EXPECT_FALSE(resolver.Resolve());
EXPECT_EQ(resolver.error(),
"12:34 error: built-in function 'pack4xU8Clamp' requires the "
- "packed_4x8_integer_dot_product language feature, which is not allowed in the "
+ "'packed_4x8_integer_dot_product' language feature, which is not allowed in the "
"current environment");
}
@@ -736,7 +736,7 @@
EXPECT_FALSE(resolver.Resolve());
EXPECT_EQ(resolver.error(),
"12:34 error: built-in function 'unpack4xI8' requires the "
- "packed_4x8_integer_dot_product language feature, which is not allowed in the "
+ "'packed_4x8_integer_dot_product' language feature, which is not allowed in the "
"current environment");
}
@@ -763,7 +763,7 @@
EXPECT_FALSE(resolver.Resolve());
EXPECT_EQ(resolver.error(),
"12:34 error: built-in function 'unpack4xU8' requires the "
- "packed_4x8_integer_dot_product language feature, which is not allowed in the "
+ "'packed_4x8_integer_dot_product' language feature, which is not allowed in the "
"current environment");
}
@@ -990,10 +990,9 @@
Resolver resolver{this, wgsl::AllowedFeatures{}};
EXPECT_FALSE(resolver.Resolve());
- EXPECT_EQ(resolver.error(),
- "12:34 error: built-in function 'textureBarrier' requires the "
- "readonly_and_readwrite_storage_textures language feature, which is not allowed in "
- "the current environment");
+ EXPECT_EQ(
+ resolver.error(),
+ R"(12:34 error: built-in function 'textureBarrier' requires the 'readonly_and_readwrite_storage_textures' language feature, which is not allowed in the current environment)");
}
} // namespace
diff --git a/src/tint/lang/wgsl/resolver/builtins_validation_test.cc b/src/tint/lang/wgsl/resolver/builtins_validation_test.cc
index 616161d..c108ab8 100644
--- a/src/tint/lang/wgsl/resolver/builtins_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/builtins_validation_test.cc
@@ -146,8 +146,8 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
} else {
StringStream err;
- err << "12:34 error: @builtin(" << params.builtin << ")";
- err << " cannot be used for " << params.stage << " shader input";
+ err << "12:34 error: '@builtin(" << params.builtin << ")' cannot be used for "
+ << params.stage << " shader input";
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), err.str());
}
@@ -180,7 +180,7 @@
});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: @builtin(frag_depth) cannot be used for fragment shader input");
+ "12:34 error: '@builtin(frag_depth)' cannot be used for fragment shader input");
}
TEST_F(ResolverBuiltinsValidationTest, FragDepthIsInputStruct_Fail) {
@@ -214,7 +214,7 @@
});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(12:34 error: @builtin(frag_depth) cannot be used for fragment shader input
+ R"(12:34 error: '@builtin(frag_depth)' cannot be used for fragment shader input
note: while analyzing entry point 'fragShader')");
}
@@ -271,7 +271,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: store type of @builtin(position) must be 'vec4<f32>'");
+ EXPECT_EQ(r()->error(), "12:34 error: store type of '@builtin(position)' must be 'vec4<f32>'");
}
TEST_F(ResolverBuiltinsValidationTest, PositionNotF32_ReturnType_Fail) {
@@ -287,7 +287,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: store type of @builtin(position) must be 'vec4<f32>'");
+ EXPECT_EQ(r()->error(), "12:34 error: store type of '@builtin(position)' must be 'vec4<f32>'");
}
TEST_F(ResolverBuiltinsValidationTest, PositionIsVec4h_Fail) {
@@ -304,7 +304,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: store type of @builtin(position) must be 'vec4<f32>'");
+ EXPECT_EQ(r()->error(), "12:34 error: store type of '@builtin(position)' must be 'vec4<f32>'");
}
TEST_F(ResolverBuiltinsValidationTest, FragDepthNotF32_Struct_Fail) {
@@ -333,7 +333,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: store type of @builtin(frag_depth) must be 'f32'");
+ EXPECT_EQ(r()->error(), "12:34 error: store type of '@builtin(frag_depth)' must be 'f32'");
}
TEST_F(ResolverBuiltinsValidationTest, SampleMaskNotU32_Struct_Fail) {
@@ -362,7 +362,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: store type of @builtin(sample_mask) must be 'u32'");
+ EXPECT_EQ(r()->error(), "12:34 error: store type of '@builtin(sample_mask)' must be 'u32'");
}
TEST_F(ResolverBuiltinsValidationTest, SampleMaskNotU32_ReturnType_Fail) {
@@ -377,7 +377,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: store type of @builtin(sample_mask) must be 'u32'");
+ EXPECT_EQ(r()->error(), "12:34 error: store type of '@builtin(sample_mask)' must be 'u32'");
}
TEST_F(ResolverBuiltinsValidationTest, SampleMaskIsNotU32_Fail) {
@@ -403,7 +403,7 @@
Location(0_a),
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: store type of @builtin(sample_mask) must be 'u32'");
+ EXPECT_EQ(r()->error(), "12:34 error: store type of '@builtin(sample_mask)' must be 'u32'");
}
TEST_F(ResolverBuiltinsValidationTest, SampleIndexIsNotU32_Struct_Fail) {
@@ -432,7 +432,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: store type of @builtin(sample_index) must be 'u32'");
+ EXPECT_EQ(r()->error(), "12:34 error: store type of '@builtin(sample_index)' must be 'u32'");
}
TEST_F(ResolverBuiltinsValidationTest, SampleIndexIsNotU32_Fail) {
@@ -458,7 +458,7 @@
Location(0_a),
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: store type of @builtin(sample_index) must be 'u32'");
+ EXPECT_EQ(r()->error(), "12:34 error: store type of '@builtin(sample_index)' must be 'u32'");
}
TEST_F(ResolverBuiltinsValidationTest, PositionIsNotF32_Fail) {
@@ -484,7 +484,7 @@
Location(0_a),
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: store type of @builtin(position) must be 'vec4<f32>'");
+ EXPECT_EQ(r()->error(), "12:34 error: store type of '@builtin(position)' must be 'vec4<f32>'");
}
TEST_F(ResolverBuiltinsValidationTest, FragDepthIsNotF32_Fail) {
@@ -503,7 +503,7 @@
Builtin(Source{{12, 34}}, core::BuiltinValue::kFragDepth),
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: store type of @builtin(frag_depth) must be 'f32'");
+ EXPECT_EQ(r()->error(), "12:34 error: store type of '@builtin(frag_depth)' must be 'f32'");
}
TEST_F(ResolverBuiltinsValidationTest, VertexIndexIsNotU32_Fail) {
@@ -528,7 +528,7 @@
Builtin(core::BuiltinValue::kPosition),
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: store type of @builtin(vertex_index) must be 'u32'");
+ EXPECT_EQ(r()->error(), "12:34 error: store type of '@builtin(vertex_index)' must be 'u32'");
}
TEST_F(ResolverBuiltinsValidationTest, InstanceIndexIsNotU32) {
@@ -553,7 +553,7 @@
Builtin(core::BuiltinValue::kPosition),
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: store type of @builtin(instance_index) must be 'u32'");
+ EXPECT_EQ(r()->error(), "12:34 error: store type of '@builtin(instance_index)' must be 'u32'");
}
TEST_F(ResolverBuiltinsValidationTest, FragmentBuiltin_Pass) {
@@ -673,8 +673,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: store type of @builtin(workgroup_id) must be "
- "'vec3<u32>'");
+ R"(12:34 error: store type of '@builtin(workgroup_id)' must be 'vec3<u32>')");
}
TEST_F(ResolverBuiltinsValidationTest, ComputeBuiltin_NumWorkgroupsNotVec3U32) {
@@ -688,8 +687,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: store type of @builtin(num_workgroups) must be "
- "'vec3<u32>'");
+ R"(12:34 error: store type of '@builtin(num_workgroups)' must be 'vec3<u32>')");
}
TEST_F(ResolverBuiltinsValidationTest, ComputeBuiltin_GlobalInvocationNotVec3U32) {
@@ -703,8 +701,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: store type of @builtin(global_invocation_id) must be "
- "'vec3<u32>'");
+ R"(12:34 error: store type of '@builtin(global_invocation_id)' must be 'vec3<u32>')");
}
TEST_F(ResolverBuiltinsValidationTest, ComputeBuiltin_LocalInvocationIndexNotU32) {
@@ -718,8 +715,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: store type of @builtin(local_invocation_index) must be "
- "'u32'");
+ R"(12:34 error: store type of '@builtin(local_invocation_index)' must be 'u32')");
}
TEST_F(ResolverBuiltinsValidationTest, ComputeBuiltin_LocalInvocationNotVec3U32) {
@@ -733,8 +729,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: store type of @builtin(local_invocation_id) must be "
- "'vec3<u32>'");
+ R"(12:34 error: store type of '@builtin(local_invocation_id)' must be 'vec3<u32>')");
}
TEST_F(ResolverBuiltinsValidationTest, FragmentBuiltinStruct_Pass) {
@@ -800,7 +795,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: store type of @builtin(front_facing) must be 'bool'");
+ EXPECT_EQ(r()->error(), "12:34 error: store type of '@builtin(front_facing)' must be 'bool'");
}
TEST_F(ResolverBuiltinsValidationTest, FrontFacingMemberIsNotBool_Fail) {
@@ -829,7 +824,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: store type of @builtin(front_facing) must be 'bool'");
+ EXPECT_EQ(r()->error(), "12:34 error: store type of '@builtin(front_facing)' must be 'bool'");
}
// TODO(crbug.com/tint/1846): This isn't a validation test, but this sits next to other @builtin
diff --git a/src/tint/lang/wgsl/resolver/call_validation_test.cc b/src/tint/lang/wgsl/resolver/call_validation_test.cc
index 5df9c73..001fb4e 100644
--- a/src/tint/lang/wgsl/resolver/call_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/call_validation_test.cc
@@ -481,7 +481,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(12:34 error: ignoring return value of function 'fn_must_use' annotated with @must_use
+ R"(12:34 error: ignoring return value of function 'fn_must_use' annotated with '@must_use'
56:78 note: function 'fn_must_use' declared here)");
}
diff --git a/src/tint/lang/wgsl/resolver/dual_source_blending_extension_test.cc b/src/tint/lang/wgsl/resolver/dual_source_blending_extension_test.cc
index ab8677e..55c6704 100644
--- a/src/tint/lang/wgsl/resolver/dual_source_blending_extension_test.cc
+++ b/src/tint/lang/wgsl/resolver/dual_source_blending_extension_test.cc
@@ -50,7 +50,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(12:34 error: use of @blend_src requires enabling extension 'chromium_internal_dual_source_blending')");
+ R"(12:34 error: use of '@blend_src' requires enabling extension 'chromium_internal_dual_source_blending')");
}
class DualSourceBlendingExtensionTests : public ResolverTest {
@@ -68,7 +68,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: @location must be an i32 or u32 value");
+ EXPECT_EQ(r()->error(), "12:34 error: '@blend_srci32' or 'u32' value");
}
// Using a floating point number as an index value should fail.
@@ -78,7 +78,7 @@
Vector{Location(0_a), BlendSrc(Source{{12, 34}}, 1.0_a)}),
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: @location must be an i32 or u32 value");
+ EXPECT_EQ(r()->error(), "12:34 error: '@blend_srci32' or 'u32' value");
}
// Using a number less than zero as an index value should fail.
@@ -89,7 +89,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: @blend_src value must be zero or one");
+ EXPECT_EQ(r()->error(), "12:34 error: '@blend_src' value must be zero or one");
}
// Using a number greater than one as an index value should fail.
@@ -100,7 +100,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: @blend_src value must be zero or one");
+ EXPECT_EQ(r()->error(), "12:34 error: '@blend_src' value must be zero or one");
}
// Using an index value at the same location multiple times should fail.
@@ -112,7 +112,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: @location(0) @blend_src(0) appears multiple times");
+ EXPECT_EQ(r()->error(), "12:34 error: '@location(0) @blend_src(0)' appears multiple times");
}
// Using the index attribute without a location attribute should fail.
@@ -123,7 +123,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: @blend_src can only be used with @location(0)");
+ EXPECT_EQ(r()->error(), "12:34 error: '@blend_src' can only be used with '@location(0)'");
}
// Using the index attribute without a location attribute should fail.
@@ -139,7 +139,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: @blend_src can only be used with @location(0)");
+ EXPECT_EQ(r()->error(), "12:34 error: '@blend_src' can only be used with '@location(0)'");
}
// Using an index attribute on a struct member should pass.
@@ -172,7 +172,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: @blend_src can only be used with @location(0)");
+ EXPECT_EQ(r()->error(), "12:34 error: '@blend_src' can only be used with '@location(0)'");
}
// Using the index attribute with a non-zero location should fail.
@@ -188,7 +188,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: @blend_src can only be used with @location(0)");
+ EXPECT_EQ(r()->error(), "12:34 error: '@blend_src' can only be used with '@location(0)'");
}
TEST_F(DualSourceBlendingExtensionTests, NoNonZeroCollisionsBetweenInAndOut) {
@@ -253,8 +253,8 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(12:34 error: use of @blend_src requires all the output @location attributes of the entry point to be paired with a @blend_src attribute
-56:78 note: use of @blend_src here
+ R"(12:34 error: use of '@blend_src' requires all the output '@location' attributes of the entry point to be paired with a '@blend_src' attribute
+56:78 note: use of '@blend_src' here
note: while analyzing entry point 'F')");
}
@@ -286,8 +286,8 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(3:4 error: use of @blend_src requires all the output @location attributes of the entry point to be paired with a @blend_src attribute
-1:2 note: use of @blend_src here
+ R"(3:4 error: use of '@blend_src' requires all the output '@location' attributes of the entry point to be paired with a '@blend_src' attribute
+1:2 note: use of '@blend_src' here
note: while analyzing entry point 'F')");
}
@@ -311,8 +311,8 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(1:2 error: use of @blend_src requires all the output @location attributes of the entry point to be paired with a @blend_src attribute
-note: use of @blend_src here
+ R"(1:2 error: use of '@blend_src' requires all the output '@location' attributes of the entry point to be paired with a '@blend_src' attribute
+note: use of '@blend_src' here
5:6 note: while analyzing entry point 'F')");
}
diff --git a/src/tint/lang/wgsl/resolver/entry_point_validation_test.cc b/src/tint/lang/wgsl/resolver/entry_point_validation_test.cc
index 444f9e5..0a43290 100644
--- a/src/tint/lang/wgsl/resolver/entry_point_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/entry_point_validation_test.cc
@@ -119,7 +119,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), R"(14:52 error: multiple entry point IO attributes
-13:43 note: previously consumed @location)");
+13:43 note: previously consumed '@location')");
}
TEST_F(ResolverEntryPointValidationTest, ReturnType_Struct_Valid) {
@@ -171,7 +171,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), R"(14:52 error: multiple entry point IO attributes
-13:43 note: previously consumed @location
+13:43 note: previously consumed '@location'
12:34 note: while analyzing entry point 'main')");
}
@@ -227,7 +227,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(12:34 error: @builtin(frag_depth) appears multiple times as pipeline output
+ R"(12:34 error: '@builtin(frag_depth)' appears multiple times as pipeline output
12:34 note: while analyzing entry point 'main')");
}
@@ -286,7 +286,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), R"(14:52 error: multiple entry point IO attributes
-13:43 note: previously consumed @location)");
+13:43 note: previously consumed '@location')");
}
TEST_F(ResolverEntryPointValidationTest, Parameter_Struct_Valid) {
@@ -338,7 +338,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), R"(14:52 error: multiple entry point IO attributes
-13:43 note: previously consumed @location
+13:43 note: previously consumed '@location'
12:34 note: while analyzing entry point 'main')");
}
@@ -393,7 +393,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: @builtin(sample_index) appears multiple times as pipeline input");
+ "12:34 error: '@builtin(sample_index)' appears multiple times as pipeline input");
}
TEST_F(ResolverEntryPointValidationTest, Parameter_Struct_DuplicateBuiltins) {
@@ -427,7 +427,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(12:34 error: @builtin(sample_index) appears multiple times as pipeline input
+ R"(12:34 error: '@builtin(sample_index)' appears multiple times as pipeline input
12:34 note: while analyzing entry point 'main')");
}
@@ -772,8 +772,8 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(12:34 error: cannot apply @location to declaration of type 'bool'
-34:56 note: @location must only be applied to declarations of numeric scalar or numeric vector type)");
+ R"(12:34 error: cannot apply '@location' to declaration of type 'bool'
+34:56 note: '@location' must only be applied to declarations of numeric scalar or numeric vector type)");
}
TEST_F(LocationAttributeTests, BadType_Output_Array) {
@@ -793,8 +793,8 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(12:34 error: cannot apply @location to declaration of type 'array<f32, 2>'
-34:56 note: @location must only be applied to declarations of numeric scalar or numeric vector type)");
+ R"(12:34 error: cannot apply '@location' to declaration of type 'array<f32, 2>'
+34:56 note: '@location' must only be applied to declarations of numeric scalar or numeric vector type)");
}
TEST_F(LocationAttributeTests, BadType_Input_Struct) {
@@ -821,8 +821,8 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(12:34 error: cannot apply @location to declaration of type 'Input'
-13:43 note: @location must only be applied to declarations of numeric scalar or numeric vector type)");
+ R"(12:34 error: cannot apply '@location' to declaration of type 'Input'
+13:43 note: '@location' must only be applied to declarations of numeric scalar or numeric vector type)");
}
TEST_F(LocationAttributeTests, BadType_Input_Struct_NestedStruct) {
@@ -879,8 +879,8 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(13:43 error: cannot apply @location to declaration of type 'array<f32>'
-note: @location must only be applied to declarations of numeric scalar or numeric vector type)");
+ R"(13:43 error: cannot apply '@location' to declaration of type 'array<f32>'
+note: '@location' must only be applied to declarations of numeric scalar or numeric vector type)");
}
TEST_F(LocationAttributeTests, BadMemberType_Input) {
@@ -906,8 +906,8 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(34:56 error: cannot apply @location to declaration of type 'array<i32>'
-12:34 note: @location must only be applied to declarations of numeric scalar or numeric vector type)");
+ R"(34:56 error: cannot apply '@location' to declaration of type 'array<i32>'
+12:34 note: '@location' must only be applied to declarations of numeric scalar or numeric vector type)");
}
TEST_F(LocationAttributeTests, BadMemberType_Output) {
@@ -931,8 +931,8 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(34:56 error: cannot apply @location to declaration of type 'atomic<i32>'
-12:34 note: @location must only be applied to declarations of numeric scalar or numeric vector type)");
+ R"(34:56 error: cannot apply '@location' to declaration of type 'atomic<i32>'
+12:34 note: '@location' must only be applied to declarations of numeric scalar or numeric vector type)");
}
TEST_F(LocationAttributeTests, BadMemberType_Unused) {
@@ -946,8 +946,8 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(34:56 error: cannot apply @location to declaration of type 'mat3x2<f32>'
-12:34 note: @location must only be applied to declarations of numeric scalar or numeric vector type)");
+ R"(34:56 error: cannot apply '@location' to declaration of type 'mat3x2<f32>'
+12:34 note: '@location' must only be applied to declarations of numeric scalar or numeric vector type)");
}
TEST_F(LocationAttributeTests, ReturnType_Struct_Valid) {
@@ -998,8 +998,8 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: cannot apply @location to declaration of type 'Output'
-13:43 note: @location must only be applied to declarations of numeric scalar or numeric vector type)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: cannot apply '@location' to declaration of type 'Output'
+13:43 note: '@location' must only be applied to declarations of numeric scalar or numeric vector type)");
}
TEST_F(LocationAttributeTests, ReturnType_Struct_NestedStruct) {
@@ -1054,8 +1054,8 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(13:43 error: cannot apply @location to declaration of type 'array<f32>'
-12:34 note: @location must only be applied to declarations of numeric scalar or numeric vector type)");
+ R"(13:43 error: cannot apply '@location' to declaration of type 'array<f32>'
+12:34 note: '@location' must only be applied to declarations of numeric scalar or numeric vector type)");
}
TEST_F(LocationAttributeTests, ComputeShaderLocation_Input) {
@@ -1072,7 +1072,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: @location cannot be used by compute shaders)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@location' cannot be used by compute shaders)");
}
TEST_F(LocationAttributeTests, ComputeShaderLocation_Output) {
@@ -1087,7 +1087,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: @location cannot be used by compute shaders)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@location' cannot be used by compute shaders)");
}
TEST_F(LocationAttributeTests, ComputeShaderLocationStructMember_Output) {
@@ -1106,9 +1106,8 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: @location cannot be used by compute shaders\n"
- "56:78 note: while analyzing entry point 'main'");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@location' cannot be used by compute shaders
+56:78 note: while analyzing entry point 'main')");
}
TEST_F(LocationAttributeTests, ComputeShaderLocationStructMember_Input) {
@@ -1125,9 +1124,8 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: @location cannot be used by compute shaders\n"
- "56:78 note: while analyzing entry point 'main'");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@location' cannot be used by compute shaders
+56:78 note: while analyzing entry point 'main')");
}
TEST_F(LocationAttributeTests, Duplicate_input) {
@@ -1153,7 +1151,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: @location(1) appears multiple times)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@location(1)' appears multiple times)");
}
TEST_F(LocationAttributeTests, Duplicate_struct) {
@@ -1186,7 +1184,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(34:56 error: @location(1) appears multiple times
+ R"(34:56 error: '@location(1)' appears multiple times
12:34 note: while analyzing entry point 'main')");
}
diff --git a/src/tint/lang/wgsl/resolver/f16_extension_test.cc b/src/tint/lang/wgsl/resolver/f16_extension_test.cc
index c7f7fbd..632f790 100644
--- a/src/tint/lang/wgsl/resolver/f16_extension_test.cc
+++ b/src/tint/lang/wgsl/resolver/f16_extension_test.cc
@@ -53,7 +53,7 @@
GlobalVar("v", ty.f16(Source{{12, 34}}), core::AddressSpace::kPrivate);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: f16 type used without 'f16' extension enabled");
+ EXPECT_EQ(r()->error(), "12:34 error: 'f16' type used without 'f16' extension enabled");
}
TEST_F(ResolverF16ExtensionTest, Vec2TypeUsedWithExtension) {
@@ -71,7 +71,7 @@
GlobalVar("v", ty.vec2(ty.f16(Source{{12, 34}})), core::AddressSpace::kPrivate);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: f16 type used without 'f16' extension enabled");
+ EXPECT_EQ(r()->error(), "12:34 error: 'f16' type used without 'f16' extension enabled");
}
TEST_F(ResolverF16ExtensionTest, Vec2TypeInitUsedWithExtension) {
@@ -89,7 +89,7 @@
GlobalVar("v", Call(ty.vec2(ty.f16(Source{{12, 34}}))), core::AddressSpace::kPrivate);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: f16 type used without 'f16' extension enabled");
+ EXPECT_EQ(r()->error(), "12:34 error: 'f16' type used without 'f16' extension enabled");
}
TEST_F(ResolverF16ExtensionTest, Vec2TypeConvUsedWithExtension) {
@@ -108,7 +108,7 @@
core::AddressSpace::kPrivate);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: f16 type used without 'f16' extension enabled");
+ EXPECT_EQ(r()->error(), "12:34 error: 'f16' type used without 'f16' extension enabled");
}
TEST_F(ResolverF16ExtensionTest, F16LiteralUsedWithExtension) {
@@ -126,7 +126,7 @@
GlobalVar("v", Expr(Source{{12, 34}}, 16_h), core::AddressSpace::kPrivate);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: f16 type used without 'f16' extension enabled");
+ EXPECT_EQ(r()->error(), "12:34 error: 'f16' type used without 'f16' extension enabled");
}
using ResolverF16ExtensionBuiltinTypeAliasTest = ResolverTestWithParam<const char*>;
@@ -146,7 +146,7 @@
GlobalVar("v", ty(Source{{12, 34}}, GetParam()), core::AddressSpace::kPrivate);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: f16 type used without 'f16' extension enabled");
+ EXPECT_EQ(r()->error(), "12:34 error: 'f16' type used without 'f16' extension enabled");
}
INSTANTIATE_TEST_SUITE_P(ResolverF16ExtensionBuiltinTypeAliasTest,
diff --git a/src/tint/lang/wgsl/resolver/framebuffer_fetch_extension_test.cc b/src/tint/lang/wgsl/resolver/framebuffer_fetch_extension_test.cc
index a9c6576..b18be5c 100644
--- a/src/tint/lang/wgsl/resolver/framebuffer_fetch_extension_test.cc
+++ b/src/tint/lang/wgsl/resolver/framebuffer_fetch_extension_test.cc
@@ -66,7 +66,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(12:34 error: use of @color requires enabling extension 'chromium_experimental_framebuffer_fetch')");
+ R"(12:34 error: use of '@color' requires enabling extension 'chromium_experimental_framebuffer_fetch')");
}
TEST_F(FramebufferFetchExtensionTest, ColorMemberUsedWithExtension) {
@@ -94,7 +94,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(12:34 error: use of @color requires enabling extension 'chromium_experimental_framebuffer_fetch')");
+ R"(12:34 error: use of '@color' requires enabling extension 'chromium_experimental_framebuffer_fetch')");
}
TEST_F(FramebufferFetchExtensionTest, DuplicateColorParams) {
@@ -112,7 +112,7 @@
ty.void_(), Empty, Vector{Stage(ast::PipelineStage::kFragment)});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(1:2 error: @color(1) appears multiple times)");
+ EXPECT_EQ(r()->error(), R"(1:2 error: '@color(1)' appears multiple times)");
}
TEST_F(FramebufferFetchExtensionTest, DuplicateColorStruct) {
@@ -136,7 +136,7 @@
Vector{Stage(ast::PipelineStage::kFragment)});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(1:2 error: @color(1) appears multiple times)");
+ EXPECT_EQ(r()->error(), R"(1:2 error: '@color(1)' appears multiple times)");
}
TEST_F(FramebufferFetchExtensionTest, DuplicateColorParamAndStruct) {
@@ -163,7 +163,7 @@
ty.void_(), Empty, Vector{Stage(ast::PipelineStage::kFragment)});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(1:2 error: @color(2) appears multiple times
+ EXPECT_EQ(r()->error(), R"(1:2 error: '@color(2)' appears multiple times
note: while analyzing entry point 'f')");
}
@@ -206,8 +206,8 @@
} else {
EXPECT_FALSE(r()->Resolve());
auto expected =
- ReplaceAll(R"(12:34 error: cannot apply @color to declaration of type '$TYPE'
-56:78 note: @color must only be applied to declarations of numeric scalar or numeric vector type)",
+ ReplaceAll(R"(12:34 error: cannot apply '@color' to declaration of type '$TYPE'
+56:78 note: '@color' must only be applied to declarations of numeric scalar or numeric vector type)",
"$TYPE", GetParam().name);
EXPECT_EQ(r()->error(), expected);
}
@@ -230,8 +230,8 @@
} else {
EXPECT_FALSE(r()->Resolve());
auto expected =
- ReplaceAll(R"(12:34 error: cannot apply @color to declaration of type '$TYPE'
-56:78 note: @color must only be applied to declarations of numeric scalar or numeric vector type)",
+ ReplaceAll(R"(12:34 error: cannot apply '@color' to declaration of type '$TYPE'
+56:78 note: '@color' must only be applied to declarations of numeric scalar or numeric vector type)",
"$TYPE", GetParam().name);
EXPECT_EQ(r()->error(), expected);
}
diff --git a/src/tint/lang/wgsl/resolver/function_validation_test.cc b/src/tint/lang/wgsl/resolver/function_validation_test.cc
index 2a01da4..3de0b09 100644
--- a/src/tint/lang/wgsl/resolver/function_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/function_validation_test.cc
@@ -150,7 +150,7 @@
ASSERT_TRUE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 warning: code is unreachable");
+ EXPECT_EQ(r()->error(), R"(12:34 warning: code is unreachable)");
EXPECT_TRUE(Sem().Get(decl_a)->IsReachable());
EXPECT_TRUE(Sem().Get(ret)->IsReachable());
EXPECT_FALSE(Sem().Get(assign_a)->IsReachable());
@@ -170,7 +170,7 @@
Func("func", tint::Empty, ty.void_(), Vector{decl_a, Block(Block(Block(ret))), assign_a});
ASSERT_TRUE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 warning: code is unreachable");
+ EXPECT_EQ(r()->error(), R"(12:34 warning: code is unreachable)");
EXPECT_TRUE(Sem().Get(decl_a)->IsReachable());
EXPECT_TRUE(Sem().Get(ret)->IsReachable());
EXPECT_FALSE(Sem().Get(assign_a)->IsReachable());
@@ -207,7 +207,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: discard statement cannot be used in vertex pipeline stage");
+ R"(12:34 error: discard statement cannot be used in vertex pipeline stage)");
}
TEST_F(ResolverFunctionValidationTest, DiscardCalledIndirectlyFromComputeEntryPoint) {
@@ -260,7 +260,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: missing return at end of function");
+ EXPECT_EQ(r()->error(), R"(12:34 error: missing return at end of function)");
}
TEST_F(ResolverFunctionValidationTest, VoidFunctionEndWithoutReturnStatementEmptyBody_Pass) {
@@ -277,7 +277,7 @@
Func(Source{{12, 34}}, "func", tint::Empty, ty.i32(), tint::Empty);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: missing return at end of function");
+ EXPECT_EQ(r()->error(), R"(12:34 error: missing return at end of function)");
}
TEST_F(ResolverFunctionValidationTest, FunctionTypeMustMatchReturnStatementType_Pass) {
@@ -343,7 +343,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: function 'v' does not return a value");
+ EXPECT_EQ(r()->error(), R"(12:34 error: function 'v' does not return a value)");
}
TEST_F(ResolverFunctionValidationTest, FunctionTypeMustMatchReturnStatementTypeMissing_fail) {
@@ -623,8 +623,9 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: workgroup_size arguments must be of the same type, either i32 or u32");
+ EXPECT_EQ(
+ r()->error(),
+ "12:34 error: '@workgroup_size' arguments must be of the same type, either 'i32' or 'u32'");
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_MismatchType_I32) {
@@ -638,8 +639,9 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: workgroup_size arguments must be of the same type, either i32 or u32");
+ EXPECT_EQ(
+ r()->error(),
+ "12:34 error: '@workgroup_size' arguments must be of the same type, either 'i32' or 'u32'");
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_Const_TypeMismatch) {
@@ -654,8 +656,9 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: workgroup_size arguments must be of the same type, either i32 or u32");
+ EXPECT_EQ(
+ r()->error(),
+ "12:34 error: '@workgroup_size' arguments must be of the same type, either 'i32' or 'u32'");
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_Const_TypeMismatch2) {
@@ -672,8 +675,9 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: workgroup_size arguments must be of the same type, either i32 or u32");
+ EXPECT_EQ(
+ r()->error(),
+ "12:34 error: '@workgroup_size' arguments must be of the same type, either 'i32' or 'u32'");
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_Mismatch_ConstU32) {
@@ -690,8 +694,9 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: workgroup_size arguments must be of the same type, either i32 or u32");
+ EXPECT_EQ(
+ r()->error(),
+ "12:34 error: '@workgroup_size' arguments must be of the same type, either 'i32' or 'u32'");
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_Literal_BadType) {
@@ -707,8 +712,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- "12:34 error: workgroup_size argument must be a constant or override-expression of type "
- "abstract-integer, i32 or u32");
+ R"(12:34 error: '@workgroup_size' argument must be a constant or override-expression of type 'abstract-integer', 'i32' or 'u32')");
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_Literal_Negative) {
@@ -722,7 +726,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: workgroup_size argument must be at least 1");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@workgroup_size' argument must be at least 1)");
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_Literal_Zero) {
@@ -736,7 +740,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: workgroup_size argument must be at least 1");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@workgroup_size' argument must be at least 1)");
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_Const_BadType) {
@@ -753,8 +757,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- "12:34 error: workgroup_size argument must be a constant or override-expression of type "
- "abstract-integer, i32 or u32");
+ R"(12:34 error: '@workgroup_size' argument must be a constant or override-expression of type 'abstract-integer', 'i32' or 'u32')");
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_Const_Negative) {
@@ -769,7 +772,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: workgroup_size argument must be at least 1");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@workgroup_size' argument must be at least 1)");
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_Const_Zero) {
@@ -784,7 +787,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: workgroup_size argument must be at least 1");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@workgroup_size' argument must be at least 1)");
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_Const_NestedZeroValueInitializer) {
@@ -799,7 +802,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: workgroup_size argument must be at least 1");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@workgroup_size' argument must be at least 1)");
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_OverflowsU32_0x10000_0x100_0x100) {
@@ -812,7 +815,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: total workgroup grid size cannot exceed 0xffffffff");
+ EXPECT_EQ(r()->error(), R"(12:34 error: total workgroup grid size cannot exceed 0xffffffff)");
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_OverflowsU32_0x10000_0x10000) {
@@ -825,7 +828,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: total workgroup grid size cannot exceed 0xffffffff");
+ EXPECT_EQ(r()->error(), R"(12:34 error: total workgroup grid size cannot exceed 0xffffffff)");
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_OverflowsU32_0x10000_C_0x10000) {
@@ -840,7 +843,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: total workgroup grid size cannot exceed 0xffffffff");
+ EXPECT_EQ(r()->error(), R"(12:34 error: total workgroup grid size cannot exceed 0xffffffff)");
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_OverflowsU32_0x10000_C) {
@@ -855,7 +858,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: total workgroup grid size cannot exceed 0xffffffff");
+ EXPECT_EQ(r()->error(), R"(12:34 error: total workgroup grid size cannot exceed 0xffffffff)");
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_OverflowsU32_0x10000_O_0x10000) {
@@ -870,7 +873,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: total workgroup grid size cannot exceed 0xffffffff");
+ EXPECT_EQ(r()->error(), R"(12:34 error: total workgroup grid size cannot exceed 0xffffffff)");
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_NonConst) {
@@ -885,9 +888,9 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: workgroup_size argument must be a constant or override-expression of "
- "type abstract-integer, i32 or u32");
+ EXPECT_EQ(
+ r()->error(),
+ R"(12:34 error: '@workgroup_size' argument must be a constant or override-expression of type 'abstract-integer', 'i32' or 'u32')");
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_InvalidExpr_x) {
@@ -901,9 +904,9 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: workgroup_size argument must be a constant or override-expression of "
- "type abstract-integer, i32 or u32");
+ EXPECT_EQ(
+ r()->error(),
+ R"(12:34 error: '@workgroup_size' argument must be a constant or override-expression of type 'abstract-integer', 'i32' or 'u32')");
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_InvalidExpr_y) {
@@ -917,9 +920,9 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: workgroup_size argument must be a constant or override-expression of "
- "type abstract-integer, i32 or u32");
+ EXPECT_EQ(
+ r()->error(),
+ R"(12:34 error: '@workgroup_size' argument must be a constant or override-expression of type 'abstract-integer', 'i32' or 'u32')");
}
TEST_F(ResolverFunctionValidationTest, WorkgroupSize_InvalidExpr_z) {
@@ -933,9 +936,9 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: workgroup_size argument must be a constant or override-expression of "
- "type abstract-integer, i32 or u32");
+ EXPECT_EQ(
+ r()->error(),
+ R"(12:34 error: '@workgroup_size' argument must be a constant or override-expression of type 'abstract-integer', 'i32' or 'u32')");
}
TEST_F(ResolverFunctionValidationTest, ReturnIsConstructible_NonPlain) {
@@ -943,7 +946,7 @@
Func("f", tint::Empty, ret_type, tint::Empty);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: function return type must be a constructible type");
+ EXPECT_EQ(r()->error(), R"(12:34 error: function return type must be a constructible type)");
}
TEST_F(ResolverFunctionValidationTest, ReturnIsConstructible_AtomicInt) {
@@ -951,7 +954,7 @@
Func("f", tint::Empty, ret_type, tint::Empty);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: function return type must be a constructible type");
+ EXPECT_EQ(r()->error(), R"(12:34 error: function return type must be a constructible type)");
}
TEST_F(ResolverFunctionValidationTest, ReturnIsConstructible_ArrayOfAtomic) {
@@ -959,7 +962,7 @@
Func("f", tint::Empty, ret_type, tint::Empty);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: function return type must be a constructible type");
+ EXPECT_EQ(r()->error(), R"(12:34 error: function return type must be a constructible type)");
}
TEST_F(ResolverFunctionValidationTest, ReturnIsConstructible_StructOfAtomic) {
@@ -970,7 +973,7 @@
Func("f", tint::Empty, ret_type, tint::Empty);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: function return type must be a constructible type");
+ EXPECT_EQ(r()->error(), R"(12:34 error: function return type must be a constructible type)");
}
TEST_F(ResolverFunctionValidationTest, ReturnIsConstructible_RuntimeArray) {
@@ -978,7 +981,7 @@
Func("f", tint::Empty, ret_type, tint::Empty);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: function return type must be a constructible type");
+ EXPECT_EQ(r()->error(), R"(12:34 error: function return type must be a constructible type)");
}
TEST_F(ResolverFunctionValidationTest, ParameterStoreType_NonAtomicFree) {
@@ -990,7 +993,7 @@
Func("f", Vector{bar}, ty.void_(), tint::Empty);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: type of function parameter must be constructible");
+ EXPECT_EQ(r()->error(), R"(12:34 error: type of function parameter must be constructible)");
}
TEST_F(ResolverFunctionValidationTest, ParameterStoreType_AtomicFree) {
@@ -1022,7 +1025,7 @@
Func(Source{{12, 34}}, "f", params, ty.void_(), tint::Empty);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: function declares 256 parameters, maximum is 255");
+ EXPECT_EQ(r()->error(), R"(12:34 error: function declares 256 parameters, maximum is 255)");
}
TEST_F(ResolverFunctionValidationTest, ParameterVectorNoType) {
@@ -1032,7 +1035,7 @@
tint::Empty);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: expected '<' for 'vec3'");
+ EXPECT_EQ(r()->error(), R"(12:34 error: expected '<' for 'vec3')");
}
TEST_F(ResolverFunctionValidationTest, ParameterMatrixNoType) {
@@ -1042,7 +1045,7 @@
tint::Empty);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: expected '<' for 'mat3x3'");
+ EXPECT_EQ(r()->error(), R"(12:34 error: expected '<' for 'mat3x3')");
}
enum class Expectation {
diff --git a/src/tint/lang/wgsl/resolver/host_shareable_validation_test.cc b/src/tint/lang/wgsl/resolver/host_shareable_validation_test.cc
index 50e7448..e4018af 100644
--- a/src/tint/lang/wgsl/resolver/host_shareable_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/host_shareable_validation_test.cc
@@ -50,7 +50,7 @@
EXPECT_EQ(
r()->error(),
- R"(12:34 error: Type 'bool' cannot be used in address space 'storage' as it is non-host-shareable
+ R"(12:34 error: type 'bool' cannot be used in address space 'storage' as it is non-host-shareable
56:78 note: while analyzing structure member S.x
90:12 note: while instantiating 'var' g)");
}
@@ -66,7 +66,7 @@
EXPECT_EQ(
r()->error(),
- R"(12:34 error: Type 'vec3<bool>' cannot be used in address space 'storage' as it is non-host-shareable
+ R"(12:34 error: type 'vec3<bool>' cannot be used in address space 'storage' as it is non-host-shareable
56:78 note: while analyzing structure member S.x
90:12 note: while instantiating 'var' g)");
}
@@ -82,7 +82,7 @@
EXPECT_EQ(
r()->error(),
- R"(12:34 error: Type 'bool' cannot be used in address space 'storage' as it is non-host-shareable
+ R"(12:34 error: type 'bool' cannot be used in address space 'storage' as it is non-host-shareable
56:78 note: while analyzing structure member S.x
90:12 note: while instantiating 'var' g)");
}
@@ -101,7 +101,7 @@
EXPECT_EQ(
r()->error(),
- R"(error: Type 'bool' cannot be used in address space 'storage' as it is non-host-shareable
+ R"(error: type 'bool' cannot be used in address space 'storage' as it is non-host-shareable
1:2 note: while analyzing structure member I1.x
3:4 note: while analyzing structure member I2.y
5:6 note: while analyzing structure member I3.z
diff --git a/src/tint/lang/wgsl/resolver/increment_decrement_validation_test.cc b/src/tint/lang/wgsl/resolver/increment_decrement_validation_test.cc
index 2f4ea33..3f2d7ea 100644
--- a/src/tint/lang/wgsl/resolver/increment_decrement_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/increment_decrement_validation_test.cc
@@ -166,7 +166,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), R"(56:78 error: cannot modify 'let'
-12:34 note: 'a' is declared here:)");
+12:34 note: 'let a' declared here)");
}
TEST_F(ResolverIncrementDecrementValidationTest, Parameter) {
@@ -182,7 +182,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), R"(56:78 error: cannot modify function parameter
-12:34 note: 'a' is declared here:)");
+12:34 note: parameter 'a' declared here)");
}
TEST_F(ResolverIncrementDecrementValidationTest, ReturnValue) {
diff --git a/src/tint/lang/wgsl/resolver/override_test.cc b/src/tint/lang/wgsl/resolver/override_test.cc
index 3077e79..df09b2e 100644
--- a/src/tint/lang/wgsl/resolver/override_test.cc
+++ b/src/tint/lang/wgsl/resolver/override_test.cc
@@ -106,8 +106,8 @@
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(56:78 error: @id values must be unique
-12:34 note: a override with an ID of 7 was previously declared here:)");
+ EXPECT_EQ(r()->error(), R"(56:78 error: '@id' values must be unique
+12:34 note: a override with an ID of 7 was previously declared here)");
}
TEST_F(ResolverOverrideTest, IdTooLarge) {
@@ -115,7 +115,7 @@
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: @id value must be between 0 and 65535");
+ EXPECT_EQ(r()->error(), "12:34 error: '@id' value must be between 0 and 65535");
}
TEST_F(ResolverOverrideTest, TransitiveReferences_DirectUse) {
diff --git a/src/tint/lang/wgsl/resolver/pixel_local_extension_test.cc b/src/tint/lang/wgsl/resolver/pixel_local_extension_test.cc
index eceb5ae..74ea8e1 100644
--- a/src/tint/lang/wgsl/resolver/pixel_local_extension_test.cc
+++ b/src/tint/lang/wgsl/resolver/pixel_local_extension_test.cc
@@ -354,8 +354,8 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(12:34 error: struct members used in the 'pixel_local' address space can only be of the type 'i32', 'u32' or 'f32'
-56:78 note: struct 'S' used in the 'pixel_local' address space here)");
+ R"(12:34 error: 'struct' members used in the 'pixel_local' address space can only be of the type 'i32', 'u32' or 'f32'
+56:78 note: 'struct S' used in the 'pixel_local' address space here)");
}
}
diff --git a/src/tint/lang/wgsl/resolver/ptr_ref_validation_test.cc b/src/tint/lang/wgsl/resolver/ptr_ref_validation_test.cc
index bbcbc13..e7b05da 100644
--- a/src/tint/lang/wgsl/resolver/ptr_ref_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/ptr_ref_validation_test.cc
@@ -306,7 +306,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: cannot initialize let of type "
+ "12:34 error: cannot initialize 'let' of type "
"'ptr<storage, i32, read>' with value of type "
"'ptr<storage, i32, read_write>'");
}
diff --git a/src/tint/lang/wgsl/resolver/resolver.cc b/src/tint/lang/wgsl/resolver/resolver.cc
index 0beaffe..20ec2a4 100644
--- a/src/tint/lang/wgsl/resolver/resolver.cc
+++ b/src/tint/lang/wgsl/resolver/resolver.cc
@@ -108,6 +108,8 @@
#include "src/tint/utils/math/math.h"
#include "src/tint/utils/text/string.h"
#include "src/tint/utils/text/string_stream.h"
+#include "src/tint/utils/text/styled_text.h"
+#include "src/tint/utils/text/text_style.h"
using namespace tint::core::fluent_types; // NOLINT
@@ -269,7 +271,8 @@
attribute, //
[&](const ast::InternalAttribute* attr) -> bool { return InternalAttribute(attr); },
[&](Default) {
- ErrorInvalidAttribute(attribute, "'let' declaration");
+ ErrorInvalidAttribute(attribute, StyledText{} << style::Keyword << "let"
+ << style::Plain << " declaration");
return false;
});
if (!ok) {
@@ -278,7 +281,8 @@
}
if (TINT_UNLIKELY(!v->initializer)) {
- AddError(v->source) << "'let' declaration must have an initializer";
+ AddError(v->source) << style::Keyword << "let" << style::Plain
+ << " declaration must have an initializer";
return nullptr;
}
@@ -299,7 +303,8 @@
if (!ApplyAddressSpaceUsageToType(core::AddressSpace::kUndefined,
const_cast<core::type::Type*>(sem->Type()), v->source)) {
- AddNote(v->source) << "while instantiating 'let' " << v->name->symbol.Name();
+ AddNote(v->source) << "while instantiating " << style::Keyword << "let " << style::Variable
+ << v->name->symbol.Name();
return nullptr;
}
@@ -357,7 +362,8 @@
if (!ApplyAddressSpaceUsageToType(core::AddressSpace::kUndefined,
const_cast<core::type::Type*>(ty), v->source)) {
- AddNote(v->source) << "while instantiating 'override' " << v->name->symbol.Name();
+ AddNote(v->source) << "while instantiating " << style::Keyword << "override "
+ << style::Variable << v->name->symbol.Name();
return nullptr;
}
@@ -374,19 +380,24 @@
return false;
}
if (!materialized->Type()->IsAnyOf<core::type::I32, core::type::U32>()) {
- AddError(attr->source) << "@id must be an i32 or u32 value";
+ AddError(attr->source)
+ << style::Attribute << "@id" << style::Plain << " must be an "
+ << style::Type << "i32" << style::Plain << " or " << style::Type << "u32"
+ << style::Plain << " value";
return false;
}
auto const_value = materialized->ConstantValue();
auto value = const_value->ValueAs<AInt>();
if (value < 0) {
- AddError(attr->source) << "@id value must be non-negative";
+ AddError(attr->source) << style::Attribute << "@id" << style::Plain
+ << " value must be non-negative";
return false;
}
if (value > std::numeric_limits<decltype(OverrideId::value)>::max()) {
AddError(attr->source)
- << "@id value must be between 0 and "
+ << style::Attribute << "@id" << style::Plain
+ << " value must be between 0 and "
<< std::numeric_limits<decltype(OverrideId::value)>::max();
return false;
}
@@ -399,7 +410,8 @@
return true;
},
[&](Default) {
- ErrorInvalidAttribute(attribute, "'override' declaration");
+ ErrorInvalidAttribute(attribute, StyledText{} << style::Keyword << "override"
+ << style::Plain << " declaration");
return false;
});
if (!ok) {
@@ -425,7 +437,9 @@
Mark(attribute);
bool ok = Switch(attribute, //
[&](Default) {
- ErrorInvalidAttribute(attribute, "'const' declaration");
+ ErrorInvalidAttribute(attribute,
+ StyledText{} << style::Keyword << "const"
+ << style::Plain << " declaration");
return false;
});
if (!ok) {
@@ -684,7 +698,8 @@
case kErrored:
return nullptr;
case kInvalid:
- ErrorInvalidAttribute(attribute, "module-scope 'var'");
+ ErrorInvalidAttribute(
+ attribute, StyledText{} << "module-scope " << style::Keyword << "var");
return nullptr;
}
}
@@ -700,7 +715,8 @@
attribute,
[&](const ast::InternalAttribute* attr) { return InternalAttribute(attr); },
[&](Default) {
- ErrorInvalidAttribute(attribute, "function-scope 'var'");
+ ErrorInvalidAttribute(
+ attribute, StyledText{} << "function-scope " << style::Keyword << "var");
return false;
});
if (!ok) {
@@ -759,7 +775,7 @@
[&](const ast::GroupAttribute* attr) {
if (validator_.IsValidationEnabled(
param->attributes, ast::DisabledValidation::kEntryPointParameter)) {
- ErrorInvalidAttribute(attribute, "function parameters");
+ ErrorInvalidAttribute(attribute, StyledText{} << "function parameters");
return false;
}
auto value = GroupAttribute(attr);
@@ -772,7 +788,7 @@
[&](const ast::BindingAttribute* attr) -> bool {
if (validator_.IsValidationEnabled(
param->attributes, ast::DisabledValidation::kEntryPointParameter)) {
- ErrorInvalidAttribute(attribute, "function parameters");
+ ErrorInvalidAttribute(attribute, StyledText{} << "function parameters");
return false;
}
auto value = BindingAttribute(attr);
@@ -783,7 +799,7 @@
return true;
},
[&](Default) {
- ErrorInvalidAttribute(attribute, "function parameters");
+ ErrorInvalidAttribute(attribute, StyledText{} << "function parameters");
return false;
});
if (!ok) {
@@ -802,9 +818,10 @@
[&](Default) {
if (attribute->IsAnyOf<ast::LocationAttribute, ast::BuiltinAttribute,
ast::InvariantAttribute, ast::InterpolateAttribute>()) {
- ErrorInvalidAttribute(attribute, "non-entry point function parameters");
+ ErrorInvalidAttribute(
+ attribute, StyledText{} << "non-entry point function parameters");
} else {
- ErrorInvalidAttribute(attribute, "function parameters");
+ ErrorInvalidAttribute(attribute, StyledText{} << "function parameters");
}
return false;
});
@@ -996,7 +1013,7 @@
},
[&](const ast::InternalAttribute* attr) { return InternalAttribute(attr); },
[&](Default) {
- ErrorInvalidAttribute(attribute, "functions");
+ ErrorInvalidAttribute(attribute, StyledText{} << "functions");
return false;
});
if (!ok) {
@@ -1118,19 +1135,20 @@
case kErrored:
return nullptr;
case kInvalid:
- ErrorInvalidAttribute(attribute, "entry point return types");
+ ErrorInvalidAttribute(attribute, StyledText{} << "entry point return types");
return nullptr;
}
}
} else {
for (auto* attribute : decl->return_type_attributes) {
Mark(attribute);
- bool ok = Switch(attribute, //
- [&](Default) {
- ErrorInvalidAttribute(attribute,
- "non-entry point function return types");
- return false;
- });
+ bool ok =
+ Switch(attribute, //
+ [&](Default) {
+ ErrorInvalidAttribute(
+ attribute, StyledText{} << "non-entry point function return types");
+ return false;
+ });
if (!ok) {
return nullptr;
}
@@ -2987,7 +3005,8 @@
if (!tmpl_ident) {
if (TINT_UNLIKELY(min_args != 0)) {
AddError(Source{ident->source.range.end})
- << "expected '<' for '" << ident->symbol.Name() << "'";
+ << "expected " << style::Code << "<" << style::Plain << " for " << style::Code
+ << ident->symbol.Name();
}
return nullptr;
}
@@ -3002,19 +3021,19 @@
}
if (min_args == max_args) {
if (TINT_UNLIKELY(ident->arguments.Length() != min_args)) {
- AddError(ident->source) << "'" << ident->symbol.Name() << "' requires " << min_args
- << " template arguments";
+ AddError(ident->source) << style::Code << ident->symbol.Name() << style::Plain
+ << " requires " << min_args << " template arguments";
return false;
}
} else {
if (TINT_UNLIKELY(ident->arguments.Length() < min_args)) {
- AddError(ident->source) << "'" << ident->symbol.Name() << "' requires at least "
- << min_args << " template arguments";
+ AddError(ident->source) << style::Code << ident->symbol.Name() << style::Plain
+ << " requires at least " << min_args << " template arguments";
return false;
}
if (TINT_UNLIKELY(ident->arguments.Length() > max_args)) {
- AddError(ident->source) << "'" << ident->symbol.Name() << "' requires at most "
- << max_args << " template arguments";
+ AddError(ident->source) << style::Code << ident->symbol.Name() << style::Plain
+ << " requires at most " << max_args << " template arguments";
return false;
}
}
@@ -3687,8 +3706,8 @@
ptr->Access());
root_ident = expr->RootIdentifier();
} else {
- AddError(unary->expr->source)
- << "cannot dereference expression of type '" << sem_.TypeNameOf(expr_ty) << "'";
+ AddError(unary->expr->source) << "cannot dereference expression of type "
+ << style::Type << sem_.TypeNameOf(expr_ty);
return nullptr;
}
break;
@@ -3748,14 +3767,17 @@
}
if (!materialized->Type()->IsAnyOf<core::type::I32, core::type::U32>()) {
- AddError(attr->source) << "@location must be an i32 or u32 value";
+ AddError(attr->source) << style::Attribute << "@location" << style::Plain << " must be an "
+ << style::Type << "i32" << style::Plain << " or " << style::Type
+ << "u32" << style::Plain << " value";
return Failure{};
}
auto const_value = materialized->ConstantValue();
auto value = const_value->ValueAs<AInt>();
if (value < 0) {
- AddError(attr->source) << "@location value must be non-negative";
+ AddError(attr->source) << style::Attribute << "@location" << style::Plain
+ << " value must be non-negative";
return Failure{};
}
@@ -3772,14 +3794,17 @@
}
if (!materialized->Type()->IsAnyOf<core::type::I32, core::type::U32>()) {
- AddError(attr->source) << "@color must be an i32 or u32 value";
+ AddError(attr->source) << style::Attribute << "@color" << style::Plain << " must be an "
+ << style::Type << "i32" << style::Plain << " or " << style::Type
+ << "u32" << style::Plain << " value";
return Failure{};
}
auto const_value = materialized->ConstantValue();
auto value = const_value->ValueAs<AInt>();
if (value < 0) {
- AddError(attr->source) << "@color value must be non-negative";
+ AddError(attr->source) << style::Attribute << "@color" << style::Plain
+ << " value must be non-negative";
return Failure{};
}
@@ -3795,14 +3820,17 @@
}
if (!materialized->Type()->IsAnyOf<core::type::I32, core::type::U32>()) {
- AddError(attr->source) << "@location must be an i32 or u32 value";
+ AddError(attr->source) << style::Attribute << "@blend_src" << style::Plain << style::Type
+ << "i32" << style::Plain << " or " << style::Type << "u32"
+ << style::Plain << " value";
return Failure{};
}
auto const_value = materialized->ConstantValue();
auto value = const_value->ValueAs<AInt>();
if (value != 0 && value != 1) {
- AddError(attr->source) << "@blend_src value must be zero or one";
+ AddError(attr->source) << style::Attribute << "@blend_src" << style::Plain
+ << " value must be zero or one";
return Failure{};
}
@@ -3818,14 +3846,17 @@
return Failure{};
}
if (!materialized->Type()->IsAnyOf<core::type::I32, core::type::U32>()) {
- AddError(attr->source) << "@binding must be an i32 or u32 value";
+ AddError(attr->source) << style::Attribute << "@binding" << style::Plain << " must be an "
+ << style::Type << "i32" << style::Plain << " or " << style::Type
+ << "u32" << style::Plain << " value";
return Failure{};
}
auto const_value = materialized->ConstantValue();
auto value = const_value->ValueAs<AInt>();
if (value < 0) {
- AddError(attr->source) << "@binding value must be non-negative";
+ AddError(attr->source) << style::Attribute << "@binding" << style::Plain
+ << " value must be non-negative";
return Failure{};
}
return static_cast<uint32_t>(value);
@@ -3840,14 +3871,17 @@
return Failure{};
}
if (!materialized->Type()->IsAnyOf<core::type::I32, core::type::U32>()) {
- AddError(attr->source) << "@group must be an i32 or u32 value";
+ AddError(attr->source) << style::Attribute << "@group" << style::Plain << " must be an "
+ << style::Type << "i32" << style::Plain << " or " << style::Type
+ << "u32" << style::Plain << " value";
return Failure{};
}
auto const_value = materialized->ConstantValue();
auto value = const_value->ValueAs<AInt>();
if (value < 0) {
- AddError(attr->source) << "@group value must be non-negative";
+ AddError(attr->source) << style::Attribute << "@group" << style::Plain
+ << " value must be non-negative";
return Failure{};
}
return static_cast<uint32_t>(value);
@@ -3864,9 +3898,13 @@
Vector<const sem::ValueExpression*, 3> args;
Vector<const core::type::Type*, 3> arg_tys;
- constexpr const char* kErrBadExpr =
- "workgroup_size argument must be a constant or override-expression of type "
- "abstract-integer, i32 or u32";
+ auto err_bad_expr = [&](const ast::Expression* value) {
+ AddError(value->source) << style::Attribute << "@workgroup_size" << style::Plain
+ << " argument must be a constant or override-expression of type "
+ << style::Type << "abstract-integer" << style::Plain << ", "
+ << style::Type << "i32" << style::Plain << " or " << style::Type
+ << "u32";
+ };
for (size_t i = 0; i < 3; i++) {
// Each argument to this attribute can either be a literal, an identifier for a
@@ -3881,13 +3919,13 @@
}
auto* ty = expr->Type();
if (!ty->IsAnyOf<core::type::I32, core::type::U32, core::type::AbstractInt>()) {
- AddError(value->source) << kErrBadExpr;
+ err_bad_expr(value);
return Failure{};
}
if (expr->Stage() != core::EvaluationStage::kConstant &&
expr->Stage() != core::EvaluationStage::kOverride) {
- AddError(value->source) << kErrBadExpr;
+ err_bad_expr(value);
return Failure{};
}
@@ -3897,8 +3935,9 @@
auto* common_ty = core::type::Type::Common(arg_tys);
if (!common_ty) {
- AddError(attr->source)
- << "workgroup_size arguments must be of the same type, either i32 or u32";
+ AddError(attr->source) << style::Attribute << "@workgroup_size" << style::Plain
+ << " arguments must be of the same type, either " << style::Type
+ << "i32" << style::Plain << " or " << style::Type << "u32";
return Failure{};
}
@@ -3914,7 +3953,8 @@
}
if (auto* value = materialized->ConstantValue()) {
if (value->ValueAs<AInt>() < 1) {
- AddError(values[i]->source) << "workgroup_size argument must be at least 1";
+ AddError(values[i]->source) << style::Attribute << "@workgroup_size" << style::Plain
+ << " argument must be at least 1";
return Failure{};
}
ws[i] = value->ValueAs<u32>();
@@ -4007,7 +4047,8 @@
validator_.DiagnosticFilters().Set(rule, control.severity);
} else {
auto& warning = AddWarning(control.rule_name->source)
- << "unrecognized diagnostic rule 'chromium." << name << "'\n";
+ << "unrecognized diagnostic rule " << style::Code << "chromium."
+ << name << style::Plain << "\n";
tint::SuggestAlternativeOptions opts;
opts.prefix = "chromium.";
tint::SuggestAlternatives(name, wgsl::kChromiumDiagnosticRuleStrings,
@@ -4022,7 +4063,8 @@
validator_.DiagnosticFilters().Set(rule, control.severity);
} else {
auto& warning = AddWarning(control.rule_name->source)
- << "unrecognized diagnostic rule '" << name << "'\n";
+ << "unrecognized diagnostic rule " << style::Code << name << style::Plain
+ << "\n";
tint::SuggestAlternatives(name, wgsl::kCoreDiagnosticRuleStrings, warning.message);
}
return true;
@@ -4033,8 +4075,8 @@
Mark(ext);
enabled_extensions_.Add(ext->name);
if (!allowed_features_.extensions.count(ext->name)) {
- AddError(ext->source) << "extension '" << ext->name
- << "' is not allowed in the current environment";
+ AddError(ext->source) << "extension " << style::Code << ext->name << style::Plain
+ << " is not allowed in the current environment";
return false;
}
}
@@ -4044,8 +4086,8 @@
bool Resolver::Requires(const ast::Requires* req) {
for (auto feature : req->features) {
if (!allowed_features_.features.count(feature)) {
- AddError(req->source) << "language feature '" << wgsl::ToString(feature)
- << "' is not allowed in the current environment";
+ AddError(req->source) << "language feature " << style::Code << wgsl::ToString(feature)
+ << style::Plain << " is not allowed in the current environment";
return false;
}
}
@@ -4101,8 +4143,8 @@
auto* count_val = count_sem->ConstantValue();
if (auto* ty = count_val->Type(); !ty->is_integer_scalar()) {
AddError(count_expr->source)
- << "array count must evaluate to a constant integer expression, but is type '"
- << ty->FriendlyName() << "'";
+ << "array count must evaluate to a constant integer expression, but is type "
+ << style::Type << ty->FriendlyName();
return nullptr;
}
@@ -4150,7 +4192,8 @@
return true;
},
[&](Default) {
- ErrorInvalidAttribute(attribute, "array types");
+ ErrorInvalidAttribute(
+ attribute, StyledText{} << style::Type << "array" << style::Plain << " types");
return false;
});
if (!ok) {
@@ -4226,9 +4269,9 @@
// https://gpuweb.github.io/gpuweb/wgsl/#limits
const size_t kMaxNumStructMembers = 16383;
if (str->members.Length() > kMaxNumStructMembers) {
- AddError(str->source) << "struct '" << struct_name() << "' has "
- << str->members.Length() << " members, maximum is "
- << kMaxNumStructMembers;
+ AddError(str->source) << style::Keyword << "struct " << style::Type << struct_name()
+ << style::Plain << " has " << str->members.Length()
+ << " members, maximum is " << kMaxNumStructMembers;
return nullptr;
}
}
@@ -4242,7 +4285,8 @@
bool ok = Switch(
attribute, [&](const ast::InternalAttribute* attr) { return InternalAttribute(attr); },
[&](Default) {
- ErrorInvalidAttribute(attribute, "struct declarations");
+ ErrorInvalidAttribute(attribute, StyledText{} << style::Keyword << "struct"
+ << style::Plain << " declarations");
return false;
});
if (!ok) {
@@ -4268,7 +4312,8 @@
Mark(member);
Mark(member->name);
if (auto added = member_map.Add(member->name->symbol, member); !added) {
- AddError(member->source) << "redefinition of '" << member->name->symbol.Name() << "'";
+ AddError(member->source)
+ << "redefinition of " << style::Code << member->name->symbol.Name();
AddNote(added.value->source) << "previous definition is here";
return nullptr;
}
@@ -4339,20 +4384,23 @@
return false;
}
if (!materialized->Type()->IsAnyOf<core::type::I32, core::type::U32>()) {
- AddError(attr->source) << "@align must be an i32 or u32 value";
+ AddError(attr->source) << style::Attribute << "@align" << style::Plain
+ << " value must be an " << style::Type << "i32"
+ << style::Plain << " or " << style::Type << "u32";
return false;
}
auto const_value = materialized->ConstantValue();
if (!const_value) {
- AddError(attr->source) << "@align must be constant expression";
+ AddError(attr->source) << style::Attribute << "@align" << style::Plain
+ << " value must be constant expression";
return false;
}
auto value = const_value->ValueAs<AInt>();
if (value <= 0 || !tint::IsPowerOfTwo(value)) {
- AddError(attr->source)
- << "@align value must be a positive, power-of-two integer";
+ AddError(attr->source) << style::Attribute << "@align" << style::Plain
+ << " value must be a positive, power-of-two integer";
return false;
}
align = u32(value);
@@ -4368,26 +4416,31 @@
return false;
}
if (!materialized->Type()->IsAnyOf<core::type::U32, core::type::I32>()) {
- AddError(attr->source) << "@size must be an i32 or u32 value";
+ AddError(attr->source) << style::Attribute << "@size" << style::Plain
+ << " value must be an " << style::Type << "i32"
+ << style::Plain << " or " << style::Type << "u32";
return false;
}
auto const_value = materialized->ConstantValue();
if (!const_value) {
- AddError(attr->expr->source) << "@size must be constant expression";
+ AddError(attr->expr->source) << style::Attribute << "@size" << style::Plain
+ << " value must be constant expression";
return false;
}
{
auto value = const_value->ValueAs<AInt>();
if (value <= 0) {
- AddError(attr->source) << "@size must be a positive integer";
+ AddError(attr->source) << style::Attribute << "@size" << style::Plain
+ << " value must be a positive integer";
return false;
}
}
auto value = const_value->ValueAs<uint64_t>();
if (value < size) {
AddError(attr->source)
- << "@size must be at least as big as the type's size (" << size << ")";
+ << style::Attribute << "@size" << style::Plain
+ << " must be at least as big as the type's size (" << size << ")";
return false;
}
size = u32(value);
@@ -4444,14 +4497,17 @@
[&](const ast::StrideAttribute* attr) {
if (validator_.IsValidationEnabled(
member->attributes, ast::DisabledValidation::kIgnoreStrideAttribute)) {
- ErrorInvalidAttribute(attribute, "struct members");
+ ErrorInvalidAttribute(attribute, StyledText{} << style::Keyword << "struct"
+ << style::Plain
+ << " members");
return false;
}
return StrideAttribute(attr);
},
[&](const ast::InternalAttribute* attr) { return InternalAttribute(attr); },
[&](Default) {
- ErrorInvalidAttribute(attribute, "struct members");
+ ErrorInvalidAttribute(attribute, StyledText{} << style::Keyword << "struct"
+ << style::Plain << " members");
return false;
});
if (!ok) {
@@ -4460,7 +4516,9 @@
}
if (has_offset_attr && (has_align_attr || has_size_attr)) {
- AddError(member->source) << "@offset cannot be used with @align or @size";
+ AddError(member->source) << style::Attribute << "@offset" << style::Plain
+ << " cannot be used with " << style::Attribute << "@align"
+ << style::Plain << " or " << style::Attribute << "@size";
return nullptr;
}
@@ -4525,8 +4583,9 @@
// https://gpuweb.github.io/gpuweb/wgsl/#limits
const size_t nest_depth = 1 + members_nest_depth;
if (nest_depth > kMaxNestDepthOfCompositeType) {
- AddError(str->source) << "struct '" << struct_name() << "' has nesting depth of "
- << nest_depth << ", maximum is " << kMaxNestDepthOfCompositeType;
+ AddError(str->source) << style::Keyword << "struct " << style::Type << struct_name()
+ << style::Plain << " has nesting depth of " << nest_depth
+ << ", maximum is " << kMaxNestDepthOfCompositeType;
return nullptr;
}
nest_depth_.Add(out, nest_depth);
@@ -4614,7 +4673,8 @@
attribute,
[&](const ast::DiagnosticAttribute* attr) { return DiagnosticAttribute(attr); },
[&](Default) {
- ErrorInvalidAttribute(attribute, "switch body");
+ ErrorInvalidAttribute(attribute, StyledText{} << style::Keyword << "switch"
+ << style::Plain << " body");
return false;
});
if (!ok) {
@@ -4870,8 +4930,9 @@
}
if (core::IsHostShareable(address_space) && !validator_.IsHostShareable(ty)) {
- AddError(usage) << "Type '" << sem_.TypeNameOf(ty) << "' cannot be used in address space '"
- << address_space << "' as it is non-host-shareable";
+ AddError(usage) << "type " << style::Type << sem_.TypeNameOf(ty) << style::Plain
+ << " cannot be used in address space " << style::Enum << address_space
+ << style::Plain << " as it is non-host-shareable";
return false;
}
@@ -4893,7 +4954,7 @@
attribute, //
[&](const ast::DiagnosticAttribute* attr) { return DiagnosticAttribute(attr); },
[&](Default) {
- ErrorInvalidAttribute(attribute, use);
+ ErrorInvalidAttribute(attribute, StyledText{} << use);
return false;
});
if (!ok) {
@@ -4979,8 +5040,8 @@
bool Resolver::CheckNotTemplated(const char* use, const ast::Identifier* ident) {
if (TINT_UNLIKELY(ident->Is<ast::TemplatedIdentifier>())) {
- AddError(ident->source) << use << " '" << ident->symbol.Name()
- << "' does not take template arguments";
+ AddError(ident->source) << use << " " << style::Code << ident->symbol.Name() << style::Plain
+ << " does not take template arguments";
if (auto resolved = dependencies_.resolved_identifiers.Get(ident)) {
if (auto* ast_node = resolved->Node()) {
sem_.NoteDeclarationSource(ast_node);
@@ -4991,8 +5052,9 @@
return true;
}
-void Resolver::ErrorInvalidAttribute(const ast::Attribute* attr, std::string_view use) {
- AddError(attr->source) << "@" << attr->Name() << " is not valid for " << std::string(use);
+void Resolver::ErrorInvalidAttribute(const ast::Attribute* attr, StyledText use) {
+ AddError(attr->source) << style::Attribute << "@" << attr->Name() << style::Plain
+ << " is not valid for " << use;
}
void Resolver::AddICE(std::string_view msg, const Source& source) const {
diff --git a/src/tint/lang/wgsl/resolver/resolver.h b/src/tint/lang/wgsl/resolver/resolver.h
index 73b27ef..5dcab43 100644
--- a/src/tint/lang/wgsl/resolver/resolver.h
+++ b/src/tint/lang/wgsl/resolver/resolver.h
@@ -636,7 +636,7 @@
/// Raises an error that the attribute is not valid for the given use.
/// @param attr the invalue attribute
/// @param use the thing that the attribute was applied to
- void ErrorInvalidAttribute(const ast::Attribute* attr, std::string_view use);
+ void ErrorInvalidAttribute(const ast::Attribute* attr, StyledText use);
/// Adds the given internal compiler error message to the diagnostics
void AddICE(std::string_view msg, const Source& source) const;
diff --git a/src/tint/lang/wgsl/resolver/resolver_test.cc b/src/tint/lang/wgsl/resolver/resolver_test.cc
index 4f0af3b..3d21f7a 100644
--- a/src/tint/lang/wgsl/resolver/resolver_test.cc
+++ b/src/tint/lang/wgsl/resolver/resolver_test.cc
@@ -2533,7 +2533,7 @@
}
Structure(Source{{12, 34}}, "S", std::move(members));
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: struct 'S' has 16384 members, maximum is 16383");
+ EXPECT_EQ(r()->error(), "12:34 error: 'struct S' has 16384 members, maximum is 16383");
}
TEST_F(ResolverTest, MaxNumStructMembers_WithIgnoreStructMemberLimit_Valid) {
@@ -2574,7 +2574,7 @@
s = Structure(source, "S" + std::to_string(i), Vector{Member("m", ty.Of(s))});
}
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: struct 'S254' has nesting depth of 256, maximum is 255");
+ EXPECT_EQ(r()->error(), "12:34 error: 'struct S254' has nesting depth of 256, maximum is 255");
}
TEST_F(ResolverTest, MaxNestDepthOfCompositeType_StructsWithVector_Valid) {
@@ -2596,7 +2596,7 @@
s = Structure(source, "S" + std::to_string(i), Vector{Member("m", ty.Of(s))});
}
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: struct 'S253' has nesting depth of 256, maximum is 255");
+ EXPECT_EQ(r()->error(), "12:34 error: 'struct S253' has nesting depth of 256, maximum is 255");
}
TEST_F(ResolverTest, MaxNestDepthOfCompositeType_StructsWithMatrix_Valid) {
@@ -2618,7 +2618,7 @@
s = Structure(source, "S" + std::to_string(i), Vector{Member("m", ty.Of(s))});
}
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: struct 'S252' has nesting depth of 256, maximum is 255");
+ EXPECT_EQ(r()->error(), "12:34 error: 'struct S252' has nesting depth of 256, maximum is 255");
}
TEST_F(ResolverTest, MaxNestDepthOfCompositeType_Arrays_Valid) {
@@ -2714,7 +2714,7 @@
s = Structure(source, "S" + std::to_string(i), Vector{Member("m", ty.Of(s))});
}
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "12:34 error: struct 'S251' has nesting depth of 256, maximum is 255");
+ EXPECT_EQ(r()->error(), "12:34 error: 'struct S251' has nesting depth of 256, maximum is 255");
}
TEST_F(ResolverTest, MaxNestDepthOfCompositeType_ArraysOfStruct_Valid) {
diff --git a/src/tint/lang/wgsl/resolver/sem_helper.cc b/src/tint/lang/wgsl/resolver/sem_helper.cc
index 25eeef5..5164284 100644
--- a/src/tint/lang/wgsl/resolver/sem_helper.cc
+++ b/src/tint/lang/wgsl/resolver/sem_helper.cc
@@ -72,7 +72,7 @@
if (auto* incomplete = type->As<IncompleteType>(); TINT_UNLIKELY(incomplete)) {
AddError(expr->Declaration()->source.End())
<< "expected " << style::Code << "<" << style::Plain << " for " << style::Type
- << incomplete->builtin << style::Plain;
+ << incomplete->builtin;
return nullptr;
}
@@ -95,7 +95,7 @@
[&](const ast::Parameter*) { text << "parameter"; }, //
[&](const ast::Override*) { text << style::Keyword << "override"; }, //
[&](Default) { text << "variable"; });
- text << " " << style::Variable << name << style::Plain;
+ text << " " << style::Variable << name;
},
[&](const sem::ValueExpression* val_expr) {
text << "value of type " << style::Type << val_expr->Type()->FriendlyName();
diff --git a/src/tint/lang/wgsl/resolver/subgroups_extension_test.cc b/src/tint/lang/wgsl/resolver/subgroups_extension_test.cc
index e8e784f..7fdb6c1 100644
--- a/src/tint/lang/wgsl/resolver/subgroups_extension_test.cc
+++ b/src/tint/lang/wgsl/resolver/subgroups_extension_test.cc
@@ -48,7 +48,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(error: use of @builtin(subgroup_size) attribute requires enabling extension 'chromium_experimental_subgroups')");
+ R"(error: use of '@builtin(subgroup_size)' attribute requires enabling extension 'chromium_experimental_subgroups')");
}
// Using a subgroup_invocation_id builtin attribute without chromium_experimental_subgroups enabled
@@ -62,7 +62,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
- R"(error: use of @builtin(subgroup_invocation_id) attribute requires enabling extension 'chromium_experimental_subgroups')");
+ R"(error: use of '@builtin(subgroup_invocation_id)' attribute requires enabling extension 'chromium_experimental_subgroups')");
}
// Using an i32 for a subgroup_size builtin input should fail.
@@ -74,7 +74,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "error: store type of @builtin(subgroup_size) must be 'u32'");
+ EXPECT_EQ(r()->error(), "error: store type of '@builtin(subgroup_size)' must be 'u32'");
}
// Using an i32 for a subgroup_invocation_id builtin input should fail.
@@ -86,7 +86,8 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), "error: store type of @builtin(subgroup_invocation_id) must be 'u32'");
+ EXPECT_EQ(r()->error(),
+ "error: store type of '@builtin(subgroup_invocation_id)' must be 'u32'");
}
// Using builtin(subgroup_size) for anything other than a compute shader input should fail.
@@ -98,7 +99,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "error: @builtin(subgroup_size) is only valid as a compute shader input");
+ "error: '@builtin(subgroup_size)' is only valid as a compute shader input");
}
// Using builtin(subgroup_invocation_id) for anything other than a compute shader input should fail.
@@ -110,7 +111,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "error: @builtin(subgroup_invocation_id) is only valid as a compute shader input");
+ "error: '@builtin(subgroup_invocation_id)' is only valid as a compute shader input");
}
} // namespace
diff --git a/src/tint/lang/wgsl/resolver/type_validation_test.cc b/src/tint/lang/wgsl/resolver/type_validation_test.cc
index f89f25c..8d191a8 100644
--- a/src/tint/lang/wgsl/resolver/type_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/type_validation_test.cc
@@ -384,7 +384,7 @@
GlobalVar("a", ty.array(Source{{12, 34}}, ty.f32(), "size"), core::AddressSpace::kPrivate);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: array with an 'override' element count can only be used as the store "
+ "12:34 error: 'array' with an 'override' element count can only be used as the store "
"type of a 'var<workgroup>'");
}
@@ -396,7 +396,7 @@
core::AddressSpace::kWorkgroup);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: array with an 'override' element count can only be used as the store "
+ "12:34 error: 'array' with an 'override' element count can only be used as the store "
"type of a 'var<workgroup>'");
}
@@ -409,7 +409,7 @@
Structure("S", Vector{Member("a", ty.array(Source{{12, 34}}, ty.f32(), "size"))});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: array with an 'override' element count can only be used as the store "
+ "12:34 error: 'array' with an 'override' element count can only be used as the store "
"type of a 'var<workgroup>'");
}
@@ -425,7 +425,7 @@
});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: array with an 'override' element count can only be used as the store "
+ "12:34 error: 'array' with an 'override' element count can only be used as the store "
"type of a 'var<workgroup>'");
}
@@ -441,7 +441,7 @@
});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: array with an 'override' element count can only be used as the store "
+ "12:34 error: 'array' with an 'override' element count can only be used as the store "
"type of a 'var<workgroup>'");
}
@@ -459,7 +459,7 @@
});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: array with an 'override' element count can only be used as the store "
+ "12:34 error: 'array' with an 'override' element count can only be used as the store "
"type of a 'var<workgroup>'");
}
@@ -477,7 +477,7 @@
});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: array with an 'override' element count can only be used as the store "
+ "12:34 error: 'array' with an 'override' element count can only be used as the store "
"type of a 'var<workgroup>'");
}
diff --git a/src/tint/lang/wgsl/resolver/validation_test.cc b/src/tint/lang/wgsl/resolver/validation_test.cc
index a3c74fd..809ade9 100644
--- a/src/tint/lang/wgsl/resolver/validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/validation_test.cc
@@ -1194,7 +1194,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(12:34 error: @align value must be a positive, power-of-two integer)");
+ R"(12:34 error: '@align' value must be a positive, power-of-two integer)");
}
TEST_F(ResolverValidationTest, NonPOTStructMemberAlignAttribute) {
@@ -1204,7 +1204,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(12:34 error: @align value must be a positive, power-of-two integer)");
+ R"(12:34 error: '@align' value must be a positive, power-of-two integer)");
}
TEST_F(ResolverValidationTest, ZeroStructMemberAlignAttribute) {
@@ -1214,7 +1214,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(12:34 error: @align value must be a positive, power-of-two integer)");
+ R"(12:34 error: '@align' value must be a positive, power-of-two integer)");
}
TEST_F(ResolverValidationTest, ZeroStructMemberSizeAttribute) {
@@ -1223,7 +1223,8 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: @size must be at least as big as the type's size (4))");
+ EXPECT_EQ(r()->error(),
+ R"(12:34 error: '@size' must be at least as big as the type's size (4))");
}
TEST_F(ResolverValidationTest, OffsetAndSizeAttribute) {
@@ -1233,7 +1234,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: @offset cannot be used with @align or @size)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@offset' cannot be used with '@align' or '@size')");
}
TEST_F(ResolverValidationTest, OffsetAndAlignAttribute) {
@@ -1243,7 +1244,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: @offset cannot be used with @align or @size)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@offset' cannot be used with '@align' or '@size')");
}
TEST_F(ResolverValidationTest, OffsetAndAlignAndSizeAttribute) {
@@ -1253,7 +1254,7 @@
});
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: @offset cannot be used with @align or @size)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: '@offset' cannot be used with '@align' or '@size')");
}
TEST_F(ResolverTest, Expr_Initializer_Cast_Pointer) {
diff --git a/src/tint/lang/wgsl/resolver/validator.cc b/src/tint/lang/wgsl/resolver/validator.cc
index bf18b93..9546c27 100644
--- a/src/tint/lang/wgsl/resolver/validator.cc
+++ b/src/tint/lang/wgsl/resolver/validator.cc
@@ -88,6 +88,8 @@
#include "src/tint/utils/math/math.h"
#include "src/tint/utils/text/string.h"
#include "src/tint/utils/text/string_stream.h"
+#include "src/tint/utils/text/styled_text.h"
+#include "src/tint/utils/text/text_style.h"
using namespace tint::core::fluent_types; // NOLINT
@@ -134,11 +136,6 @@
}
}
-// Helper to stringify a pipeline IO attribute.
-StyledText AttrToStr(const ast::Attribute* attr) {
- return StyledText{} << "@" << attr->Name();
-}
-
template <typename CALLBACK>
void TraverseCallChain(const sem::Function* from, const sem::Function* to, CALLBACK&& callback) {
for (auto* f : from->TransitivelyCalledFunctions()) {
@@ -312,9 +309,10 @@
for (auto pair : incompatible) {
if (enabled_extensions_.Contains(pair.first) && enabled_extensions_.Contains(pair.second)) {
AddError(source_of(pair.first))
- << "extension '" << pair.first << "' cannot be used with extension '" << pair.second
- << "'";
- AddNote(source_of(pair.second)) << "'" << pair.second << "' enabled here";
+ << "extension " << style::Code << pair.first << style::Plain
+ << " cannot be used with extension " << style::Code << pair.second;
+ AddNote(source_of(pair.second))
+ << style::Code << pair.second << style::Plain << " enabled here";
return false;
}
}
@@ -431,8 +429,8 @@
const core::type::Type* from,
const Source& source) const {
if (core::type::Type::ConversionRank(from, to) == core::type::Type::kNoConversion) {
- AddError(source) << "cannot convert value of type '" << sem_.TypeNameOf(from)
- << "' to type '" << sem_.TypeNameOf(to) << "'";
+ AddError(source) << "cannot convert value of type " << style::Type << sem_.TypeNameOf(from)
+ << style::Plain << " to type " << style::Type << sem_.TypeNameOf(to);
return false;
}
return true;
@@ -446,9 +444,10 @@
// Value type has to match storage type
if (storage_ty != value_type) {
- AddError(v->source) << "cannot initialize " << v->Kind() << " of type '"
- << sem_.TypeNameOf(storage_ty) << "' with value of type '"
- << sem_.TypeNameOf(initializer_ty) << "'";
+ AddError(v->source) << "cannot initialize " << style::Keyword << v->Kind() << style::Plain
+ << " of type " << style::Type << sem_.TypeNameOf(storage_ty)
+ << style::Plain << " with value of type " << style::Type
+ << sem_.TypeNameOf(initializer_ty);
return false;
}
@@ -490,16 +489,18 @@
}
auto note_usage = [&] {
- AddNote(source) << "'" << store_ty->FriendlyName() << "' used in address space '"
- << address_space << "' here";
+ AddNote(source) << style::Type << store_ty->FriendlyName() << style::Plain
+ << " used in address space " << style::Enum << address_space << style::Plain
+ << " here";
};
// Among three host-shareable address spaces, f16 is supported in "uniform" and
// "storage" address space, but not "push_constant" address space yet.
if (Is<core::type::F16>(store_ty->DeepestElement()) &&
address_space == core::AddressSpace::kPushConstant) {
- AddError(source)
- << "using f16 types in 'push_constant' address space is not implemented yet";
+ AddError(source) << "using " << style::Type << "f16" << style::Plain << " in "
+ << style::Enum << "push_constant" << style::Plain
+ << " address space is not implemented yet";
return false;
}
@@ -520,12 +521,14 @@
!enabled_extensions_.Contains(
wgsl::Extension::kChromiumInternalRelaxedUniformLayout)) {
AddError(m->Declaration()->source)
- << "the offset of a struct member of type '"
- << m->Type()->UnwrapRef()->FriendlyName() << "' in address space '"
- << address_space << "' must be a multiple of " << required_align
- << " bytes, but '" << member_name_of(m) << "' is currently at offset "
- << m->Offset() << ". Consider setting @align(" << required_align
- << ") on this member";
+ << "the offset of a struct member of type " << style::Type
+ << m->Type()->UnwrapRef()->FriendlyName() << style::Plain
+ << " in address space " << style::Enum << address_space << style::Plain
+ << " must be a multiple of " << required_align << " bytes, but "
+ << style::Variable << member_name_of(m) << style::Plain
+ << " is currently at offset " << m->Offset() << ". Consider setting "
+ << style::Attribute << "@align" << style::Code << "(" << required_align << ")"
+ << style::Plain << " on this member";
AddNote(str->Declaration()->source) << "see layout of struct:\n" << str->Layout();
@@ -547,12 +550,15 @@
!enabled_extensions_.Contains(
wgsl::Extension::kChromiumInternalRelaxedUniformLayout)) {
AddError(m->Declaration()->source)
- << "uniform storage requires that the number of bytes between the start of "
- "the previous member of type struct and the current member be a "
+ << style::Enum << "uniform" << style::Plain
+ << " storage requires that the number of bytes between the start of the "
+ "previous member of type struct and the current member be a "
"multiple of 16 bytes, but there are currently "
- << prev_to_curr_offset << " bytes between '" << member_name_of(prev_member)
- << "' and '" << member_name_of(m)
- << "'. Consider setting @align(16) on this member";
+ << prev_to_curr_offset << " bytes between " << style::Variable
+ << member_name_of(prev_member) << style::Plain << " and " << style::Variable
+ << member_name_of(m) << style::Plain << ". Consider setting "
+ << style::Attribute << "@align" << style::Code << "(16)" << style::Plain
+ << " on this member";
AddNote(str->Declaration()->source) << "see layout of struct:\n"
<< str->Layout();
@@ -585,23 +591,24 @@
if (arr->Stride() % 16 != 0) {
// Since WGSL has no stride attribute, try to provide a useful hint for how the
// shader author can resolve the issue.
- std::string_view hint;
+ StyledText hint;
if (arr->ElemType()->Is<core::type::Scalar>()) {
- hint = "Consider using a vector or struct as the element type instead.";
+ hint << "Consider using a vector or struct as the element type instead.";
} else if (auto* vec = arr->ElemType()->As<core::type::Vector>();
vec && vec->type()->Size() == 4) {
- hint = "Consider using a vec4 instead.";
+ hint << "Consider using a vec4 instead.";
} else if (arr->ElemType()->Is<sem::Struct>()) {
- hint = "Consider using the @size attribute on the last struct member.";
+ hint << "Consider using the " << style::Attribute << "@size" << style::Plain
+ << " attribute on the last struct member.";
} else {
- hint =
- "Consider wrapping the element type in a struct and using the @size "
- "attribute.";
+ hint << "Consider wrapping the element type in a struct and using the "
+ << style::Attribute << "@size" << style::Plain << " attribute.";
}
- AddError(source) << "uniform storage requires that array elements are aligned to "
- "16 bytes, but array element of type '"
- << arr->ElemType()->FriendlyName() << "' has a stride of "
- << arr->Stride() << " bytes. " << hint;
+ AddError(source) << style::Enum << "uniform" << style::Plain
+ << " storage requires that array elements are aligned to "
+ "16 bytes, but array element of type "
+ << style::Type << arr->ElemType()->FriendlyName() << style::Plain
+ << " has a stride of " << arr->Stride() << " bytes. " << hint;
return false;
}
}
@@ -624,7 +631,8 @@
ast::DisabledValidation::kIgnoreAddressSpace)) {
if (!local->Type()->UnwrapRef()->IsConstructible()) {
AddError(var->type ? var->type->source : var->source)
- << "function-scope 'var' must have a constructible type";
+ << "function-scope " << style::Keyword << "var" << style::Plain
+ << " must have a constructible type";
return false;
}
}
@@ -651,13 +659,15 @@
if (auto* init = global->Initializer();
init && init->Stage() > core::EvaluationStage::kOverride) {
AddError(init->Declaration()->source)
- << "module-scope 'var' initializer must be a constant or "
+ << "module-scope " << style::Keyword << "var" << style::Plain
+ << " initializer must be a constant or "
"override-expression";
return false;
}
if (!var->declared_address_space && !global->Type()->UnwrapRef()->is_handle()) {
- AddError(decl->source) << "module-scope 'var' declarations that are not of texture "
+ AddError(decl->source) << "module-scope " << style::Keyword << "var" << style::Plain
+ << " declarations that are not of texture "
"or sampler types must "
"provide an address space";
return false;
@@ -674,7 +684,8 @@
}
if (global->AddressSpace() == core::AddressSpace::kFunction) {
- AddError(decl->source) << "module-scope 'var' must not use address space 'function'";
+ AddError(decl->source) << "module-scope " << style::Keyword << "var" << style::Plain
+ << " must not use address space " << style::Enum << "function";
return false;
}
@@ -686,7 +697,8 @@
// Each resource variable must be declared with both group and binding attributes.
if (!decl->HasBindingPoint()) {
AddError(decl->source)
- << "resource variables require @group and @binding attributes";
+ << "resource variables require " << style::Attribute << "@group" << style::Plain
+ << " and " << style::Attribute << "@binding" << style::Plain << " attributes";
return false;
}
break;
@@ -698,7 +710,9 @@
// https://gpuweb.github.io/gpuweb/wgsl/#attribute-binding
// Must only be applied to a resource variable
AddError(decl->source)
- << "non-resource variables must not have @group or @binding attributes";
+ << "non-resource variables must not have " << style::Attribute << "@group"
+ << style::Plain << " or " << style::Attribute << "@binding" << style::Plain
+ << " attributes";
return false;
}
}
@@ -721,8 +735,8 @@
// https://gpuweb.github.io/gpuweb/wgsl/#module-scope-variables
// If the store type is a texture type or a sampler type, then the variable declaration must
// not have a address space attribute. The address space will always be handle.
- AddError(var->source) << "variables of type '" << sem_.TypeNameOf(store_ty)
- << "' must not specifiy an address space";
+ AddError(var->source) << "variables of type " << style::Type << sem_.TypeNameOf(store_ty)
+ << style::Plain << " must not specifiy an address space";
return false;
}
@@ -748,9 +762,11 @@
// Optionally has an initializer expression, if the variable is in the private or
// function address spaces.
AddError(var->source)
- << "var of address space '" << v->AddressSpace()
- << "' cannot have an initializer. var initializers are only supported for "
- "the address spaces 'private' and 'function'";
+ << "var of address space " << style::Enum << v->AddressSpace() << style::Plain
+ << " cannot have an initializer. var initializers are only supported for "
+ "the address spaces "
+ << style::Enum << "private" << style::Plain << " and " << style::Enum
+ << "function";
return false;
}
}
@@ -774,8 +790,8 @@
auto* storage_ty = v->Type()->UnwrapRef();
if (!(storage_ty->IsConstructible() || storage_ty->Is<core::type::Pointer>())) {
- AddError(decl->source) << sem_.TypeNameOf(storage_ty)
- << " cannot be used as the type of a 'let'";
+ AddError(decl->source) << sem_.TypeNameOf(storage_ty) << " cannot be used as the type of a "
+ << style::Keyword << "let";
return false;
}
return true;
@@ -787,24 +803,25 @@
auto* storage_ty = v->Type()->UnwrapRef();
if (auto* init = v->Initializer(); init && init->Stage() > core::EvaluationStage::kOverride) {
- AddError(init->Declaration()->source)
- << "'override' initializer must be an override-expression";
+ AddError(init->Declaration()->source) << style::Keyword << "override" << style::Plain
+ << " initializer must be an override-expression";
return false;
}
if (auto id = v->Attributes().override_id) {
if (auto var = override_ids.Get(*id); var && *var != v) {
auto* attr = ast::GetAttribute<ast::IdAttribute>(v->Declaration()->attributes);
- AddError(attr->source) << "@id values must be unique";
+ AddError(attr->source)
+ << style::Attribute << "@id" << style::Plain << " values must be unique";
AddNote(ast::GetAttribute<ast::IdAttribute>((*var)->Declaration()->attributes)->source)
- << "a override with an ID of " << id->value << " was previously declared here:";
+ << "a override with an ID of " << id->value << " was previously declared here";
return false;
}
}
if (!storage_ty->Is<core::type::Scalar>()) {
- AddError(decl->source) << sem_.TypeNameOf(storage_ty)
- << " cannot be used as the type of a 'override'";
+ AddError(decl->source) << sem_.TypeNameOf(storage_ty) << " cannot be used as the type of a "
+ << style::Keyword << "override";
return false;
}
@@ -842,8 +859,8 @@
break;
}
if (!ok) {
- AddError(decl->source) << "function parameter of pointer type cannot be in '" << sc
- << "' address space";
+ AddError(decl->source) << "function parameter of pointer type cannot be in "
+ << style::Enum << sc << style::Plain << " address space";
return false;
}
}
@@ -874,6 +891,13 @@
bool is_stage_mismatch = false;
bool is_output = !is_input;
auto builtin = sem_.Get(attr)->Value();
+
+ auto err_builtin_type = [&](const char* required) {
+ AddError(attr->source) << "store type of " << style::Attribute << "@builtin" << style::Code
+ << "(" << style::Enum << builtin << style::Code << ")"
+ << style::Plain << " must be " << style::Type << required;
+ };
+
switch (builtin) {
case core::BuiltinValue::kPosition: {
if (stage != ast::PipelineStage::kNone &&
@@ -883,8 +907,7 @@
}
auto* vec = type->As<core::type::Vector>();
if (!(vec && vec->Width() == 4 && vec->type()->Is<core::type::F32>())) {
- AddError(attr->source)
- << "store type of @builtin(" << builtin << ") must be 'vec4<f32>'";
+ err_builtin_type("vec4<f32>");
return false;
}
break;
@@ -899,8 +922,7 @@
}
if (!(type->is_unsigned_integer_vector() &&
type->As<core::type::Vector>()->Width() == 3)) {
- AddError(attr->source)
- << "store type of @builtin(" << builtin << ") must be 'vec3<u32>'";
+ err_builtin_type("vec3<u32>");
return false;
}
break;
@@ -910,7 +932,7 @@
is_stage_mismatch = true;
}
if (!type->Is<core::type::F32>()) {
- AddError(attr->source) << "store type of @builtin(" << builtin << ") must be 'f32'";
+ err_builtin_type("f32");
return false;
}
break;
@@ -920,8 +942,7 @@
is_stage_mismatch = true;
}
if (!type->Is<core::type::Bool>()) {
- AddError(attr->source)
- << "store type of @builtin(" << builtin << ") must be 'bool'";
+ err_builtin_type("bool");
return false;
}
break;
@@ -931,7 +952,7 @@
is_stage_mismatch = true;
}
if (!type->Is<core::type::U32>()) {
- AddError(attr->source) << "store type of @builtin(" << builtin << ") must be 'u32'";
+ err_builtin_type("u32");
return false;
}
break;
@@ -942,7 +963,7 @@
is_stage_mismatch = true;
}
if (!type->Is<core::type::U32>()) {
- AddError(attr->source) << "store type of @builtin(" << builtin << ") must be 'u32'";
+ err_builtin_type("u32");
return false;
}
break;
@@ -951,7 +972,7 @@
is_stage_mismatch = true;
}
if (!type->Is<core::type::U32>()) {
- AddError(attr->source) << "store type of @builtin(" << builtin << ") must be 'u32'";
+ err_builtin_type("u32");
return false;
}
break;
@@ -961,25 +982,28 @@
is_stage_mismatch = true;
}
if (!type->Is<core::type::U32>()) {
- AddError(attr->source) << "store type of @builtin(" << builtin << ") must be 'u32'";
+ err_builtin_type("u32");
return false;
}
break;
case core::BuiltinValue::kSubgroupInvocationId:
case core::BuiltinValue::kSubgroupSize:
if (!enabled_extensions_.Contains(wgsl::Extension::kChromiumExperimentalSubgroups)) {
- AddError(attr->source)
- << "use of @builtin(" << builtin
- << ") attribute requires enabling extension 'chromium_experimental_subgroups'";
+ AddError(attr->source) << "use of " << style::Attribute << "@builtin" << style::Code
+ << "(" << style::Enum << builtin << style::Code << ")"
+ << style::Plain << " attribute requires enabling extension "
+ << style::Code << "chromium_experimental_subgroups";
return false;
}
if (!type->Is<core::type::U32>()) {
- AddError(attr->source) << "store type of @builtin(" << builtin << ") must be 'u32'";
+ err_builtin_type("u32");
return false;
}
if (stage != ast::PipelineStage::kNone && stage != ast::PipelineStage::kCompute) {
AddError(attr->source)
- << "@builtin(" << builtin << ") is only valid as a compute shader input";
+ << style::Attribute << "@builtin" << style::Code << "(" << style::Enum
+ << builtin << style::Code << ")" << style::Plain
+ << " is only valid as a compute shader input";
return false;
}
break;
@@ -988,8 +1012,10 @@
}
if (is_stage_mismatch) {
- AddError(attr->source) << "@builtin(" << builtin << ") cannot be used for "
- << stage_name.str() << " shader " << (is_input ? "input" : "output");
+ AddError(attr->source) << style::Attribute << "@builtin" << style::Code << "("
+ << style::Enum << builtin << style::Code << ")" << style::Plain
+ << " cannot be used for " << stage_name.str() << " shader "
+ << (is_input ? "input" : "output");
return false;
}
@@ -1000,7 +1026,8 @@
const core::type::Type* storage_ty,
const ast::PipelineStage stage) const {
if (stage == ast::PipelineStage::kCompute) {
- AddError(attr->source) << AttrToStr(attr) << " cannot be used by compute shaders";
+ AddError(attr->source) << style::Attribute << "@" << attr->Name() << style::Plain
+ << " cannot be used by compute shaders";
return false;
}
@@ -1012,8 +1039,8 @@
}
if (type->is_integer_scalar_or_vector() && i_type->Value() != core::InterpolationType::kFlat) {
- AddError(attr->source)
- << "interpolation type must be 'flat' for integral user-defined IO types";
+ AddError(attr->source) << "interpolation type must be " << style::Enum << "flat"
+ << style::Plain << " for integral user-defined IO types";
return false;
}
@@ -1028,7 +1055,8 @@
bool Validator::InvariantAttribute(const ast::InvariantAttribute* attr,
const ast::PipelineStage stage) const {
if (stage == ast::PipelineStage::kCompute) {
- AddError(attr->source) << AttrToStr(attr) << " cannot be used by compute shaders";
+ AddError(attr->source) << style::Attribute << "@" << attr->Name() << style::Plain
+ << " cannot be used by compute shaders";
return false;
}
return true;
@@ -1042,7 +1070,8 @@
attr, //
[&](const ast::WorkgroupAttribute*) {
if (decl->PipelineStage() != ast::PipelineStage::kCompute) {
- AddError(attr->source) << "@workgroup_size is only valid for compute stages";
+ AddError(attr->source) << style::Attribute << "@workgroup_size" << style::Plain
+ << " is only valid for compute stages";
return false;
}
return true;
@@ -1050,7 +1079,8 @@
[&](const ast::MustUseAttribute*) {
if (func->ReturnType()->Is<core::type::Void>()) {
AddError(attr->source)
- << "@must_use can only be applied to functions that return a value";
+ << style::Attribute << "@must_use" << style::Plain
+ << " can only be applied to functions that return a value";
return false;
}
return true;
@@ -1085,7 +1115,7 @@
}
} else if (TINT_UNLIKELY(IsValidationEnabled(
decl->attributes, ast::DisabledValidation::kFunctionHasNoBody))) {
- TINT_ICE() << "Function " << decl->name->symbol.Name() << " has no body";
+ TINT_ICE() << "function " << decl->name->symbol.Name() << " has no body";
}
}
@@ -1150,14 +1180,17 @@
if (pipeline_io_attribute) {
AddError(attr->source) << "multiple entry point IO attributes";
AddNote(pipeline_io_attribute->source)
- << "previously consumed " << AttrToStr(pipeline_io_attribute);
+ << "previously consumed " << style::Attribute << "@"
+ << pipeline_io_attribute->Name();
return false;
}
pipeline_io_attribute = attr;
if (builtins.Contains(builtin)) {
AddError(decl->source)
- << "@builtin(" << builtin << ") appears multiple times as pipeline "
+ << style::Attribute << "@builtin" << style::Code << "(" << style::Enum
+ << builtin << style::Code << ")" << style::Plain
+ << " appears multiple times as pipeline "
<< (param_or_ret == ParamOrRetType::kParameter ? "input" : "output");
return false;
}
@@ -1175,7 +1208,8 @@
if (pipeline_io_attribute) {
AddError(attr->source) << "multiple entry point IO attributes";
AddNote(pipeline_io_attribute->source)
- << "previously consumed " << AttrToStr(pipeline_io_attribute);
+ << "previously consumed " << style::Attribute << "@"
+ << pipeline_io_attribute->Name();
return false;
}
pipeline_io_attribute = attr;
@@ -1202,7 +1236,8 @@
if (pipeline_io_attribute) {
AddError(attr->source) << "multiple entry point IO attributes";
AddNote(pipeline_io_attribute->source)
- << "previously consumed " << AttrToStr(pipeline_io_attribute);
+ << "previously consumed " << style::Attribute << "@"
+ << pipeline_io_attribute->Name();
return false;
}
pipeline_io_attribute = attr;
@@ -1251,15 +1286,17 @@
if (decl->PipelineStage() == ast::PipelineStage::kVertex &&
param_or_ret == ParamOrRetType::kReturnType) {
AddError(source) << "integral user-defined vertex outputs must have a "
- "flat interpolation "
- "attribute";
+ << style::Attribute << "@interpolate" << style::Code << "("
+ << style::Enum << "flat" << style::Code << ")"
+ << style::Plain << " attribute";
return false;
}
if (decl->PipelineStage() == ast::PipelineStage::kFragment &&
param_or_ret == ParamOrRetType::kParameter) {
- AddError(source) << "integral user-defined fragment inputs must have "
- "a flat interpolation "
- "attribute";
+ AddError(source) << "integral user-defined fragment inputs must have a "
+ << style::Attribute << "@interpolate" << style::Code << "("
+ << style::Enum << "flat" << style::Code << ")"
+ << style::Plain << " attribute";
return false;
}
}
@@ -1271,7 +1308,9 @@
// in the backend writers.
if (location.value_or(1) != 0) {
AddError(blend_src_attribute->source)
- << "@blend_src can only be used with @location(0)";
+ << style::Attribute << "@blend_src" << style::Plain
+ << " can only be used with " << style::Attribute << "@location"
+ << style::Code << "(" << style::Literal << "0" << style::Code << ")";
return false;
}
}
@@ -1284,10 +1323,12 @@
if (first_blend_src && first_location_without_blend_src) {
AddError(first_location_without_blend_src->source)
- << "use of @blend_src requires all the output @location "
- "attributes of the entry "
- "point to be paired with a @blend_src attribute";
- AddNote(first_blend_src->source) << "use of @blend_src here";
+ << "use of " << style::Attribute << "@blend_src" << style::Plain
+ << " requires all the output " << style::Attribute << "@location"
+ << style::Plain << " attributes of the entry point to be paired with a "
+ << style::Attribute << "@blend_src" << style::Plain << " attribute";
+ AddNote(first_blend_src->source)
+ << "use of " << style::Attribute << "@blend_src" << style::Plain << " here";
return false;
}
@@ -1297,8 +1338,11 @@
}
if (first_nonzero_location && first_blend_src) {
AddError(first_blend_src->source)
- << "pipeline cannot use both a @blend_src and non-zero @location";
- AddNote(first_nonzero_location->source) << "non-zero @location declared here";
+ << "pipeline cannot use both a " << style::Attribute << "@blend_src"
+ << style::Plain << " and non-zero " << style::Attribute << "@location";
+ AddNote(first_nonzero_location->source)
+ << "non-zero " << style::Attribute << "@location" << style::Plain
+ << " declared here";
return false;
}
@@ -1306,18 +1350,22 @@
blend_src.value_or(0));
if (!locations_and_blend_srcs.Add(location_and_blend_src)) {
auto& err = AddError(location_attribute->source)
- << "@location(" << location.value() << ") ";
+ << style::Attribute << "@location" << style::Code << "("
+ << style::Literal << location.value() << style::Code << ")";
if (blend_src_attribute) {
- err << "@blend_src(" << blend_src.value() << ") ";
+ err << style::Attribute << " @blend_src" << style::Code << "("
+ << style::Literal << blend_src.value() << style::Code << ")";
}
- err << "appears multiple times";
+ err << style::Plain << " appears multiple times";
return false;
}
}
if (color_attribute && !colors.Add(color.value())) {
AddError(color_attribute->source)
- << "@color(" << color.value() << ") appears multiple times";
+ << style::Attribute << "@color" << style::Code << "(" << style::Literal
+ << color.value() << style::Code << ")" << style::Plain
+ << " appears multiple times";
return false;
}
@@ -1325,7 +1373,8 @@
if (!pipeline_io_attribute ||
!pipeline_io_attribute->Is<ast::LocationAttribute>()) {
AddError(interpolate_attribute->source)
- << "@interpolate can only be used with @location";
+ << style::Attribute << "@interpolate" << style::Plain
+ << " can only be used with " << style::Attribute << "@location";
return false;
}
}
@@ -1340,7 +1389,9 @@
}
if (!has_position) {
AddError(invariant_attribute->source)
- << "@invariant must be applied to a position builtin";
+ << style::Attribute << "@invariant" << style::Plain
+ << " must be applied to a " << style::Attribute << "@builtin" << style::Code
+ << "(" << style::Enum << "position" << style::Code << ")";
return false;
}
}
@@ -1366,8 +1417,8 @@
member->Declaration()->source, param_or_ret,
/*is_struct_member*/ true, member->Attributes().location,
member->Attributes().blend_src, member->Attributes().color)) {
- AddNote(decl->source)
- << "while analyzing entry point '" << decl->name->symbol.Name() << "'";
+ AddNote(decl->source) << "while analyzing entry point " << style::Function
+ << decl->name->symbol.Name();
return false;
}
}
@@ -1418,16 +1469,16 @@
}
}
if (!found) {
- AddError(decl->source)
- << "a vertex shader must include the 'position' builtin in its return type";
+ AddError(decl->source) << "a vertex shader must include the " << style::Enum
+ << "position" << style::Plain << " builtin in its return type";
return false;
}
}
if (decl->PipelineStage() == ast::PipelineStage::kCompute) {
if (!ast::HasAttribute<ast::WorkgroupAttribute>(decl->attributes)) {
- AddError(decl->source)
- << "a compute shader must include 'workgroup_size' in its attributes";
+ AddError(decl->source) << "a compute shader must include " << style::Attribute
+ << "@workgroup_size" << style::Plain << " in its attributes";
return false;
}
}
@@ -1454,10 +1505,12 @@
// resource interface of a given shader must not have the same group and binding values,
// when considered as a pair of values.
auto func_name = decl->name->symbol.Name();
- AddError(var_decl->source) << "entry point '" << func_name
- << "' references multiple variables that use the same "
- "resource binding @group("
- << bp->group << "), @binding(" << bp->binding << ")";
+ AddError(var_decl->source)
+ << "entry point " << style::Function << func_name << style::Plain
+ << " references multiple variables that use the same resource binding "
+ << style::Attribute << "@group" << style::Code << "(" << style::Literal << bp->group
+ << style::Code << ")" << style::Plain << ", " << style::Attribute << "@binding"
+ << style::Code << "(" << style::Literal << bp->binding << style::Code << ")";
AddNote(added.value->source) << "first resource binding usage declared here";
return false;
}
@@ -1494,7 +1547,8 @@
if (auto* stmt = expr->Stmt()) {
if (auto* decl = As<ast::VariableDeclStatement>(stmt->Declaration())) {
if (decl->variable->Is<ast::Const>()) {
- AddNote(decl->source) << "consider changing 'const' to 'let'";
+ AddNote(decl->source) << "consider changing " << style::Keyword << "const"
+ << style::Plain << " to " << style::Keyword << "let";
}
}
}
@@ -1570,13 +1624,14 @@
call->Target(), //
[&](const sem::Function* fn) {
AddError(call->Declaration()->source)
- << "ignoring return value of function '"
- << fn->Declaration()->name->symbol.Name() + "' annotated with @must_use";
+ << "ignoring return value of function " << style::Function
+ << fn->Declaration()->name->symbol.Name() << style::Plain << " annotated with "
+ << style::Attribute << "@must_use";
sem_.NoteDeclarationSource(fn->Declaration());
},
[&](const sem::BuiltinFn* b) {
AddError(call->Declaration()->source)
- << "ignoring return value of builtin '" << b->Fn() << "'";
+ << "ignoring return value of builtin " << style::Function << b->Fn();
},
[&](const sem::ValueConversion*) {
AddError(call->Declaration()->source) << "value conversion evaluated but not used";
@@ -1690,7 +1745,8 @@
// used instead.
auto* builtin = call->Target()->As<sem::BuiltinFn>();
AddError(call->Declaration()->source)
- << "builtin function '" << builtin->Fn() << "' does not return a value";
+ << "builtin function " << style::Function << builtin->Fn() << style::Plain
+ << " does not return a value";
return false;
}
}
@@ -1795,8 +1851,8 @@
if (extension != wgsl::Extension::kUndefined) {
if (!enabled_extensions_.Contains(extension)) {
AddError(call->Declaration()->source)
- << "cannot call built-in function '" << builtin->Fn() << "' without extension "
- << extension;
+ << "cannot call built-in function " << style::Function << builtin->Fn()
+ << style::Plain << " without extension " << extension;
return false;
}
}
@@ -1805,8 +1861,8 @@
if (feature != wgsl::LanguageFeature::kUndefined) {
if (!allowed_features_.features.count(feature)) {
AddError(call->Declaration()->source)
- << "built-in function '" << builtin->Fn() << "' requires the "
- << wgsl::ToString(feature)
+ << "built-in function " << style::Function << builtin->Fn() << style::Plain
+ << " requires the " << style::Code << wgsl::ToString(feature) << style::Plain
<< " language feature, which is not allowed in the current environment";
return false;
}
@@ -1818,7 +1874,8 @@
bool Validator::CheckF16Enabled(const Source& source) const {
// Validate if f16 type is allowed.
if (!enabled_extensions_.Contains(wgsl::Extension::kF16)) {
- AddError(source) << "f16 type used without 'f16' extension enabled";
+ AddError(source) << style::Type << "f16" << style::Plain << " type used without "
+ << style::Code << "f16" << style::Plain << " extension enabled";
return false;
}
return true;
@@ -1846,9 +1903,10 @@
bool more = decl->args.Length() > target->Parameters().Length();
AddError(decl->source) << "too "
<< (more ? std::string("many") : std::string("few")) +
- " arguments in call to '"
- << name << "', expected " << target->Parameters().Length()
- << ", got " << call->Arguments().Length();
+ " arguments in call to "
+ << style::Function << name << style::Plain << ", expected "
+ << target->Parameters().Length() << ", got "
+ << call->Arguments().Length();
return false;
}
@@ -1859,10 +1917,10 @@
auto* arg_type = sem_.TypeOf(arg_expr)->UnwrapRef();
if (param_type != arg_type) {
- AddError(arg_expr->source)
- << "type mismatch for argument " << (i + 1) << " in call to '" << name
- << "', expected '" << sem_.TypeNameOf(param_type) << "', got '"
- << sem_.TypeNameOf(arg_type) << "'";
+ AddError(arg_expr->source) << "type mismatch for argument " << (i + 1) << " in call to "
+ << style::Function << name << style::Plain << ", expected "
+ << style::Type << sem_.TypeNameOf(param_type) << style::Plain
+ << ", got " << style::Type << sem_.TypeNameOf(arg_type);
return false;
}
@@ -1906,7 +1964,8 @@
// https://gpuweb.github.io/gpuweb/wgsl/#function-call-expr
// If the called function does not return a value, a function call
// statement should be used instead.
- AddError(decl->source) << "function '" << name << "' does not return a value";
+ AddError(decl->source) << "function " << style::Function << name << style::Plain
+ << " does not return a value";
return false;
}
}
@@ -1934,9 +1993,9 @@
auto* value_ty = sem_.TypeOf(value);
if (member->Type() != value_ty->UnwrapRef()) {
AddError(value->source)
- << "type in structure constructor does not match struct member type: expected '"
- << sem_.TypeNameOf(member->Type()) << "', found '" << sem_.TypeNameOf(value_ty)
- << "'";
+ << "type in structure constructor does not match struct member type: expected "
+ << style::Type << sem_.TypeNameOf(member->Type()) << style::Plain << ", found "
+ << style::Type << sem_.TypeNameOf(value_ty);
return false;
}
}
@@ -1952,9 +2011,9 @@
auto* value_ty = sem_.TypeOf(value)->UnwrapRef();
if (core::type::Type::ConversionRank(value_ty, elem_ty) ==
core::type::Type::kNoConversion) {
- AddError(value->source)
- << "'" << sem_.TypeNameOf(value_ty) + "' cannot be used to construct an array of '"
- << sem_.TypeNameOf(elem_ty) << "'";
+ AddError(value->source) << style::Type << sem_.TypeNameOf(value_ty) << style::Plain
+ << " cannot be used to construct an array of " << style::Type
+ << sem_.TypeNameOf(elem_ty);
return false;
}
}
@@ -1992,7 +2051,10 @@
bool Validator::Vector(const core::type::Type* el_ty, const Source& source) const {
if (!el_ty->Is<core::type::Scalar>()) {
- AddError(source) << "vector element type must be 'bool', 'f32', 'f16', 'i32' or 'u32'";
+ AddError(source) << "vector element type must be " << style::Type << "bool" << style::Plain
+ << ", " << style::Type << "f32" << style::Plain << ", " << style::Type
+ << "f16" << style::Plain << ", " << style::Type << "i32" << style::Plain
+ << " or " << style::Type << "u32";
return false;
}
return true;
@@ -2000,7 +2062,8 @@
bool Validator::Matrix(const core::type::Type* el_ty, const Source& source) const {
if (!el_ty->is_float_scalar()) {
- AddError(source) << "matrix element type must be 'f32' or 'f16'";
+ AddError(source) << "matrix element type must be " << style::Type << "f32" << style::Plain
+ << " or " << style::Type << "f16";
return false;
}
return true;
@@ -2010,12 +2073,12 @@
auto backtrace = [&](const sem::Function* func, const sem::Function* entry_point) {
if (func != entry_point) {
TraverseCallChain(entry_point, func, [&](const sem::Function* f) {
- AddNote(f->Declaration()->source)
- << "called by function '" << f->Declaration()->name->symbol.Name() << "'";
+ AddNote(f->Declaration()->source) << "called by function " << style::Function
+ << f->Declaration()->name->symbol.Name();
});
AddNote(entry_point->Declaration()->source)
- << "called by entry point '" << entry_point->Declaration()->name->symbol.Name()
- << "'";
+ << "called by entry point " << style::Function
+ << entry_point->Declaration()->name->symbol.Name();
}
};
@@ -2028,8 +2091,8 @@
break;
}
}
- AddError(source) << "var with '" << var->AddressSpace()
- << "' address space cannot be used by " << stage << " pipeline stage";
+ AddError(source) << "var with " << style::Enum << var->AddressSpace() << style::Plain
+ << " address space cannot be used by " << stage << " pipeline stage";
AddNote(var->Declaration()->source) << "variable is declared here";
backtrace(func, entry_point);
return false;
@@ -2236,8 +2299,9 @@
[&](const ast::StructMemberSizeAttribute*) {
if (!member->Type()->HasCreationFixedFootprint()) {
AddError(attr->source)
- << "@size can only be applied to members where the member's type size "
- "can be fully determined at shader creation time";
+ << style::Attribute << "@size" << style::Plain
+ << " can only be applied to members where the member's type size can "
+ "be fully determined at shader creation time";
return false;
}
return true;
@@ -2250,7 +2314,8 @@
if (invariant_attribute && !has_position) {
AddError(invariant_attribute->source)
- << "@invariant must be applied to a position builtin";
+ << style::Attribute << "@invariant" << style::Plain
+ << " must be applied to a position builtin";
return false;
}
@@ -2260,14 +2325,17 @@
// backend writers.
if (member->Attributes().location.value_or(1) != 0) {
AddError(blend_src_attribute->source)
- << "@blend_src can only be used with @location(0)";
+ << style::Attribute << "@blend_src" << style::Plain << " can only be used with "
+ << style::Attribute << "@location" << style::Code << "(" << style::Literal
+ << "0" << style::Code << ")";
return false;
}
}
if (interpolate_attribute && !location_attribute) {
AddError(interpolate_attribute->source)
- << "@interpolate can only be used with @location";
+ << style::Attribute << "@interpolate" << style::Plain << " can only be used with "
+ << style::Attribute << "@location";
return false;
}
@@ -2278,11 +2346,13 @@
if (!locations_and_blend_srcs.Add(std::make_pair(location, blend_src))) {
auto& err = AddError(location_attribute->source)
- << "@location(" << location << ") ";
+ << style::Attribute << "@location" << style::Code << "("
+ << style::Literal << location << style::Code << ")";
if (blend_src) {
- err << "@blend_src(" << blend_src.value() << ") ";
+ err << style::Attribute << " @blend_src" << style::Code << "(" << style::Literal
+ << blend_src.value() << style::Code << ")";
}
- err << "appears multiple times";
+ err << style::Plain << " appears multiple times";
return false;
}
}
@@ -2291,7 +2361,8 @@
uint32_t color = member->Attributes().color.value();
if (!colors.Add(color)) {
AddError(color_attribute->source)
- << "@color(" << color << ") appears multiple times";
+ << style::Attribute << "@color" << style::Code << "(" << style::Literal << color
+ << style::Code << ")" << style::Plain << " appears multiple times";
return false;
}
}
@@ -2305,16 +2376,18 @@
ast::PipelineStage stage,
const Source& source) const {
if (stage == ast::PipelineStage::kCompute) {
- AddError(attr->source) << AttrToStr(attr) << " cannot be used by compute shaders";
+ AddError(attr->source) << style::Attribute << "@" << attr->Name() << style::Plain
+ << " cannot be used by compute shaders";
return false;
}
if (!type->is_numeric_scalar_or_vector()) {
std::string invalid_type = sem_.TypeNameOf(type);
- AddError(source) << "cannot apply @location to declaration of type '" << invalid_type
- << "'";
- AddNote(attr->source) << "@location must only be applied to declarations of numeric scalar "
- "or numeric vector type";
+ AddError(source) << "cannot apply " << style::Attribute << "@location" << style::Plain
+ << " to declaration of type " << style::Type << invalid_type;
+ AddNote(attr->source)
+ << style::Attribute << "@location" << style::Plain
+ << " must only be applied to declarations of numeric scalar or numeric vector type";
return false;
}
@@ -2327,8 +2400,9 @@
const Source& source,
const std::optional<bool> is_input) const {
if (!enabled_extensions_.Contains(wgsl::Extension::kChromiumExperimentalFramebufferFetch)) {
- AddError(attr->source) << "use of @color requires enabling extension "
- "'chromium_experimental_framebuffer_fetch'";
+ AddError(attr->source) << "use of " << style::Attribute << "@color" << style::Plain
+ << " requires enabling extension " << style::Code
+ << "chromium_experimental_framebuffer_fetch";
return false;
}
@@ -2336,15 +2410,18 @@
stage != ast::PipelineStage::kNone && stage != ast::PipelineStage::kFragment;
bool is_output = !is_input.value_or(true);
if (is_stage_non_fragment || is_output) {
- AddError(attr->source) << "@color can only be used for fragment shader input";
+ AddError(attr->source) << style::Attribute << "@color" << style::Plain
+ << " can only be used for fragment shader input";
return false;
}
if (!type->is_numeric_scalar_or_vector()) {
std::string invalid_type = sem_.TypeNameOf(type);
- AddError(source) << "cannot apply @color to declaration of type '" << invalid_type << "'";
- AddNote(attr->source) << "@color must only be applied to declarations of numeric scalar or "
- "numeric vector type";
+ AddError(source) << "cannot apply " << style::Attribute << "@color" << style::Plain
+ << " to declaration of type " << style::Type << invalid_type;
+ AddNote(attr->source)
+ << style::Attribute << "@color" << style::Plain
+ << " must only be applied to declarations of numeric scalar or numeric vector type";
return false;
}
@@ -2355,8 +2432,9 @@
ast::PipelineStage stage,
const std::optional<bool> is_input) const {
if (!enabled_extensions_.Contains(wgsl::Extension::kChromiumInternalDualSourceBlending)) {
- AddError(attr->source) << "use of @blend_src requires enabling extension "
- "'chromium_internal_dual_source_blending'";
+ AddError(attr->source) << "use of " << style::Attribute << "@blend_src" << style::Plain
+ << " requires enabling extension " << style::Code
+ << "chromium_internal_dual_source_blending";
return false;
}
@@ -2364,7 +2442,8 @@
stage != ast::PipelineStage::kNone && stage != ast::PipelineStage::kFragment;
bool is_output = is_input.value_or(false);
if (is_stage_non_fragment || is_output) {
- AddError(attr->source) << AttrToStr(attr) << " can only be used for fragment shader output";
+ AddError(attr->source) << style::Attribute << "@" << attr->Name() << style::Plain
+ << " can only be used for fragment shader output";
return false;
}
@@ -2377,8 +2456,9 @@
sem::Statement* current_statement) const {
if (func_type->UnwrapRef() != ret_type) {
AddError(ret->source)
- << "return statement type must match its function return type, returned '"
- << sem_.TypeNameOf(ret_type) << "', expected '" << sem_.TypeNameOf(func_type) << "'";
+ << "return statement type must match its function return type, returned " << style::Type
+ << sem_.TypeNameOf(ret_type) << style::Plain << ", expected " << style::Type
+ << sem_.TypeNameOf(func_type);
return false;
}
@@ -2480,9 +2560,11 @@
if (!ty->IsConstructible() &&
!ty->IsAnyOf<core::type::Pointer, core::type::Texture, core::type::Sampler,
core::type::AbstractNumeric>()) {
- AddError(rhs->source) << "cannot assign '" << sem_.TypeNameOf(rhs_ty)
- << "' to '_'. '_' can only be assigned a constructible, pointer, "
- "texture or sampler type";
+ AddError(rhs->source)
+ << "cannot assign " << style::Type << sem_.TypeNameOf(rhs_ty) << style::Plain
+ << " to " << style::Code << "_" << style::Plain << ". " << style::Code << "_"
+ << style::Plain
+ << " can only be assigned a constructible, pointer, texture or sampler type";
return false;
}
return true; // RHS can be anything.
@@ -2551,7 +2633,7 @@
}
if (lhs_ref->Access() == core::Access::kRead) {
AddError(a->source) << "cannot store into a read-only type " << style::Type
- << sem_.RawTypeNameOf(lhs_ty) << style::Plain;
+ << sem_.RawTypeNameOf(lhs_ty);
return false;
}
return true;
@@ -2564,14 +2646,22 @@
if (auto* var_user = sem_.Get<sem::VariableUser>(lhs)) {
auto* v = var_user->Variable()->Declaration();
- const char* err = Switch(
+ bool errored = Switch(
v, //
- [&](const ast::Parameter*) { return "cannot modify function parameter"; },
- [&](const ast::Let*) { return "cannot modify 'let'"; },
- [&](const ast::Override*) { return "cannot modify 'override'"; });
- if (err) {
- AddError(lhs->source) << err;
- AddNote(v->source) << "'" << v->name->symbol.Name() << "' is declared here:";
+ [&](const ast::Parameter*) {
+ AddError(lhs->source) << "cannot modify function parameter";
+ return true;
+ },
+ [&](const ast::Let*) {
+ AddError(lhs->source) << "cannot modify " << style::Keyword << "let";
+ return true;
+ },
+ [&](const ast::Override*) {
+ AddError(lhs->source) << "cannot modify " << style::Keyword << "override";
+ return true;
+ });
+ if (errored) {
+ sem_.NoteDeclarationSource(v);
return false;
}
}
@@ -2580,7 +2670,8 @@
auto* lhs_ref = lhs_ty->As<core::type::Reference>();
if (!lhs_ref) {
// LHS is not a reference, so it has no storage.
- AddError(lhs->source) << "cannot modify value of type '" << sem_.TypeNameOf(lhs_ty) << "'";
+ AddError(lhs->source) << "cannot modify value of type " << style::Type
+ << sem_.TypeNameOf(lhs_ty);
return false;
}
@@ -2591,8 +2682,8 @@
}
if (lhs_ref->Access() == core::Access::kRead) {
- AddError(inc->source) << "cannot modify read-only type '" << sem_.RawTypeNameOf(lhs_ty)
- << "'";
+ AddError(inc->source) << "cannot modify read-only type " << style::Type
+ << sem_.RawTypeNameOf(lhs_ty);
return false;
}
return true;
@@ -2630,8 +2721,8 @@
if (!diag_added && diag_added.value->severity != dc->severity) {
AddError(dc->rule_name->source) << "conflicting diagnostic " << use;
AddNote(diag_added.value->rule_name->source)
- << "severity of '" << dc->rule_name->String() << "' set to '" << dc->severity
- << "' here";
+ << "severity of " << style::Code << dc->rule_name->String() << style::Plain
+ << " set to " << style::Code << dc->severity << style::Plain << " here";
return false;
}
}
@@ -2665,9 +2756,11 @@
}
void Validator::RaiseArrayWithOverrideCountError(const Source& source) const {
- AddError(source)
- << "array with an 'override' element count can only be used as the store type of a "
- "'var<workgroup>'";
+ AddError(source) << style::Type << "array" << style::Plain << " with an " << style::Keyword
+ << "override" << style::Plain
+ << " element count can only be used as the store type of a " << style::Keyword
+ << "var" << style::Code << "<" << style::Enum << "workgroup" << style::Code
+ << ">";
}
std::string Validator::VectorPretty(uint32_t size, const core::type::Type* element_type) const {
@@ -2691,15 +2784,21 @@
using Allowed = std::tuple<core::type::I32, core::type::U32, core::type::F32>;
if (TINT_UNLIKELY(!member->Type()->TypeInfo().IsAnyOfTuple<Allowed>())) {
AddError(member->Declaration()->source)
- << "struct members used in the 'pixel_local' address "
- "space can only be of the type 'i32', 'u32' or 'f32'";
- AddNote(source) << "struct '" << str->Name().Name()
- << "' used in the 'pixel_local' address space here";
+ << style::Keyword << "struct" << style::Plain << " members used in the "
+ << style::Enum << "pixel_local" << style::Plain
+ << " address space can only be of the type " << style::Type << "i32"
+ << style::Plain << ", " << style::Type << "u32" << style::Plain
+ << " or " << style::Type << "f32";
+ AddNote(source)
+ << style::Keyword << "struct " << style::Type << str->Name().Name()
+ << style::Plain << " used in the " << style::Enum << "pixel_local"
+ << style::Plain << " address space here";
return false;
}
}
} else if (TINT_UNLIKELY(!store_ty->TypeInfo().Is<core::type::Struct>())) {
- AddError(source) << "'pixel_local' variable only support struct storage types";
+ AddError(source) << style::Enum << "pixel_local" << style::Plain
+ << " variable only support struct storage types";
return false;
}
break;
@@ -2708,16 +2807,19 @@
wgsl::Extension::kChromiumExperimentalPushConstant) &&
IsValidationEnabled(attributes,
ast::DisabledValidation::kIgnoreAddressSpace))) {
- AddError(source) << "use of variable address space 'push_constant' requires "
- "enabling extension 'chromium_experimental_push_constant'";
+ AddError(source) << "use of variable address space " << style::Enum
+ << "push_constant" << style::Plain
+ << " requires enabling extension " << style::Code
+ << "chromium_experimental_push_constant";
return false;
}
break;
case core::AddressSpace::kStorage:
if (TINT_UNLIKELY(access == core::Access::kWrite)) {
// The access mode for the storage address space can only be 'read' or 'read_write'.
- AddError(source)
- << "access mode 'write' is not valid for the 'storage' address space";
+ AddError(source) << "access mode " << style::Enum << "write" << style::Plain
+ << " is not valid for the " << style::Enum << "storage"
+ << style::Plain << " address space";
return false;
}
break;
@@ -2725,24 +2827,30 @@
break;
}
- auto atomic_error = [&]() -> const char* {
+ auto atomic_error = [&] {
StyledText err;
if (address_space != core::AddressSpace::kStorage &&
address_space != core::AddressSpace::kWorkgroup) {
- return "atomic variables must have <storage> or <workgroup> address space";
+ AddError(source) << style::Type << "atomic" << style::Plain << " variables must have "
+ << style::Enum << "storage" << style::Plain << " or " << style::Enum
+ << "workgroup" << style::Plain << " address space";
+ return true;
}
if (address_space == core::AddressSpace::kStorage && access != core::Access::kReadWrite) {
- return "atomic variables in <storage> address space must have read_write access mode";
+ AddError(source) << "atomic variables in " << style::Enum << "storage" << style::Plain
+ << " address space must have " << style::Enum << "read_write"
+ << style::Plain << " access mode";
+ return true;
}
- return nullptr;
+ return false;
};
auto check_sub_atomics = [&] {
if (auto atomic_use = atomic_composite_info_.Get(store_ty)) {
- if (auto* err = atomic_error()) {
- AddError(source) << err;
+ if (TINT_UNLIKELY(atomic_error())) {
AddNote(**atomic_use)
- << "atomic sub-type of '" << sem_.TypeNameOf(store_ty) << "' is declared here";
+ << "atomic sub-type of " << style::Type << sem_.TypeNameOf(store_ty)
+ << style::Plain << " is declared here";
return false;
}
}
@@ -2752,8 +2860,7 @@
return Switch(
store_ty, //
[&](const core::type::Atomic*) {
- if (auto* err = atomic_error()) {
- AddError(source) << err;
+ if (TINT_UNLIKELY(atomic_error())) {
return false;
}
return true;
@@ -2783,27 +2890,29 @@
}
AddError(ep->Declaration()->source)
- << "entry point '" << ep->Declaration()->name->symbol.Name()
- << "' uses two different '" << space << "' variables.";
- AddNote(var->Declaration()->source)
- << "first '" << space << "' variable declaration is here";
+ << "entry point " << style::Function << ep->Declaration()->name->symbol.Name()
+ << style::Plain << " uses two different " << style::Enum << space << style::Plain
+ << " variables.";
+ AddNote(var->Declaration()->source) << "first " << style::Enum << space << style::Plain
+ << " variable declaration is here";
if (func != ep) {
TraverseCallChain(ep, func, [&](const sem::Function* f) {
- AddNote(f->Declaration()->source)
- << "called by function '" << f->Declaration()->name->symbol.Name() << "'";
+ AddNote(f->Declaration()->source) << "called by function " << style::Function
+ << f->Declaration()->name->symbol.Name();
});
- AddNote(ep->Declaration()->source)
- << "called by entry point '" << ep->Declaration()->name->symbol.Name() << "'";
+ AddNote(ep->Declaration()->source) << "called by entry point " << style::Function
+ << ep->Declaration()->name->symbol.Name();
}
AddNote(seen_var->Declaration()->source)
- << "second '" << space << "' variable declaration is here";
+ << "second " << style::Enum << space << style::Plain
+ << " variable declaration is here";
if (seen_func != ep) {
TraverseCallChain(ep, seen_func, [&](const sem::Function* f) {
- AddNote(f->Declaration()->source)
- << "called by function '" << f->Declaration()->name->symbol.Name() << "'";
+ AddNote(f->Declaration()->source) << "called by function " << style::Function
+ << f->Declaration()->name->symbol.Name();
});
- AddNote(ep->Declaration()->source)
- << "called by entry point '" << ep->Declaration()->name->symbol.Name() << "'";
+ AddNote(ep->Declaration()->source) << "called by entry point " << style::Function
+ << ep->Declaration()->name->symbol.Name();
}
return false;
}
diff --git a/src/tint/lang/wgsl/resolver/variable_validation_test.cc b/src/tint/lang/wgsl/resolver/variable_validation_test.cc
index 10bc7ec..89179ce 100644
--- a/src/tint/lang/wgsl/resolver/variable_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/variable_validation_test.cc
@@ -190,7 +190,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(3:3 error: cannot initialize const of type 'i32' with value of type 'u32')");
+ R"(3:3 error: cannot initialize 'const' of type 'i32' with value of type 'u32')");
}
TEST_F(ResolverVariableValidationTest, LetInitializerWrongType) {
@@ -199,7 +199,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(3:3 error: cannot initialize let of type 'i32' with value of type 'u32')");
+ R"(3:3 error: cannot initialize 'let' of type 'i32' with value of type 'u32')");
}
TEST_F(ResolverVariableValidationTest, VarInitializerWrongType) {
@@ -208,7 +208,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(3:3 error: cannot initialize var of type 'i32' with value of type 'u32')");
+ R"(3:3 error: cannot initialize 'var' of type 'i32' with value of type 'u32')");
}
TEST_F(ResolverVariableValidationTest, ConstInitializerWrongTypeViaAlias) {
@@ -217,7 +217,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(3:3 error: cannot initialize const of type 'i32' with value of type 'u32')");
+ R"(3:3 error: cannot initialize 'const' of type 'i32' with value of type 'u32')");
}
TEST_F(ResolverVariableValidationTest, LetInitializerWrongTypeViaAlias) {
@@ -226,7 +226,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(3:3 error: cannot initialize let of type 'i32' with value of type 'u32')");
+ R"(3:3 error: cannot initialize 'let' of type 'i32' with value of type 'u32')");
}
TEST_F(ResolverVariableValidationTest, VarInitializerWrongTypeViaAlias) {
@@ -235,7 +235,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- R"(3:3 error: cannot initialize var of type 'i32' with value of type 'u32')");
+ R"(3:3 error: cannot initialize 'var' of type 'i32' with value of type 'u32')");
}
TEST_F(ResolverVariableValidationTest, LetOfPtrConstructedWithRef) {
@@ -250,7 +250,7 @@
EXPECT_EQ(
r()->error(),
- R"(12:34 error: cannot initialize let of type 'ptr<function, f32, read_write>' with value of type 'f32')");
+ R"(12:34 error: cannot initialize 'let' of type 'ptr<function, f32, read_write>' with value of type 'f32')");
}
TEST_F(ResolverVariableValidationTest, LocalLetRedeclared) {
@@ -338,10 +338,9 @@
WrapInFunction(ptr);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: cannot initialize let of type "
- "'ptr<storage, i32, read_write>' with value of type "
- "'ptr<storage, i32, read>'");
+ EXPECT_EQ(
+ r()->error(),
+ R"(12:34 error: cannot initialize 'let' of type 'ptr<storage, i32, read_write>' with value of type 'ptr<storage, i32, read>')");
}
TEST_F(ResolverVariableValidationTest, NonConstructibleType_Atomic) {