Skip to content

Commit

Permalink
Fix Issue 16165 - Show count of arguments vs parameters on mismatch
Browse files Browse the repository at this point in the history
  • Loading branch information
ntrel authored and thewilsonator committed Nov 25, 2018
1 parent b979aae commit b14d8f8
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 33 deletions.
16 changes: 16 additions & 0 deletions src/dmd/mtype.d
Expand Up @@ -4514,6 +4514,13 @@ extern (C++) final class TypeFunction : TypeNext
return buf.extractString();
}

private const(char)* getMatchError(A...)(const(char)* format, A args)
{
OutBuffer buf;
buf.printf(format, args);
return buf.extractString();
}

/********************************
* 'args' are being matched to function 'this'
* Determine match level.
Expand Down Expand Up @@ -4566,7 +4573,10 @@ extern (C++) final class TypeFunction : TypeNext
else if (nargs > nparams)
{
if (varargs == 0)
{
if (pMessage) *pMessage = getMatchError("expected %d argument(s), not %d", nparams, nargs);
goto Nomatch;
}
// too many args; no match
match = MATCH.convert; // match ... with a "conversion" match level
}
Expand Down Expand Up @@ -4733,7 +4743,11 @@ extern (C++) final class TypeFunction : TypeNext
tsa = cast(TypeSArray)tb;
sz = tsa.dim.toInteger();
if (sz != nargs - u)
{
if (pMessage) *pMessage = getMatchError("expected %d variadic argument(s), not %d",
sz, nargs - u);
goto Nomatch;
}
goto case Tarray;
case Tarray:
{
Expand Down Expand Up @@ -4784,6 +4798,8 @@ extern (C++) final class TypeFunction : TypeNext
}
if (pMessage && u < nargs)
*pMessage = getParamError((*args)[u], p);
else if (pMessage)
*pMessage = getMatchError("expected %d argument(s), not %d", nparams, nargs);
goto Nomatch;
}
if (m < match)
Expand Down
47 changes: 24 additions & 23 deletions test/fail_compilation/diag8101.d
@@ -1,29 +1,30 @@
/*
TEST_OUTPUT:
---
fail_compilation/diag8101.d(56): Error: function `diag8101.f_0(int)` is not callable using argument types `()`
fail_compilation/diag8101.d(57): Error: none of the overloads of `f_1` are callable using argument types `()`, candidates are:
fail_compilation/diag8101.d(32): `diag8101.f_1(int)`
fail_compilation/diag8101.d(33): `diag8101.f_1(int, int)`
fail_compilation/diag8101.d(58): Error: none of the overloads of `f_2` are callable using argument types `()`, candidates are:
fail_compilation/diag8101.d(35): `diag8101.f_2(int)`
fail_compilation/diag8101.d(36): `diag8101.f_2(int, int)`
fail_compilation/diag8101.d(37): `diag8101.f_2(int, int, int)`
fail_compilation/diag8101.d(38): `diag8101.f_2(int, int, int, int)`
fail_compilation/diag8101.d(39): `diag8101.f_2(int, int, int, int, int)`
fail_compilation/diag8101.d(58): ... (1 more, -v to show) ...
fail_compilation/diag8101.d(60): Error: template `diag8101.t_0` cannot deduce function from argument types `!()()`, candidates are:
fail_compilation/diag8101.d(42): `diag8101.t_0(T1)()`
fail_compilation/diag8101.d(61): Error: template `diag8101.t_1` cannot deduce function from argument types `!()()`, candidates are:
fail_compilation/diag8101.d(44): `diag8101.t_1(T1)()`
fail_compilation/diag8101.d(45): `diag8101.t_1(T1, T2)()`
fail_compilation/diag8101.d(62): Error: template `diag8101.t_2` cannot deduce function from argument types `!()()`, candidates are:
fail_compilation/diag8101.d(47): `diag8101.t_2(T1)()`
fail_compilation/diag8101.d(48): `diag8101.t_2(T1, T2)()`
fail_compilation/diag8101.d(49): `diag8101.t_2(T1, T2, T3)()`
fail_compilation/diag8101.d(50): `diag8101.t_2(T1, T2, T3, T4)()`
fail_compilation/diag8101.d(51): `diag8101.t_2(T1, T2, T3, T4, T5)()`
fail_compilation/diag8101.d(62): ... (1 more, -v to show) ...
fail_compilation/diag8101.d(57): Error: function `diag8101.f_0(int)` is not callable using argument types `()`
fail_compilation/diag8101.d(57): expected 1 argument(s), not 0
fail_compilation/diag8101.d(58): Error: none of the overloads of `f_1` are callable using argument types `()`, candidates are:
fail_compilation/diag8101.d(33): `diag8101.f_1(int)`
fail_compilation/diag8101.d(34): `diag8101.f_1(int, int)`
fail_compilation/diag8101.d(59): Error: none of the overloads of `f_2` are callable using argument types `()`, candidates are:
fail_compilation/diag8101.d(36): `diag8101.f_2(int)`
fail_compilation/diag8101.d(37): `diag8101.f_2(int, int)`
fail_compilation/diag8101.d(38): `diag8101.f_2(int, int, int)`
fail_compilation/diag8101.d(39): `diag8101.f_2(int, int, int, int)`
fail_compilation/diag8101.d(40): `diag8101.f_2(int, int, int, int, int)`
fail_compilation/diag8101.d(59): ... (1 more, -v to show) ...
fail_compilation/diag8101.d(61): Error: template `diag8101.t_0` cannot deduce function from argument types `!()()`, candidates are:
fail_compilation/diag8101.d(43): `diag8101.t_0(T1)()`
fail_compilation/diag8101.d(62): Error: template `diag8101.t_1` cannot deduce function from argument types `!()()`, candidates are:
fail_compilation/diag8101.d(45): `diag8101.t_1(T1)()`
fail_compilation/diag8101.d(46): `diag8101.t_1(T1, T2)()`
fail_compilation/diag8101.d(63): Error: template `diag8101.t_2` cannot deduce function from argument types `!()()`, candidates are:
fail_compilation/diag8101.d(48): `diag8101.t_2(T1)()`
fail_compilation/diag8101.d(49): `diag8101.t_2(T1, T2)()`
fail_compilation/diag8101.d(50): `diag8101.t_2(T1, T2, T3)()`
fail_compilation/diag8101.d(51): `diag8101.t_2(T1, T2, T3, T4)()`
fail_compilation/diag8101.d(52): `diag8101.t_2(T1, T2, T3, T4, T5)()`
fail_compilation/diag8101.d(63): ... (1 more, -v to show) ...
---
*/

