Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 38 additions & 6 deletions src/dmd/mtype.d
Original file line number Diff line number Diff line change
Expand Up @@ -4514,6 +4514,15 @@ extern (C++) final class TypeFunction : TypeNext
return buf.extractString();
}

private extern(D) const(char)* getMatchError(A...)(const(char)* format, A args)
{
if (global.gag && !global.params.showGaggedErrors)
return null;
OutBuffer buf;
buf.printf(format, args);
return buf.extractString();
}

/********************************
* 'args' are being matched to function 'this'
* Determine match level.
Expand Down Expand Up @@ -4560,13 +4569,15 @@ extern (C++) final class TypeFunction : TypeNext

size_t nparams = Parameter.dim(parameters);
size_t nargs = args ? args.dim : 0;
if (nparams == nargs)
{
}
else if (nargs > nparams)
if (nargs > nparams)
{
if (varargs == 0)
goto Nomatch;
{
// suppress early exit if an error message is wanted,
// so we can check any matching args are valid
if (!pMessage)
goto Nomatch;
}
// too many args; no match
match = MATCH.convert; // match ... with a "conversion" match level
}
Expand Down Expand Up @@ -4614,8 +4625,8 @@ extern (C++) final class TypeFunction : TypeNext
{
if (p.defaultArg)
continue;
goto L1;
// try typesafe variadics
goto L1;
}
{
Expression arg = (*args)[u];
Expand Down Expand Up @@ -4733,7 +4744,19 @@ extern (C++) final class TypeFunction : TypeNext
tsa = cast(TypeSArray)tb;
sz = tsa.dim.toInteger();
if (sz != nargs - u)
{
if (pMessage)
// Windows (Vista) OutBuffer.vprintf issue? 2nd argument always zero
//*pMessage = getMatchError("expected %d variadic argument(s), not %d", sz, nargs - u);
if (!global.gag || global.params.showGaggedErrors)
{
OutBuffer buf;
buf.printf("expected %d variadic argument(s)", sz);
buf.printf(", not %d", nargs - u);
*pMessage = buf.extractString();
}
goto Nomatch;
}
goto case Tarray;
case Tarray:
{
Expand Down Expand Up @@ -4784,13 +4807,22 @@ extern (C++) final class TypeFunction : TypeNext
}
if (pMessage && u < nargs)
*pMessage = getParamError((*args)[u], p);
else if (pMessage)
*pMessage = getMatchError("missing argument for parameter #%d: `%s`",
u + 1, parameterToChars(p, this, false));
goto Nomatch;
}
if (m < match)
match = m; // pick worst match
}

Ldone:
if (pMessage && !varargs && nargs > nparams)
{
// all parameters had a match, but there are surplus args
*pMessage = getMatchError("expected %d argument(s), not %d", nparams, nargs);
goto Nomatch;
}
//printf("match = %d\n", match);
return match;

Expand Down
18 changes: 18 additions & 0 deletions test/fail_compilation/bug16165.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
void f(int x, Object y);

void g()
{
Object o;
f(o, o, 404);
f(5, 6, 404);
}

/*
TEST_OUTPUT:
---
fail_compilation/bug16165.d(6): Error: function `bug16165.f(int x, Object y)` is not callable using argument types `(Object, Object, int)`
fail_compilation/bug16165.d(6): cannot pass argument `o` of type `object.Object` to parameter `int x`
fail_compilation/bug16165.d(7): Error: function `bug16165.f(int x, Object y)` is not callable using argument types `(int, int, int)`
fail_compilation/bug16165.d(7): cannot pass argument `6` of type `int` to parameter `Object y`
---
*/
47 changes: 24 additions & 23 deletions test/fail_compilation/diag8101.d
Original file line number Diff line number Diff line change
@@ -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): missing argument for parameter #1: `int`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this error message look like with several missing arguments?

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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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(22): Error: function `fail332.foo(int _param_0, ...)` is not callable using argument types `()`
fail_compilation/fail332.d(22): missing argument for parameter #1: `int _param_0`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is _param_0 mentioned sometimes and sometimes it's not, i.e.: https://github.com/dlang/dmd/pull/7584/files#diff-534158a8eaceb0162bf8ef17709be089R33

fail_compilation/fail332.d(23): Error: function `fail332.foo(int _param_0, ...)` is not callable using argument types `(typeof(null))`
fail_compilation/fail332.d(23): cannot pass argument `null` of type `typeof(null)` to parameter `int _param_0`
fail_compilation/fail332.d(25): Error: function `fail332.baz(int[] _param_0...)` is not callable using argument types `(string)`
fail_compilation/fail332.d(25): cannot pass argument `""` of type `string` to parameter `int[] _param_0...`
fail_compilation/fail332.d(26): Error: function `fail332.baz(int[] _param_0...)` is not callable using argument types `(int, typeof(null))`
fail_compilation/fail332.d(26): 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): missing argument for parameter #1: `Object`
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
Original file line number Diff line number Diff line change
@@ -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): missing argument for parameter #1: `int`
---
*/

Expand Down
3 changes: 2 additions & 1 deletion test/fail_compilation/ice10922.d
Original file line number Diff line number Diff line change
@@ -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): missing argument for parameter #1: `const(uint) n`
---
*/

Expand Down
8 changes: 5 additions & 3 deletions test/fail_compilation/ice12501.d
Original file line number Diff line number Diff line change
@@ -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(31): Error: function `ice12501.foo(int value)` is not callable using argument types `(int, int)`
fail_compilation/ice12501.d(31): expected 1 argument(s), not 2
fail_compilation/ice12501.d(31): Error: function `ice12501.foo(int value)` is not callable using argument types `(int, int)`
fail_compilation/ice12501.d(31): expected 1 argument(s), not 2
fail_compilation/ice12501.d(45): 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
Original file line number Diff line number Diff line change
@@ -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(35): Error: function `ice9540.A.test.AddFront!(this, f).AddFront.dg(int _param_0)` is not callable using argument types `()`
fail_compilation/ice9540.d(35): missing argument for parameter #1: `int _param_0`
fail_compilation/ice9540.d(26): Error: template instance `ice9540.A.test.AddFront!(this, f)` error instantiating
---
*/

Expand Down