Bug 7909 – to!(enum)(string) and to!(string)(enum) break when enum is integral

Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-04-14T07:19:00Z
Last change time
2012-05-22T00:53:53Z
Keywords
pull, rejects-valid
Assigned to
nobody
Creator
destructionator

Comments

Comment #0 by destructionator — 2012-04-14T07:19:59Z
import std.conv; enum Test { a = -1, b = 0, c = 1 } void main() { assert(to!string(Test.a) == "a"); // matches more than one assert(to!Test("b") == Test.b); // does not match anything } First line error: Error: template std.conv.toImpl matches more than one template declaration, src/phobos/std/conv.d(1034):toImpl(T,S) if (!isImplicitlyConvertible!(S,T) && is(S == enum) && isSomeString!(T)) and src/phobos/std/conv.d(1155):toImpl(T,S) if (isIntegral!(S) && isSigned!(S) && isSomeString!(T)) e.d(6): Error: template instance std.conv.to!(string).to!(Test) error instantiating Second line error: src/phobos/std/conv.d(244): Error: template std.conv.toImpl does not match any function template declaration src/phobos/std/conv.d(244): Error: template std.conv.toImpl cannot deduce template function from argument types !(Test)(string) src/phobos/std/conv.d(244): Error: template instance toImpl!(Test) errors instantiating template e.d(7): Error: template instance std.conv.to!(Test).to!(string) error instantiating This worked correctly on dmd 2.058. Note that if you use an enum without assigned values (enum Test {a,b,c}), it still works.
Comment #1 by destructionator — 2012-04-14T07:26:07Z
static assert(isIntegral!(Test)); fails on .58, passes on .59. This is what causes the matches more than one error. Though, interesting to note that: static assert(is(Test : int)); passes on both .58 and 59. It might be some kind of compiler overload resolution change that broke things; isIntegral is implemented with that. The compiler might have changed for correctness (I'm not really sure yet), but the Phobos behavior used to be good and now isn't, so I still call it a phobos regression.
Comment #2 by destructionator — 2012-04-14T07:57:10Z
Well, a simple enough fix for the first one is to tighten up the constraint on toImpl for the isIntegral one. Line 1156 of conv.d, add: !is(S == enum). Doesn't seem to break anything (indeed, if isIntegral used to always return false on enums, it'd just be restoring the previous behavior anyway). Now, for the parsing side. We can do basically the same thing. Line 1708 of conv.d, add: && !is(Target == enum). That takes the isIntegral variety out of consideration, and then it uses the correct enum version. Strange that it didn't say "matches more than one" again, since it is basically the same thing, but meh, whatever, this fixes it and didn't break the other cases I tried.
Comment #3 by k.hara.pg — 2012-04-14T20:45:05Z
https://github.com/D-Programming-Language/phobos/pull/537 (In reply to comment #1) > static assert(isIntegral!(Test)); > fails on .58, passes on .59. This is what causes the matches more than one > error. > > Though, interesting to note that: > static assert(is(Test : int)); > passes on both .58 and 59. > > > It might be some kind of compiler overload resolution change that broke things; > isIntegral is implemented with that. > > The compiler might have changed for correctness (I'm not really sure yet), but > the Phobos behavior used to be good and now isn't, so I still call it a phobos > regression. Yes, this is 2.059 Phobos regression, not compilers. As you mentioned, isIntegral!T should return false if T is enum type.
Comment #4 by github-bugzilla — 2012-05-21T22:34:46Z
Commits pushed to master at https://github.com/D-Programming-Language/phobos https://github.com/D-Programming-Language/phobos/commit/52462bec6ea846f30e8dac309d63ccb4101e8f0c fix Issue 7909 - to!(enum)(string) and to!(string)(enum) break when enum is integral https://github.com/D-Programming-Language/phobos/commit/ac143b63fd435299434478a4ce72317685b80f47 Merge pull request #537 from 9rnsr/fix7909 Issue 7909 - to!enum(string) and to!string(enum) break when enum is integral