Expand Down
3 changes: 2 additions & 1 deletion test/fail_compilation/diag9420.d
@@ -1,7 +1,8 @@
/*
TEST_OUTPUT
---
fail_compilation/diag9420.d(20): Error: function `diag9420.S.t3!().tx()` is not callable using argument types `(int)`
fail_compilation\diag9420.d(21): Error: function `diag9420.S.t3!().tx()` is not callable using argument types `(int)`
fail_compilation\diag9420.d(21): expected 0 argument(s), not 1
---
*/

Expand Down
45 changes: 43 additions & 2 deletions test/fail_compilation/fail332.d
@@ -1,15 +1,56 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail332.d(14): Error: function `fail332.foo(int _param_0, ...)` is not callable using argument types `()`
fail_compilation\fail332.d(32): Error: function `fail332.foo(int _param_0, ...)` is not callable using argument types `()`
fail_compilation\fail332.d(32): expected 1 argument(s), not 0
fail_compilation\fail332.d(33): Error: function `fail332.foo(int _param_0, ...)` is not callable using argument types `(typeof(null))`
fail_compilation\fail332.d(33): cannot pass argument `null` of type `typeof(null)` to parameter `int _param_0`
fail_compilation\fail332.d(35): Error: function `fail332.baz(int[] _param_0...)` is not callable using argument types `(string)`
fail_compilation\fail332.d(35): cannot pass argument `""` of type `string` to parameter `int[] _param_0...`
fail_compilation\fail332.d(36): Error: function `fail332.baz(int[] _param_0...)` is not callable using argument types `(int, typeof(null))`
fail_compilation\fail332.d(36): cannot pass argument `null` of type `typeof(null)` to parameter `int[] _param_0...`
---
*/

import core.vararg;

void foo(int, ...) {}
void baz(int[]...) {}

void bar()
void test()
{
foo();
foo(null);

baz("");
baz(3, null);
}

