Template function named argument error messages

This commit is contained in:
abul 2025-04-20 14:33:02 +05:30 committed by Nicholas Wilson
parent 283547e3af
commit ddb917f8e8
4 changed files with 108 additions and 27 deletions

View file

@ -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);
}
@ -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;
@ -1920,6 +1926,62 @@ FuncDeclaration resolveFuncCall(Loc loc, Scope* sc, Dsymbol s,
return null;
}
/********************************************************
* 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 report
*/
private void checkNamedArgErrorAndReportOverload(Dsymbol od, ArgumentList argumentList, Loc loc)
{
if (!argumentList.hasNames())
return;
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:

View file

@ -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) --> (no parameter named `x`)
}

View file

@ -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)`
---
*/

View file

@ -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)`
---
*/