[tint][wgsl] Be explicit about overload param/arg count mismatch

When you pass more arguments than parameters, and all the parameters
have a matching argument.

Bug: tint:2187
Change-Id: I0d8fc563da88b1d1ad2e4c8ce26c5a74210665ad
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/178060
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/lang/core/constant/eval_binary_op_test.cc b/src/tint/lang/core/constant/eval_binary_op_test.cc
index fd4d890..df37060 100644
--- a/src/tint/lang/core/constant/eval_binary_op_test.cc
+++ b/src/tint/lang/core/constant/eval_binary_op_test.cc
@@ -1989,18 +1989,22 @@
  • 'vec2<T  ✓ >(x: T  ✓ , y: T  ✗ ) -> vec2<T>' where:
       ✓  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec2<T  ✓ >(T  ✓ ) -> vec2<T>' where:
+      ✗  overload expects 1 argument, call passed 2 arguments
       ✓  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec2<T  ✓ >(vec2<T>  ✗ ) -> vec2<T>' where:
       ✓  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec2<T  ✓ >() -> vec2<T>' where:
+      ✗  overload expects 0 arguments, call passed 2 arguments
       ✓  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec2(x: T  ✓ , y: T  ✗ ) -> vec2<T>' where:
       ✓  'T' is 'abstract-int', 'abstract-float', 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec2(T  ✓ ) -> vec2<T>' where:
-      ✗  overload expects 0 template arguments
+      ✗  overload expects 1 argument, call passed 2 arguments
+      ✗  overload expects 0 template arguments, call passed 1 argument
       ✓  'T' is 'abstract-int', 'abstract-float', 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec2() -> vec2<abstract-int>' where:
-      ✗  overload expects 0 template arguments
+      ✗  overload expects 0 arguments, call passed 2 arguments
+      ✗  overload expects 0 template arguments, call passed 1 argument
  • 'vec2(vec2<T>  ✗ ) -> vec2<T>' where:
       ✗  'T' is 'abstract-int', 'abstract-float', 'f32', 'f16', 'i32', 'u32' or 'bool'
 
@@ -2040,18 +2044,22 @@
  • 'vec2<T  ✓ >(x: T  ✓ , y: T  ✗ ) -> vec2<T>' where:
       ✓  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec2<T  ✓ >(T  ✓ ) -> vec2<T>' where:
+      ✗  overload expects 1 argument, call passed 2 arguments
       ✓  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec2<T  ✓ >(vec2<T>  ✗ ) -> vec2<T>' where:
       ✓  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec2<T  ✓ >() -> vec2<T>' where:
+      ✗  overload expects 0 arguments, call passed 2 arguments
       ✓  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec2(x: T  ✓ , y: T  ✗ ) -> vec2<T>' where:
       ✓  'T' is 'abstract-int', 'abstract-float', 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec2(T  ✓ ) -> vec2<T>' where:
-      ✗  overload expects 0 template arguments
+      ✗  overload expects 1 argument, call passed 2 arguments
+      ✗  overload expects 0 template arguments, call passed 1 argument
       ✓  'T' is 'abstract-int', 'abstract-float', 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec2() -> vec2<abstract-int>' where:
-      ✗  overload expects 0 template arguments
+      ✗  overload expects 0 arguments, call passed 2 arguments
+      ✗  overload expects 0 template arguments, call passed 1 argument
  • 'vec2(vec2<T>  ✗ ) -> vec2<T>' where:
       ✗  'T' is 'abstract-int', 'abstract-float', 'f32', 'f16', 'i32', 'u32' or 'bool'
 
diff --git a/src/tint/lang/core/intrinsic/table.cc b/src/tint/lang/core/intrinsic/table.cc
index 8c986d2..7b71604 100644
--- a/src/tint/lang/core/intrinsic/table.cc
+++ b/src/tint/lang/core/intrinsic/table.cc
@@ -607,11 +607,20 @@
         first = false;
     };
 