/*
TEST_OUTPUT:
---
fail_compilation\fail332.d(50): Error: function `fail332.bar(Object, int[2]...)` is not callable using argument types `()`
fail_compilation\fail332.d(50): expected 2 argument(s), not 0
fail_compilation\fail332.d(51): Error: function `fail332.bar(Object, int[2]...)` is not callable using argument types `(int)`
fail_compilation\fail332.d(51): cannot pass argument `4` of type `int` to parameter `Object`
fail_compilation\fail332.d(52): Error: function `fail332.bar(Object, int[2]...)` is not callable using argument types `(typeof(null))`
fail_compilation\fail332.d(52): expected 2 variadic argument(s), not 0
fail_compilation\fail332.d(53): Error: function `fail332.bar(Object, int[2]...)` is not callable using argument types `(typeof(null), int)`
fail_compilation\fail332.d(53): expected 2 variadic argument(s), not 1
fail_compilation\fail332.d(54): Error: function `fail332.bar(Object, int[2]...)` is not callable using argument types `(typeof(null), int, string)`
fail_compilation\fail332.d(54): cannot pass argument `""` of type `string` to parameter `int[2]...`
fail_compilation\fail332.d(55): Error: function `fail332.bar(Object, int[2]...)` is not callable using argument types `(typeof(null), int, int, int)`
fail_compilation\fail332.d(55): expected 2 variadic argument(s), not 3
---
*/
void bar(Object, int[2]...);

void test2()
{
bar();
bar(4);
bar(null);
bar(null, 2);
bar(null, 2, "");
bar(null, 2,3,4);
}
3 changes: 2 additions & 1 deletion test/fail_compilation/fail99.d
@@ -1,7 +1,8 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail99.d(12): Error: delegate `dg(int)` is not callable using argument types `()`
fail_compilation/fail99.d(13): Error: delegate `dg(int)` is not callable using argument types `()`
fail_compilation/fail99.d(13): expected 1 argument(s), not 0
---
*/

Expand Down
3 changes: 2 additions & 1 deletion test/fail_compilation/ice10922.d
@@ -1,7 +1,8 @@
/*
TEST_OUTPUT:
---
fail_compilation/ice10922.d(9): Error: function `ice10922.__lambda4(const(uint) n)` is not callable using argument types `()`
fail_compilation/ice10922.d(10): Error: function `ice10922.__lambda4(const(uint) n)` is not callable using argument types `()`
fail_compilation/ice10922.d(10): expected 1 argument(s), not 0
---
*/

Expand Down
8 changes: 5 additions & 3 deletions test/fail_compilation/ice12501.d
@@ -1,9 +1,11 @@
/*
TEST_OUTPUT:
---
fail_compilation/ice12501.d(29): Error: function `ice12501.foo(int value)` is not callable using argument types `(int, int)`
fail_compilation/ice12501.d(29): Error: function `ice12501.foo(int value)` is not callable using argument types `(int, int)`
fail_compilation/ice12501.d(43): Error: template instance `ice12501.reduce!(foo, foo).reduce!(Tuple!(int, int), int[])` error instantiating
fail_compilation/ice12501.d(37): Error: function `ice12501.foo(int value)` is not callable using argument types `(int, int)`
fail_compilation/ice12501.d(37): expected 1 argument(s), not 2
fail_compilation/ice12501.d(37): Error: function `ice12501.foo(int value)` is not callable using argument types `(int, int)`
fail_compilation/ice12501.d(37): expected 1 argument(s), not 2
fail_compilation/ice12501.d(51): Error: template instance `ice12501.reduce!(foo, foo).reduce!(Tuple!(int, int), int[])` error instantiating
---
*/

Expand Down
5 changes: 3 additions & 2 deletions test/fail_compilation/ice9540.d
@@ -1,8 +1,9 @@
/*
TEST_OUTPUT:
---
fail_compilation/ice9540.d(34): Error: function `ice9540.A.test.AddFront!(this, f).AddFront.dg(int _param_0)` is not callable using argument types `()`
fail_compilation/ice9540.d(25): Error: template instance `ice9540.A.test.AddFront!(this, f)` error instantiating
fail_compilation/ice9540.d(40): Error: function `ice9540.A.test.AddFront!(this, f).AddFront.dg(int _param_0)` is not callable using argument types `()`
fail_compilation/ice9540.d(40): expected 1 argument(s), not 0
fail_compilation/ice9540.d(31): Error: template instance `ice9540.A.test.AddFront!(this, f)` error instantiating
---
*/

Expand Down

0 comments on commit b14d8f8

Please sign in to comment.