From 11930ec0db841b4b5d1b30c8d8aa2ae70740b6d2 Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Fri, 22 Nov 2024 22:00:42 -0800 Subject: [PATCH] use OutBuffer to build and pass around strings --- compiler/src/dmd/expressionsem.d | 8 ++++---- compiler/src/dmd/mtype.d | 22 +++++++++++----------- compiler/src/dmd/typesem.d | 30 +++++++++++++++++++----------- 3 files changed, 34 insertions(+), 26 deletions(-) diff --git a/compiler/src/dmd/expressionsem.d b/compiler/src/dmd/expressionsem.d index 86a35cf05b3e..2da3bd49d096 100644 --- a/compiler/src/dmd/expressionsem.d +++ b/compiler/src/dmd/expressionsem.d @@ -2964,14 +2964,14 @@ private bool functionParameters(const ref Loc loc, Scope* sc, if (argumentList.names) { - const(char)* msg = null; - auto resolvedArgs = tf.resolveNamedArgs(argumentList, &msg); + OutBuffer buf; + auto resolvedArgs = tf.resolveNamedArgs(argumentList, &buf); if (!resolvedArgs) { // while errors are usually already caught by `tf.callMatch`, // this can happen when calling `typeof(freefunc)` - if (msg) - error(loc, "%s", msg); + if (buf.length) + error(loc, "%s", buf.peekChars()); return true; } // note: the argument list should be mutated with named arguments / default arguments, diff --git a/compiler/src/dmd/mtype.d b/compiler/src/dmd/mtype.d index be70b02dec90..cedf95b039a5 100644 --- a/compiler/src/dmd/mtype.d +++ b/compiler/src/dmd/mtype.d @@ -2617,10 +2617,10 @@ extern (C++) final class TypeFunction : TypeNext * * Params: * argumentList = array of function arguments - * pMessage = address to store error message, or `null` + * buf = if not null, append error message to it * Returns: re-ordered argument list, or `null` on error */ - extern(D) Expressions* resolveNamedArgs(ArgumentList argumentList, const(char)** pMessage) + extern(D) Expressions* resolveNamedArgs(ArgumentList argumentList, OutBuffer* buf) { Expression[] args = argumentList.arguments ? (*argumentList.arguments)[] : null; Identifier[] names = argumentList.names ? (*argumentList.names)[] : null; @@ -2644,8 +2644,8 @@ extern (C++) final class TypeFunction : TypeNext const pi = findParameterIndex(name); if (pi == -1) { - if (pMessage) - *pMessage = getMatchError("no parameter named `%s`", name.toChars()); + if (buf) + buf.writestring(getMatchError("no parameter named `%s`", name.toChars())); return null; } ci = pi; @@ -2655,8 +2655,8 @@ extern (C++) final class TypeFunction : TypeNext if (!isVariadic) { // Without named args, let the caller diagnose argument overflow - if (hasNamedArgs && pMessage) - *pMessage = getMatchError("argument `%s` goes past end of parameter list", arg.toChars()); + if (hasNamedArgs && buf) + buf.writestring(getMatchError("argument `%s` goes past end of parameter list", arg.toChars())); return null; } while (ci >= newArgs.length) @@ -2665,8 +2665,8 @@ extern (C++) final class TypeFunction : TypeNext if ((*newArgs)[ci]) { - if (pMessage) - *pMessage = getMatchError("parameter `%s` assigned twice", parameterList[ci].toChars()); + if (buf) + buf.writestring(getMatchError("parameter `%s` assigned twice", parameterList[ci].toChars())); return null; } (*newArgs)[ci++] = arg; @@ -2684,9 +2684,9 @@ extern (C++) final class TypeFunction : TypeNext if (this.incomplete) continue; - if (pMessage) - *pMessage = getMatchError("missing argument for parameter #%d: `%s`", - i + 1, parameterToChars(parameterList[i], this, false)); + if (buf) + buf.writestring(getMatchError("missing argument for parameter #%d: `%s`", + i + 1, parameterToChars(parameterList[i], this, false))); return null; } // strip trailing nulls from default arguments diff --git a/compiler/src/dmd/typesem.d b/compiler/src/dmd/typesem.d index eebbf45573dc..45de3631f3f0 100644 --- a/compiler/src/dmd/typesem.d +++ b/compiler/src/dmd/typesem.d @@ -753,13 +753,14 @@ extern (D) MATCH callMatch(TypeFunction tf, Type tthis, ArgumentList argumentLis } const(char)* failMessage; const(char)** pMessage = errorHelper ? &failMessage : null; - auto resolvedArgs = tf.resolveNamedArgs(argumentList, pMessage); + OutBuffer buf; + auto resolvedArgs = tf.resolveNamedArgs(argumentList, errorHelper ? &buf : null); Expression[] args; if (!resolvedArgs) { - if (failMessage) + if (buf.length) { - errorHelper(failMessage); + errorHelper(buf.peekChars()); return MATCH.nomatch; } @@ -820,6 +821,11 @@ extern (D) MATCH callMatch(TypeFunction tf, Type tthis, ArgumentList argumentLis if (!arg) continue; // default argument m = argumentMatchParameter(tf, p, arg, wildmatch, flag, sc, pMessage); + if (failMessage) + { + buf.reset(); + buf.writestring(failMessage); + } } else if (p.defaultArg) continue; @@ -846,15 +852,17 @@ extern (D) MATCH callMatch(TypeFunction tf, Type tthis, ArgumentList argumentLis errorHelper(failMessage); return MATCH.nomatch; } - if (pMessage && u >= args.length) - *pMessage = tf.getMatchError("missing argument for parameter #%d: `%s`", - u + 1, parameterToChars(p, tf, false)); - // If an error happened previously, `pMessage` was already filled - else if (pMessage && !*pMessage) - *pMessage = tf.getParamError(args[u], p); - if (errorHelper) - errorHelper(*pMessage); + { + if (u >= args.length) + buf.writestring(tf.getMatchError("missing argument for parameter #%d: `%s`", + u + 1, parameterToChars(p, tf, false))); + // If an error happened previously, `pMessage` was already filled + else if (buf.length == 0) + buf.writestring(tf.getParamError(args[u], p)); + + errorHelper(buf.peekChars()); + } return MATCH.nomatch; } if (m < match)