diff --git a/compiler/src/dmd/funcsem.d b/compiler/src/dmd/funcsem.d index a02d9b7781..3b7b3097c9 100644 --- a/compiler/src/dmd/funcsem.d +++ b/compiler/src/dmd/funcsem.d @@ -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: diff --git a/compiler/test/fail_compilation/fix21042.d b/compiler/test/fail_compilation/fix21042.d new file mode 100644 index 0000000000..b2b224e519 --- /dev/null +++ b/compiler/test/fail_compilation/fix21042.d @@ -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`) +} diff --git a/compiler/test/fail_compilation/named_arguments_error.d b/compiler/test/fail_compilation/named_arguments_error.d index 125ebcc926..761e1d4c78 100644 --- a/compiler/test/fail_compilation/named_arguments_error.d +++ b/compiler/test/fail_compilation/named_arguments_error.d @@ -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)` --- */ diff --git a/compiler/test/fail_compilation/named_arguments_ifti_error.d b/compiler/test/fail_compilation/named_arguments_ifti_error.d index 6d8a70a2c4..a73fd3cb2e 100644 --- a/compiler/test/fail_compilation/named_arguments_ifti_error.d +++ b/compiler/test/fail_compilation/named_arguments_ifti_error.d @@ -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)` --- */