tint: Add a negation operator to Number

Use this for expressing negative i32s.
Replacing `i32(-123)` with `-123_i` is more readable as the former looks
like it should be generating a WGSL cast, which it does not.

Bug: tint:1504
Change-Id: Iead3885b903e1f707b8a7e6b9090d65930df118e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/89401
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/inspector/inspector_test.cc b/src/tint/inspector/inspector_test.cc
index a9b133b..1d28818 100644
--- a/src/tint/inspector/inspector_test.cc
+++ b/src/tint/inspector/inspector_test.cc
@@ -991,7 +991,7 @@
 
 TEST_F(InspectorGetConstantIDsTest, I32) {
     AddOverridableConstantWithID("foo", 1, ty.i32(), nullptr);
-    AddOverridableConstantWithID("bar", 20, ty.i32(), Expr(i32(-42)));
+    AddOverridableConstantWithID("bar", 20, ty.i32(), Expr(-42_i));
     AddOverridableConstantWithID("baz", 300, ty.i32(), Expr(42_i));
 
     Inspector& inspector = Build();
diff --git a/src/tint/number.h b/src/tint/number.h
index 2eca79c..f77f5b3 100644
--- a/src/tint/number.h
+++ b/src/tint/number.h
@@ -40,6 +40,10 @@
     /// @returns the value as T
     operator T() const { return value; }
 
+    /// Negation operator
+    /// @returns the negative value of the number
+    Number operator-() const { return Number(-value); }
+
     /// Assignment operator
     /// @param v the new value
     /// @returns this Number so calls can be chained
diff --git a/src/tint/resolver/builtin_test.cc b/src/tint/resolver/builtin_test.cc
index 94684ba..3692e98 100644
--- a/src/tint/resolver/builtin_test.cc
+++ b/src/tint/resolver/builtin_test.cc
@@ -947,7 +947,7 @@
 TEST_P(ResolverBuiltinTest_SingleParam_FloatOrInt, Sint_Scalar) {
     auto param = GetParam();
 
-    auto* call = Call(param.name, i32(-1));
+    auto* call = Call(param.name, -1_i);
     WrapInFunction(call);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
diff --git a/src/tint/resolver/control_block_validation_test.cc b/src/tint/resolver/control_block_validation_test.cc
index b4742c9..0fab665 100644
--- a/src/tint/resolver/control_block_validation_test.cc
+++ b/src/tint/resolver/control_block_validation_test.cc
@@ -232,9 +232,9 @@
     // }
     auto* var = Var("a", ty.u32(), Expr(2_u));
 
-    auto* block = Block(Decl(var),                                       //
-                        Switch("a",                                      //
-                               Case(Source{{12, 34}}, {Expr(i32(-1))}),  //
+    auto* block = Block(Decl(var),                                    //
+                        Switch("a",                                   //
+                               Case(Source{{12, 34}}, {Expr(-1_i)}),  //
                                DefaultCase()));
     WrapInFunction(block);
 
@@ -281,12 +281,12 @@
 
     auto* block = Block(Decl(var),   //
                         Switch("a",  //
-                               Case(Expr(Source{{12, 34}}, i32(-10))),
+                               Case(Expr(Source{{12, 34}}, -10_i)),
                                Case({
                                    Expr(0_i),
                                    Expr(1_i),
                                    Expr(2_i),
-                                   Expr(Source{{56, 78}}, i32(-10)),
+                                   Expr(Source{{56, 78}}, -10_i),
                                }),
                                DefaultCase()));
     WrapInFunction(block);
diff --git a/src/tint/resolver/function_validation_test.cc b/src/tint/resolver/function_validation_test.cc
index 1bc70a5..8f878c0 100644
--- a/src/tint/resolver/function_validation_test.cc
+++ b/src/tint/resolver/function_validation_test.cc
@@ -552,7 +552,7 @@
     // fn main() {}
 
     Func("main", {}, ty.void_(), {},
-         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Expr(Source{{12, 34}}, i32(-2)))});
+         {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Expr(Source{{12, 34}}, -2_i))});
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: workgroup_size argument must be at least 1");
@@ -587,7 +587,7 @@
     // let x = -2i;
     // @stage(compute) @workgroup_size(x)
     // fn main() {}
-    GlobalConst("x", ty.i32(), Expr(i32(-2)));
+    GlobalConst("x", ty.i32(), Expr(-2_i));
     Func("main", {}, ty.void_(), {},
          {Stage(ast::PipelineStage::kCompute), WorkgroupSize(Expr(Source{{12, 34}}, "x"))});
 
