diff --git a/src/dmd/mtype.d b/src/dmd/mtype.d index f5c51902ce9a..54ad5f70e68a 100644 --- a/src/dmd/mtype.d +++ b/src/dmd/mtype.d @@ -4780,19 +4780,20 @@ extern (C++) final class TypeFunction : TypeNext } // arguments get specially formatted - private const(char)* getParamError(const(char)* format, Expression arg, Parameter par) + private const(char)* getParamError(Expression arg, Parameter par) { // show qualification when toChars() is the same but types are different auto at = arg.type.toChars(); bool qual = !arg.type.equals(par.type) && strcmp(at, par.type.toChars()) == 0; if (qual) at = arg.type.toPrettyChars(true); - OutBuffer as; - as.printf("`%s` of type `%s`", arg.toChars(), at); - OutBuffer ps; - ps.printf("`%s`", parameterToChars(par, this, qual)); OutBuffer buf; - buf.printf(format, as.peekString(), ps.peekString()); + // only mention rvalue if it's relevant + const rv = !arg.isLvalue() && par.storageClass & (STC.ref_ | STC.out_); + const char* fmt = rv ? + "cannot pass rvalue argument `%s` of type `%s` to parameter `%s`" : + "cannot pass argument `%s` of type `%s` to parameter `%s`"; + buf.printf(fmt, arg.toChars(), at, parameterToChars(par, this, qual)); return buf.extractString(); } @@ -4935,7 +4936,7 @@ extern (C++) final class TypeFunction : TypeNext { if (p.storageClass & STC.out_) { - if (pMessage) *pMessage = getParamError("cannot pass rvalue argument %s to parameter %s", arg, p); + if (pMessage) *pMessage = getParamError(arg, p); goto Nomatch; } @@ -4960,7 +4961,7 @@ extern (C++) final class TypeFunction : TypeNext } else { - if (pMessage) *pMessage = getParamError("cannot pass rvalue argument %s to parameter %s", arg, p); + if (pMessage) *pMessage = getParamError(arg, p); goto Nomatch; } } @@ -4987,9 +4988,7 @@ extern (C++) final class TypeFunction : TypeNext */ if (!ta.constConv(tp)) { - if (pMessage) *pMessage = getParamError( - arg.isLvalue() ? "cannot pass argument %s to parameter %s" : - "cannot pass rvalue argument %s to parameter %s", arg, p); + if (pMessage) *pMessage = getParamError(arg, p); goto Nomatch; } } @@ -5049,7 +5048,7 @@ extern (C++) final class TypeFunction : TypeNext if (m == MATCH.nomatch) { - if (pMessage) *pMessage = getParamError("cannot pass argument %s to parameter %s", arg, p); + if (pMessage) *pMessage = getParamError(arg, p); goto Nomatch; } if (m < match) @@ -5067,7 +5066,7 @@ extern (C++) final class TypeFunction : TypeNext } } if (pMessage && u < nargs) - *pMessage = getParamError("cannot pass argument %s to parameter %s", (*args)[u], p); + *pMessage = getParamError((*args)[u], p); goto Nomatch; } if (m < match) diff --git a/test/fail_compilation/bug15613.d b/test/fail_compilation/bug15613.d index e8072fdbaf87..5b16f72ca232 100644 --- a/test/fail_compilation/bug15613.d +++ b/test/fail_compilation/bug15613.d @@ -16,3 +16,18 @@ void main() f(null); g(8); } + +/* +TEST_OUTPUT: +--- +fail_compilation/bug15613.d(32): Error: function `bug15613.h(int[]...)` is not callable using argument types `(int, void function(int[]...))` +fail_compilation/bug15613.d(32): cannot pass argument `& h` of type `void function(int[]...)` to parameter `int[]...` +--- +*/ + +void h(int[]...); + +void test() +{ + h(7, &h); +}