+    if (all_params_match && args.Length() > overload.num_parameters) {
+        separator();
+        ss << style::Mismatch(" ✗ ")
+           << style::Plain(" overload expects ", static_cast<int>(overload.num_parameters),
+                           " argument", overload.num_parameters != 1 ? "s" : "", ", call passed ",
+                           args.Length(), " argument", args.Length() != 1 ? "s" : "");
+    }
     if (all_params_match && template_args.Length() > overload.num_explicit_templates) {
         separator();
         ss << style::Mismatch(" ✗ ")
            << style::Plain(" overload expects ", static_cast<int>(overload.num_explicit_templates),
-                           " template argument", overload.num_explicit_templates != 1 ? "s" : "");
+                           " template argument", overload.num_explicit_templates != 1 ? "s" : "",
+                           ", call passed ", template_args.Length(), " argument",
+                           template_args.Length() != 1 ? "s" : "");
     }
 
     for (size_t i = 0; i < overload.num_templates; i++) {
diff --git a/src/tint/lang/core/intrinsic/table_test.cc b/src/tint/lang/core/intrinsic/table_test.cc
index 31fbc13..ad1bb89 100644
--- a/src/tint/lang/core/intrinsic/table_test.cc
+++ b/src/tint/lang/core/intrinsic/table_test.cc
@@ -593,7 +593,8 @@
 27 candidate functions:
  • 'textureDimensions(texture: texture_depth_2d  ✓ , level: L  ✗ ) -> vec2<u32>' where:
       ✗  'L' is 'i32' or 'u32'
- • 'textureDimensions(texture: texture_depth_2d  ✓ ) -> vec2<u32>'
+ • 'textureDimensions(texture: texture_depth_2d  ✓ ) -> vec2<u32>' where:
+      ✗  overload expects 1 argument, call passed 2 arguments
  • 'textureDimensions(texture: texture_depth_2d_array  ✗ , level: L  ✗ ) -> vec2<u32>' where:
       ✗  'L' is 'i32' or 'u32'
  • 'textureDimensions(texture: texture_depth_cube  ✗ , level: L  ✗ ) -> vec2<u32>' where:
@@ -792,12 +793,14 @@
  • 'vec3<T  ✓ >(x: T  ✓ , yz: vec2<T>  ✗ ) -> vec3<T>' where:
       ✓  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec3<T  ✓ >(T  ✓ ) -> vec3<T>' where:
+      ✗  overload expects 1 argument, call passed 3 arguments
       ✓  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec3<T  ✓ >(xy: vec2<T>  ✗ , z: T  ✗ ) -> vec3<T>' where:
       ✓  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec3<T  ✓ >(vec3<T>  ✗ ) -> vec3<T>' where:
       ✓  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec3<T  ✓ >() -> vec3<T>' where:
+      ✗  overload expects 0 arguments, call passed 3 arguments
       ✓  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
 
 5 candidate conversions:
@@ -881,6 +884,7 @@
  • 'vec3<T  ✓ >(T  ✗ ) -> vec3<T>' where:
       ✓  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec3<T  ✓ >() -> vec3<T>' where:
+      ✗  overload expects 0 arguments, call passed 1 argument
       ✓  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec3<T  ✓ >(xy: vec2<T>  ✗ , z: T  ✗ ) -> vec3<T>' where:
       ✓  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
diff --git a/src/tint/lang/wgsl/intrinsic/table_test.cc b/src/tint/lang/wgsl/intrinsic/table_test.cc
index 4912c68..0393998 100644
--- a/src/tint/lang/wgsl/intrinsic/table_test.cc
+++ b/src/tint/lang/wgsl/intrinsic/table_test.cc
@@ -613,7 +613,8 @@
 27 candidate functions:
  • 'textureDimensions(texture: texture_depth_2d  ✓ , level: L  ✗ ) -> vec2<u32>' where:
       ✗  'L' is 'i32' or 'u32'
- • 'textureDimensions(texture: texture_depth_2d  ✓ ) -> vec2<u32>'
+ • 'textureDimensions(texture: texture_depth_2d  ✓ ) -> vec2<u32>' where:
+      ✗  overload expects 1 argument, call passed 2 arguments
  • 'textureDimensions(texture: texture_depth_2d_array  ✗ , level: L  ✗ ) -> vec2<u32>' where:
       ✗  'L' is 'i32' or 'u32'
  • 'textureDimensions(texture: texture_depth_cube  ✗ , level: L  ✗ ) -> vec2<u32>' where:
@@ -834,8 +835,10 @@
  • 'vec3(x: T  ✓ , yz: vec2<T>  ✗ ) -> vec3<T>' where:
       ✓  'T' is 'abstract-int', 'abstract-float', 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec3(T  ✓ ) -> vec3<T>' where:
+      ✗  overload expects 1 argument, call passed 3 arguments
       ✓  'T' is 'abstract-int', 'abstract-float', 'f32', 'f16', 'i32', 'u32' or 'bool'
- • 'vec3() -> vec3<abstract-int>'
+ • 'vec3() -> vec3<abstract-int>' where:
+      ✗  overload expects 0 arguments, call passed 3 arguments
  • 'vec3(vec3<T>  ✗ ) -> vec3<T>' where:
       ✗  'T' is 'abstract-int', 'abstract-float', 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec3<T  ✗ >(x: T  ✓ , y: T  ✗ , z: T  ✓ ) -> vec3<T>' where:
@@ -845,10 +848,12 @@
  • 'vec3<T  ✗ >(x: T  ✓ , yz: vec2<T>  ✗ ) -> vec3<T>' where:
       ✓  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec3<T  ✗ >(T  ✓ ) -> vec3<T>' where:
+      ✗  overload expects 1 argument, call passed 3 arguments
       ✓  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec3<T  ✗ >(vec3<T>  ✗ ) -> vec3<T>' where:
       ✗  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec3<T  ✗ >() -> vec3<T>' where:
+      ✗  overload expects 0 arguments, call passed 3 arguments
       ✗  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
 
 5 candidate conversions:
@@ -885,12 +890,14 @@
  • 'vec3<T  ✓ >(x: T  ✓ , yz: vec2<T>  ✗ ) -> vec3<T>' where:
       ✓  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec3<T  ✓ >(T  ✓ ) -> vec3<T>' where:
+      ✗  overload expects 1 argument, call passed 3 arguments
       ✓  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec3<T  ✓ >(xy: vec2<T>  ✗ , z: T  ✗ ) -> vec3<T>' where:
       ✓  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec3<T  ✓ >(vec3<T>  ✗ ) -> vec3<T>' where:
       ✓  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec3<T  ✓ >() -> vec3<T>' where:
+      ✗  overload expects 0 arguments, call passed 3 arguments
       ✓  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec3(x: T  ✓ , y: T  ✗ , z: T  ✓ ) -> vec3<T>' where:
       ✓  'T' is 'abstract-int', 'abstract-float', 'f32', 'f16', 'i32', 'u32' or 'bool'
@@ -899,10 +906,12 @@
  • 'vec3(x: T  ✓ , yz: vec2<T>  ✗ ) -> vec3<T>' where:
       ✓  'T' is 'abstract-int', 'abstract-float', 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec3(T  ✓ ) -> vec3<T>' where:
-      ✗  overload expects 0 template arguments
+      ✗  overload expects 1 argument, call passed 3 arguments
+      ✗  overload expects 0 template arguments, call passed 1 argument
       ✓  'T' is 'abstract-int', 'abstract-float', 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec3() -> vec3<abstract-int>' where:
-      ✗  overload expects 0 template arguments
+      ✗  overload expects 0 arguments, call passed 3 arguments
+      ✗  overload expects 0 template arguments, call passed 1 argument
  • 'vec3(vec3<T>  ✗ ) -> vec3<T>' where:
       ✗  'T' is 'abstract-int', 'abstract-float', 'f32', 'f16', 'i32', 'u32' or 'bool'
 
@@ -1017,6 +1026,7 @@
  • 'vec3<T  ✓ >(T  ✗ ) -> vec3<T>' where:
       ✓  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec3<T  ✓ >() -> vec3<T>' where:
+      ✗  overload expects 0 arguments, call passed 1 argument
       ✓  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec3<T  ✓ >(xy: vec2<T>  ✗ , z: T  ✗ ) -> vec3<T>' where:
       ✓  'T' is 'f32', 'f16', 'i32', 'u32' or 'bool'
@@ -1027,7 +1037,8 @@
  • 'vec3(T  ✗ ) -> vec3<T>' where:
       ✗  'T' is 'abstract-int', 'abstract-float', 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec3() -> vec3<abstract-int>' where:
-      ✗  overload expects 0 template arguments
+      ✗  overload expects 0 arguments, call passed 1 argument
+      ✗  overload expects 0 template arguments, call passed 1 argument
  • 'vec3(vec3<T>  ✗ ) -> vec3<T>' where:
       ✗  'T' is 'abstract-int', 'abstract-float', 'f32', 'f16', 'i32', 'u32' or 'bool'
  • 'vec3(x: T  ✗ , yz: vec2<T>  ✗ ) -> vec3<T>' where:
diff --git a/src/tint/lang/wgsl/resolver/builtin_test.cc b/src/tint/lang/wgsl/resolver/builtin_test.cc
index b29c901..e9a2788 100644
--- a/src/tint/lang/wgsl/resolver/builtin_test.cc
+++ b/src/tint/lang/wgsl/resolver/builtin_test.cc
@@ -879,6 +879,7 @@
 
 1 candidate function:
  • 'cross(vec3<T>  ✓ , vec3<T>  ✓ ) -> vec3<T>' where:
+      ✗  overload expects 2 arguments, call passed 3 arguments
       ✓  'T' is 'abstract-float', 'f32' or 'f16'
 )");
 }
