Skip to content
Closed
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
78 changes: 74 additions & 4 deletions compiler/src/dmd/funcsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -1763,13 +1763,17 @@ FuncDeclaration resolveFuncCall(Loc loc, Scope* sc, Dsymbol s,
if (!od && !td.overnext)
{
.error(loc, "%s `%s` is not callable using argument types `!(%s)%s`",
td.kind(), td.ident.toChars(), tiargsBuf.peekChars(), fargsBuf.peekChars());
td.kind(), td.ident.toChars(), tiargsBuf.peekChars(), fargsBuf.peekChars());

checkNamedArgErrorAndReport(td, argumentList, loc);
}
else
{
.error(loc, "none of the overloads of %s `%s.%s` are callable using argument types `!(%s)%s`",
td.kind(), td.parent.toPrettyChars(), td.ident.toChars(),
tiargsBuf.peekChars(), fargsBuf.peekChars());
td.kind(), td.parent.toPrettyChars(), td.ident.toChars(),
tiargsBuf.peekChars(), fargsBuf.peekChars());

checkNamedArgErrorAndReport(td, argumentList, loc);
}


Expand All @@ -1789,7 +1793,9 @@ FuncDeclaration resolveFuncCall(Loc loc, Scope* sc, Dsymbol s,
if (od)
{
.error(loc, "none of the overloads of `%s` are callable using argument types `!(%s)%s`",
od.ident.toChars(), tiargsBuf.peekChars(), fargsBuf.peekChars());
od.ident.toChars(), tiargsBuf.peekChars(), fargsBuf.peekChars());

checkNamedArgErrorAndReportOverload(od, argumentList, loc);
if (!global.gag || global.params.v.showGaggedErrors)
printCandidates(loc, od, sc.isDeprecated());
return null;
Expand Down Expand Up @@ -1920,6 +1926,70 @@ FuncDeclaration resolveFuncCall(Loc loc, Scope* sc, Dsymbol s,
return null;
}

/*******************************************
* Prints template and function overload candidates as supplemental errors.
* Params:
* loc = instantiation location
* declaration = the declaration to print overload candidates for
* showDeprecated = If `false`, `deprecated` function won't be shown
*/
/**************************************
* Check for named argument errors in template declarations and report them.
* Params:
* td = template declaration to check
* argumentList = arguments to check
* loc = location for error reporting
*/
private void checkNamedArgErrorAndReport(TemplateDeclaration td, ArgumentList argumentList, Loc loc)
{
if (!argumentList.hasNames())
return;

auto tf = td.onemember ? td.onemember.isFuncDeclaration() : null;
if (tf && tf.type && tf.type.ty == Tfunction)
{
OutBuffer buf;
auto resolvedArgs = tf.type.isTypeFunction().resolveNamedArgs(argumentList, &buf);
if (!resolvedArgs && buf.length)
.errorSupplemental(loc, "%s", buf.peekChars());
}
}

/**************************************
* Check for named argument errors in overload sets and report them.
* Params:
* od = overload declaration to check
* argumentList = arguments to check
* loc = location for error reporting
*/
private void checkNamedArgErrorAndReportOverload(Dsymbol od, ArgumentList argumentList, Loc loc)
{
if (!argumentList.hasNames())
return;

// Try to find a function declaration to check named arguments
FuncDeclaration tf = null;
overloadApply(od, (Dsymbol s) {
if (!tf)
{
if (auto fd = s.isFuncDeclaration())
tf = fd;
else if (auto td = s.isTemplateDeclaration())
if (td.onemember)
tf = td.onemember.isFuncDeclaration();
}
return 0;
});

if (tf && tf.type && tf.type.ty == Tfunction)
{
OutBuffer buf;
auto resolvedArgs = tf.type.isTypeFunction().resolveNamedArgs(argumentList, &buf);
if (!resolvedArgs && buf.length)
.errorSupplemental(loc, "%s", buf.peekChars());
}
}

/*******************************************
* Prints template and function overload candidates as supplemental errors.
* Params:
Expand Down
15 changes: 15 additions & 0 deletions compiler/test/fail_compilation/fix21042.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
TEST_OUTPUT:
---
fail_compilation/fix21042.d(14): Error: template `gun` is not callable using argument types `!()(int)`
fail_compilation/fix21042.d(14): no parameter named `x`
fail_compilation/fix21042.d(10): Candidate is: `gun(T)(T a)`
---
*/

void gun(T)(T a) {}

void main()
{
gun(x: 1); // (no explanation)
}
35 changes: 18 additions & 17 deletions compiler/test/fail_compilation/named_arguments_error.d
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
/*
TEST_OUTPUT:
---
fail_compilation/named_arguments_error.d(37): Error: function `f` is not callable using argument types `(int, int, int)`
fail_compilation/named_arguments_error.d(37): parameter `x` assigned twice
fail_compilation/named_arguments_error.d(31): `named_arguments_error.f(int x, int y, int z)` declared here
fail_compilation/named_arguments_error.d(38): Error: function `f` is not callable using argument types `(int, int, int)`
fail_compilation/named_arguments_error.d(38): argument `4` goes past end of parameter list
fail_compilation/named_arguments_error.d(31): `named_arguments_error.f(int x, int y, int z)` declared here
fail_compilation/named_arguments_error.d(38): parameter `x` assigned twice
fail_compilation/named_arguments_error.d(32): `named_arguments_error.f(int x, int y, int z)` declared here
fail_compilation/named_arguments_error.d(39): Error: function `f` is not callable using argument types `(int, int, int)`
fail_compilation/named_arguments_error.d(39): parameter `y` assigned twice
fail_compilation/named_arguments_error.d(31): `named_arguments_error.f(int x, int y, int z)` declared here
fail_compilation/named_arguments_error.d(39): argument `4` goes past end of parameter list
fail_compilation/named_arguments_error.d(32): `named_arguments_error.f(int x, int y, int z)` declared here
fail_compilation/named_arguments_error.d(40): Error: function `f` is not callable using argument types `(int, int, int)`
fail_compilation/named_arguments_error.d(40): no parameter named `a`
fail_compilation/named_arguments_error.d(31): `named_arguments_error.f(int x, int y, int z)` declared here
fail_compilation/named_arguments_error.d(41): Error: function `g` is not callable using argument types `(int, int)`
fail_compilation/named_arguments_error.d(41): missing argument for parameter #1: `int x`
fail_compilation/named_arguments_error.d(33): `named_arguments_error.g(int x, int y, int z = 3)` declared here
fail_compilation/named_arguments_error.d(43): Error: no named argument `element` allowed for array dimension
fail_compilation/named_arguments_error.d(44): Error: no named argument `number` allowed for scalar
fail_compilation/named_arguments_error.d(45): Error: cannot implicitly convert expression `g(x: 3, y: 4, z: 5)` of type `int` to `string`
fail_compilation/named_arguments_error.d(46): Error: template `tempfun` is not callable using argument types `!()(int, int)`
fail_compilation/named_arguments_error.d(49): Candidate is: `tempfun(T, U)(T t, U u)`
fail_compilation/named_arguments_error.d(40): parameter `y` assigned twice
fail_compilation/named_arguments_error.d(32): `named_arguments_error.f(int x, int y, int z)` declared here
fail_compilation/named_arguments_error.d(41): Error: function `f` is not callable using argument types `(int, int, int)`
fail_compilation/named_arguments_error.d(41): no parameter named `a`
fail_compilation/named_arguments_error.d(32): `named_arguments_error.f(int x, int y, int z)` declared here
fail_compilation/named_arguments_error.d(42): Error: function `g` is not callable using argument types `(int, int)`
fail_compilation/named_arguments_error.d(42): missing argument for parameter #1: `int x`
fail_compilation/named_arguments_error.d(34): `named_arguments_error.g(int x, int y, int z = 3)` declared here
fail_compilation/named_arguments_error.d(44): Error: no named argument `element` allowed for array dimension
fail_compilation/named_arguments_error.d(45): Error: no named argument `number` allowed for scalar
fail_compilation/named_arguments_error.d(46): Error: cannot implicitly convert expression `g(x: 3, y: 4, z: 5)` of type `int` to `string`
fail_compilation/named_arguments_error.d(47): Error: template `tempfun` is not callable using argument types `!()(int, int)`
fail_compilation/named_arguments_error.d(47): argument `1` goes past end of parameter list
fail_compilation/named_arguments_error.d(50): Candidate is: `tempfun(T, U)(T t, U u)`
---
*/

Expand Down
15 changes: 9 additions & 6 deletions compiler/test/fail_compilation/named_arguments_ifti_error.d
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
/*
TEST_OUTPUT:
---
fail_compilation/named_arguments_ifti_error.d(17): Error: template `f` is not callable using argument types `!()(int, int)`
fail_compilation/named_arguments_ifti_error.d(13): Candidate is: `f(T, U)(T x, U y)`
fail_compilation/named_arguments_ifti_error.d(18): Error: template `f` is not callable using argument types `!()(int, int)`
fail_compilation/named_arguments_ifti_error.d(13): Candidate is: `f(T, U)(T x, U y)`
fail_compilation/named_arguments_ifti_error.d(19): Error: template `f` is not callable using argument types `!()(int)`
fail_compilation/named_arguments_ifti_error.d(13): Candidate is: `f(T, U)(T x, U y)`
fail_compilation/named_arguments_ifti_error.d(20): Error: template `f` is not callable using argument types `!()(int, int)`
fail_compilation/named_arguments_ifti_error.d(20): parameter `x` assigned twice
fail_compilation/named_arguments_ifti_error.d(16): Candidate is: `f(T, U)(T x, U y)`
fail_compilation/named_arguments_ifti_error.d(21): Error: template `f` is not callable using argument types `!()(int, int)`
fail_compilation/named_arguments_ifti_error.d(21): argument `3` goes past end of parameter list
fail_compilation/named_arguments_ifti_error.d(16): Candidate is: `f(T, U)(T x, U y)`
fail_compilation/named_arguments_ifti_error.d(22): Error: template `f` is not callable using argument types `!()(int)`
fail_compilation/named_arguments_ifti_error.d(22): missing argument for parameter #1: `T x`
fail_compilation/named_arguments_ifti_error.d(16): Candidate is: `f(T, U)(T x, U y)`
---
*/

Expand Down
Loading