[Issue 16573] string-typed enum values pass isSomeString but not isInputRange

via Digitalmars-d-bugs digitalmars-d-bugs at puremagic.com
Sun Oct 2 07:37:34 PDT 2016


https://issues.dlang.org/show_bug.cgi?id=16573

Jonathan M Davis <issues.dlang at jmdavisProg.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |issues.dlang at jmdavisProg.co
                   |                            |m

--- Comment #1 from Jonathan M Davis <issues.dlang at jmdavisProg.com> ---
The reason that it's not considered an input range is that it doesn't compile
with popFront. e.g.


void main()
{
    import std.range;
    enum S { foo = "foo" }
    S s;
    s.popFront();
}

results in

q.d(6): Error: template std.range.primitives.popFront cannot deduce function
from argument types !()(S), candidates are:
/usr/local/include/d/phobos/std/range/primitives.d(2039):       
std.range.primitives.popFront(T)(ref T[] a) if (!isNarrowString!(T[]) &&
!is(T[] == void[]))
/usr/local/include/d/phobos/std/range/primitives.d(2062):       
std.range.primitives.popFront(C)(ref C[] str) if (isNarrowString!(C[]))

and it looks like that fails, because popFront takes its argument by ref and
that parameter is a dynamic array, and since passing an enum to a function that
takes something else requires a converison, and ref doesn't work with
conversions, the enum can't be used with popFront even though it converts to a
string.

Personally, I'm surprised that isSomeString works with an enum. I thought that
we made it so that it didn't, since it was an enum and not actually a string,
but it looks like it's been that way for at least a few releases, so I could
just be misremembering. In general though, treating implicit conversions like
that as if they were the base type is mine field of problems with generic code,
so I can't say that I'm particularly pleased that isSomeString is true for an
enum, even if its base type is string. isSomeString _does_ properly fail with
other types of implicit conversions though.

As for isInputRange, I really don't think that it makes sense for it to be true
for an enum, because as soon as you pop the front off, it's bound to no longer
be one of the members of the enum. Really, the enum needs to be properly
converted to a string before doing anything like that to it.

So, I don't know if isSomeString should be changed (I'd like it if it were, but
it's probably too late at this point), but I really don't think that
isInputRange should be. So, the question is what to do with exists to fix the
regression.

Looking at exists, I think that the problem is isConvertibleToString. For some
reason, it doesn't work with enums (which really doesn't make sense given its
name). If it did, then exists would work, because the overload whose constraint
is isConvertibleToString!R would convert the enum to a string to pass to the
other overload, and it would work.

So, I think that what should be done is to make isConvertibleToString work with
enums - though given that isSomeString erroneously thinks that an enum with the
base type string is a string, that could cause problems. Though for some
reason, isConvertibleToString isn't actually documented, so there shouldn't be
code in wild using it, and we shouldn't break code outside of Phobos if we made
the change. Still, the fact that isSomeString thinks that an enum is a string
does make things a bit murky. It really shouldn't.

--


More information about the Digitalmars-d-bugs mailing list