@@ -940,6 +941,7 @@
 
 2 candidate functions:
  • 'distance(vecN<T>  ✓ , vecN<T>  ✓ ) -> T' where:
+      ✗  overload expects 2 arguments, call passed 3 arguments
       ✓  'T' is 'abstract-float', 'f32' or 'f16'
  • 'distance(T  ✗ , T  ✗ ) -> T' where:
       ✗  'T' is 'abstract-float', 'f32' or 'f16'
@@ -1197,6 +1199,7 @@
 
 2 candidate functions:
  • 'length(T  ✓ ) -> T' where:
+      ✗  overload expects 1 argument, call passed 2 arguments
       ✓  'T' is 'abstract-float', 'f32' or 'f16'
  • 'length(vecN<T>  ✗ ) -> T' where:
       ✗  'T' is 'abstract-float', 'f32' or 'f16'
@@ -1393,6 +1396,7 @@
 
 2 candidate functions:
  • 'modf(T  ✓ ) -> __modf_result_T' where:
+      ✗  overload expects 1 argument, call passed 2 arguments
       ✓  'T' is 'abstract-float', 'f32' or 'f16'
  • 'modf(vecN<T>  ✗ ) -> __modf_result_vecN_T' where:
       ✗  'T' is 'abstract-float', 'f32' or 'f16'
