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