diff --git a/src/tint/resolver/type_validation_test.cc b/src/tint/resolver/type_validation_test.cc
index 2af2c0e..7fcf004 100644
--- a/src/tint/resolver/type_validation_test.cc
+++ b/src/tint/resolver/type_validation_test.cc
@@ -232,7 +232,7 @@
 
 TEST_F(ResolverTypeValidationTest, ArraySize_SignedLiteral_Negative) {
     // var<private> a : array<f32, -10i>;
-    Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, i32(-10))), ast::StorageClass::kPrivate);
+    Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, -10_i)), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1");
 }
@@ -258,7 +258,7 @@
 TEST_F(ResolverTypeValidationTest, ArraySize_SignedConstant_Negative) {
     // let size = -10i;
     // var<private> a : array<f32, size>;
-    GlobalConst("size", nullptr, Expr(i32(-10)));
+    GlobalConst("size", nullptr, Expr(-10_i));
     Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1");
diff --git a/src/tint/writer/glsl/generator_impl_constructor_test.cc b/src/tint/writer/glsl/generator_impl_constructor_test.cc
index c247bab..41a7e61 100644
--- a/src/tint/writer/glsl/generator_impl_constructor_test.cc
+++ b/src/tint/writer/glsl/generator_impl_constructor_test.cc
@@ -34,7 +34,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Constructor, EmitConstructor_Int) {
-    WrapInFunction(Expr(i32(-12345)));
+    WrapInFunction(Expr(-12345_i));
 
     GeneratorImpl& gen = Build();
 
@@ -80,7 +80,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Constructor, EmitConstructor_Type_Int) {
-    WrapInFunction(Construct<i32>(i32(-12345)));
+    WrapInFunction(Construct<i32>(-12345_i));
 
     GeneratorImpl& gen = Build();
 
diff --git a/src/tint/writer/hlsl/generator_impl_constructor_test.cc b/src/tint/writer/hlsl/generator_impl_constructor_test.cc
index 5916b0a..46cfc4d 100644
--- a/src/tint/writer/hlsl/generator_impl_constructor_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_constructor_test.cc
@@ -34,7 +34,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Int) {
-    WrapInFunction(Expr(i32(-12345)));
+    WrapInFunction(Expr(-12345_i));
 
     GeneratorImpl& gen = Build();
 
@@ -80,7 +80,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Int) {
-    WrapInFunction(Construct<i32>(i32(-12345)));
+    WrapInFunction(Construct<i32>(-12345_i));
 
     GeneratorImpl& gen = Build();
 
diff --git a/src/tint/writer/msl/generator_impl_constructor_test.cc b/src/tint/writer/msl/generator_impl_constructor_test.cc
index 134a7ae..feb9de1 100644
--- a/src/tint/writer/msl/generator_impl_constructor_test.cc
+++ b/src/tint/writer/msl/generator_impl_constructor_test.cc
@@ -34,7 +34,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, EmitConstructor_Int) {
-    WrapInFunction(Expr(i32(-12345)));
+    WrapInFunction(Expr(-12345_i));
 
     GeneratorImpl& gen = Build();
 
@@ -80,7 +80,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, EmitConstructor_Type_Int) {
-    WrapInFunction(Construct<i32>(i32(-12345)));
+    WrapInFunction(Construct<i32>(-12345_i));
 
     GeneratorImpl& gen = Build();
 
diff --git a/src/tint/writer/spirv/builder_literal_test.cc b/src/tint/writer/spirv/builder_literal_test.cc
index 00c21b0..218db86 100644
--- a/src/tint/writer/spirv/builder_literal_test.cc
+++ b/src/tint/writer/spirv/builder_literal_test.cc
@@ -72,7 +72,7 @@
 }
 
 TEST_F(BuilderTest, Literal_I32) {
-    auto* i = Expr(i32(-23));
+    auto* i = Expr(-23_i);
     WrapInFunction(i);
     spirv::Builder& b = Build();
 
@@ -86,8 +86,8 @@
 }
 
 TEST_F(BuilderTest, Literal_I32_Dedup) {
-    auto* i1 = Expr(i32(-23));
-    auto* i2 = Expr(i32(-23));
+    auto* i1 = Expr(-23_i);
+    auto* i2 = Expr(-23_i);
     WrapInFunction(i1, i2);
 
     spirv::Builder& b = Build();
diff --git a/src/tint/writer/wgsl/generator_impl_constructor_test.cc b/src/tint/writer/wgsl/generator_impl_constructor_test.cc
index 3fbf3f1..5776883 100644
--- a/src/tint/writer/wgsl/generator_impl_constructor_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_constructor_test.cc
@@ -34,7 +34,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Int) {
-    WrapInFunction(Expr(i32(-12345)));
+    WrapInFunction(Expr(-12345_i));
 
     GeneratorImpl& gen = Build();
 
@@ -80,7 +80,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Int) {
-    WrapInFunction(Construct<i32>(i32(-12345)));
+    WrapInFunction(Construct<i32>(-12345_i));
 
     GeneratorImpl& gen = Build();