Proposed Enhancement: Deprecate std.conv.text With 0 Arguments
Meta via Digitalmars-d
digitalmars-d at puremagic.com
Wed Jun 22 08:39:11 PDT 2016
This is a small but annoying problem: std.conv.text is defined
like this:
string text(T...)(T args) { return textImpl!string(args); }
private S textImpl(S, U...)(U args)
{
static if (U.length == 0)
{
return null;
}
else
{
auto result = to!S(args[0]);
foreach (arg; args[1 .. $])
result ~= to!S(arg);
return result;
}
}
If it is called with 0 arguments it will return null. This
behaviour has caused several bugs in my code because combined
with optional parens and UFCS, it is easy to accidentally call
text with 0 args but have it look like passing a variable to a
function. An example bug that I recently found in my code:
Token getNextToken(ref string input)
{
assert(!input.empty);
while (input.front.isSpace)
{
input.advance(1);
}
if (input.front == '$' || input.front.isAlpha)
{
if (input.front == '$')
{
//BUG
text.advance(1);
}
auto identStr = input.getNextWord();
if (keywords.canFind(identStr))
{
return new Keyword(input.front == '$' ? '$' ~
identStr : identStr);
}
else
{
return new Identifier(identStr);
}
}
else if (input.front.isDigit || input.front == '-' ||
input.front == '+')
{
//etc.
}
else if (input.front == '"')
{
//etc.
}
//etc...
}
void advance(ref string input, size_t n)
{
foreach (_; 0..n)
{
if (input.empty)
{
break;
}
input.popFront();
}
}
The problem is that `advance` was not advancing the input,
causing bugs in the lexing stage. Usually the compiler would warn
me that no such variable `text` exists, but as I imported
std.conv, `text` was in scope. Since `text` can take 0 or more
arguments, and due to optional parens, `text.advance(1)` is a
valid expression that does nothing. If std.conv.text took only 1
or more arguments and refused to compile with 0 arguments, then
the compiler would signal an error as normal and I would not have
to spend an hour hunting down this bug.
I would like to make a pull request to fix this, deprecating the
0-argument case and then eventually making it an error, but would
this PR be accepted considering it technically breaks
backwards-compatibility?
More information about the Digitalmars-d
mailing list