Converting all enum members to a string fails with version 2.0.72.0

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Nov 21 09:26:37 PST 2016


On Monday, November 21, 2016 17:01:56 Stefan via Digitalmars-d-learn wrote:
> Before 2.0.72.0:
>
> import std.algorithm : map, joiner;
> import std.uni : toUpper;
> import std.traits : EnumMembers;
> import std.stdio : writeln;
> import std.conv: to;
>
> private enum Color : string {
>      RED = "red",
>      BLUE = "blue",
>      YELLOW = "yellow"
> }
>
>
> void main(string[] args) {
>      writeln( [ EnumMembers!Color ].map!( toUpper ).joiner( ", "
> ).to!string );
> }
>
> printed:
> RED, BLUE, YELLOW
>
> Now I got the following compiler error:
> C:\develop\dmd-2.072.0\windows\bin\..\..\src\phobos\std\uni.d(8142,16):
> Error: cannot implicitly convert expression (result.data()) of type
> string to Color
> C:\develop\dmd-2.072.0\windows\bin\..\..\src\phobos\std\uni.d(9030,51):
> Error: template instance std.uni.toCase!(toUpperIndex, 1051, toUpperTab,
> toUpper, Color) error instantiating
> C:\develop\dmd-2.072.0\windows\bin\..\..\src\phobos\std\algorithm\iterati
> on.d(593,19):        instantiated from here: toUpper!(Color)
> C:\develop\dmd-2.072.0\windows\bin\..\..\src\phobos\std\algorithm\iterati
> on.d(488,16):        instantiated from here: MapResult!(toUpper, Color[])
> source\enums\enums.d(24,35):        instantiated from here:
> map!(Color[])
> source\enums\enums.d(24,58): Error: template
> std.algorithm.iteration.joiner cannot deduce function from
> argument types !()(MapResult!(toUpper, Color[]), string),
> candidates are:
> C:\develop\dmd-2.072.0\windows\bin\..\..\src\phobos\std\algorithm\iteratio
> n.d(2050,6):        std.algorithm.iteration.joiner(RoR, Separator)(RoR r,
> Separator sep) if (isInputRange!RoR && isInputRange!(ElementType!RoR) &&
> isForwardRange!Separator && is(ElementType!Separator :
> ElementType!(ElementType!RoR)))
> C:\develop\dmd-2.072.0\windows\bin\..\..\src\phobos\std\algorithm\iterati
> on.d(2333,6):        std.algorithm.iteration.joiner(RoR)(RoR r) if
> (isInputRange!RoR && isInputRange!(ElementType!RoR)) dmd failed with exit
> code 1.
>
> Any idea how to fix it?

Casting [EnumMembers!Color] to string[] will probably do it as would using
toUpper!string instead of toUpper. I think that the problem has to do with
Color not being an actual range, but it passes isSomeString, resulting in a
an ugly situation where the code basically assumes that it's dealing with a
string when it isn't really, and the code doesn't actually work with an
enum. Prior to 2.072.0, there was an overload for toUpper that took string
as an optimization but that inadvertently meant that types that implicitly
converted to strings worked with it and were converted to string, whereas
with 2.072.0, they now have to pass isSomeString. In the case of a struct
that implicitly converts to string or a static array of characters, it would
now simply fails the template constraint and fail to compile, whereas for an
enum with a base type of string, it's in this weird in between land where it
passes isSomeString but really needs to actually be converted to string to
work as a range. So, instead of failing the template constraint, it hits an
error inside of the std.uni stuff. I think that the change is getting
reverted for 2.072.1, because it broke existing code, but for now at least,
enums aren't going to work with toUpper or toLower.

Unfortunately, templated code that deals with strings needs to be _really_
careful about how it deals with enums with a base type of string, because
they pass isSomeString but aren't actually strings (which is great for code
that doesn't use the range API but falls flat on its face for code that does
use the range API). Static arrays and structs which implicitly convert to
strings have the same problem, but at least they don't pass isSomeString.
In general, any type which implicitly converts to another type really needs
to have that coversion forced with generic code that wants the converted
type; otherwise, it's going to have a tendency to fall flat on its face.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list