@@ -1409,6 +1413,7 @@
 
 2 candidate functions:
  • 'modf(T  ✓ ) -> __modf_result_T' where:
+      ✗  overload expects 1 argument, call passed 2 arguments
       ✓  'T' is 'abstract-float', 'f32' or 'f16'
  • 'modf(vecN<T>  ✗ ) -> __modf_result_vecN_T' where:
       ✗  'T' is 'abstract-float', 'f32' or 'f16'
@@ -1427,6 +1432,7 @@
 
 2 candidate functions:
  • 'modf(vecN<T>  ✓ ) -> __modf_result_vecN_T' where:
+      ✗  overload expects 1 argument, call passed 2 arguments
       ✓  'T' is 'abstract-float', 'f32' or 'f16'
  • 'modf(T  ✗ ) -> __modf_result_T' where:
       ✗  'T' is 'abstract-float', 'f32' or 'f16'
diff --git a/src/tint/lang/wgsl/resolver/builtin_validation_test.cc b/src/tint/lang/wgsl/resolver/builtin_validation_test.cc
index 6b55f36..728a7b8 100644
--- a/src/tint/lang/wgsl/resolver/builtin_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/builtin_validation_test.cc
@@ -168,10 +168,12 @@
 
 2 candidate constructors:
  • 'i32(i32  ✗ ) -> i32'
- • 'i32() -> i32'
+ • 'i32() -> i32' where:
+      ✗  overload expects 0 arguments, call passed 3 arguments
 
 1 candidate conversion:
  • 'i32(T  ✓ ) -> i32' where:
+      ✗  overload expects 1 argument, call passed 3 arguments
       ✓  'T' is 'abstract-int', 'abstract-float', 'f32', 'f16', 'u32' or 'bool'
 )");
 }
diff --git a/src/tint/lang/wgsl/resolver/call_validation_test.cc b/src/tint/lang/wgsl/resolver/call_validation_test.cc
index b10f3fc..d7b4c57 100644
--- a/src/tint/lang/wgsl/resolver/call_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/call_validation_test.cc
@@ -523,7 +523,7 @@
 
 2 candidate functions:
  • 'min(T  ✓ , T  ✓ ) -> T' where:
-      ✗  overload expects 0 template arguments
+      ✗  overload expects 0 template arguments, call passed 1 argument
       ✓  'T' is 'abstract-float', 'abstract-int', 'f32', 'i32', 'u32' or 'f16'
  • 'min(vecN<T>  ✗ , vecN<T>  ✗ ) -> vecN<T>' where:
       ✗  'T' is 'abstract-float', 'abstract-int', 'f32', 'i32', 'u32' or 'f16'