Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use OutBuffer to build and pass around strings #17087

Merged
merged 1 commit into from
Nov 25, 2024
Merged
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
8 changes: 4 additions & 4 deletions compiler/src/dmd/expressionsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
22 changes: 11 additions & 11 deletions compiler/src/dmd/mtype.d
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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)
Expand All @@ -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;
Expand All @@ -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
Expand Down
30 changes: 19 additions & 11 deletions compiler/src/dmd/typesem.d
Original file line number Diff line number Diff line change
Expand Up @@ -753,13 +753,14 @@
}
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());

Check warning on line 763 in compiler/src/dmd/typesem.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/typesem.d#L763

Added line #L763 was not covered by tests
return MATCH.nomatch;
}

Expand Down Expand Up @@ -820,6 +821,11 @@
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;
Expand All @@ -846,15 +852,17 @@
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)
Expand Down
Loading