Thread overview
std.conv: conversion from ulong to enum
Aug 22, 2013
Matej Nanut
Aug 22, 2013
Andrej Mitrovic
Aug 23, 2013
H. S. Teoh
Aug 23, 2013
Andrej Mitrovic
Aug 23, 2013
Andrej Mitrovic
Aug 23, 2013
H. S. Teoh
Aug 23, 2013
H. S. Teoh
Aug 23, 2013
Matej Nanut
August 22, 2013
Hi everyone,

I hope I'm not misunderstanding the spec when this won't compile:

---
import std.conv;
enum Test { a = 0 }
void main() {
    ulong l = 0;
    auto t = l.to!Test;
}
---

It doesn't compile due to the template not instantiating.

If l is an int, uint or byte, it compiles fine.  I'm assuming the fault lies in the ‘is(S : OriginalType!T)’ constraint.

So, um, is this intended behaviour?  And why are string enums not supported? Wouldn't the ‘==’ operator work just fine on them too (so the function body would stay the same)?

Thanks,
Matej
August 22, 2013
On 8/23/13, Matej Nanut <matejnanut@gmail.com> wrote:
> It doesn't compile due to the template not instantiating.

It's likely a bug just like in Issue 6893[1], where this won't compile:

-----
import std.stdio;

enum E3 : ulong { A, B, C };

void main() {
    writeln(E3.C);
}
-----

[1] : http://d.puremagic.com/issues/show_bug.cgi?id=6893
August 23, 2013
On 8/22/13 3:48 PM, Matej Nanut wrote:
> Hi everyone,
>
> I hope I'm not misunderstanding the spec when this won't compile:
>
> ---
> import std.conv;
> enum Test { a = 0 }
> void main() {
>      ulong l = 0;
>      auto t = l.to!Test;
> }
> ---
>
> It doesn't compile due to the template not instantiating.
>
> If l is an int, uint or byte, it compiles fine.  I'm assuming the fault
> lies in the ‘is(S : OriginalType!T)’ constraint.
>
> So, um, is this intended behaviour?  And why are string enums not
> supported? Wouldn't the ‘==’ operator work just fine on them too (so the
> function body would stay the same)?
>
> Thanks,
> Matej

Hrm, that's a bug. Could you please submit to d.puremagic.com/issues?

Thanks,

Andrei
August 23, 2013
On 8/22/13 5:00 PM, Andrei Alexandrescu wrote:
> On 8/22/13 3:48 PM, Matej Nanut wrote:
>> Hi everyone,
>>
>> I hope I'm not misunderstanding the spec when this won't compile:
>>
>> ---
>> import std.conv;
>> enum Test { a = 0 }
>> void main() {
>>      ulong l = 0;
>>      auto t = l.to!Test;
>> }
>> ---
>>
>> It doesn't compile due to the template not instantiating.
>>
>> If l is an int, uint or byte, it compiles fine.  I'm assuming the fault
>> lies in the ‘is(S : OriginalType!T)’ constraint.
>>
>> So, um, is this intended behaviour?  And why are string enums not
>> supported? Wouldn't the ‘==’ operator work just fine on them too (so the
>> function body would stay the same)?
>>
>> Thanks,
>> Matej
>
> Hrm, that's a bug. Could you please submit to d.puremagic.com/issues?
>
> Thanks,
>
> Andrei

Never mind, I see we track it already.

Andrei
August 23, 2013
On Thu, Aug 22, 2013 at 05:00:38PM -0700, Andrei Alexandrescu wrote:
> On 8/22/13 5:00 PM, Andrei Alexandrescu wrote:
> >On 8/22/13 3:48 PM, Matej Nanut wrote:
> >>Hi everyone,
> >>
> >>I hope I'm not misunderstanding the spec when this won't compile:
> >>
> >>---
> >>import std.conv;
> >>enum Test { a = 0 }
> >>void main() {
> >>     ulong l = 0;
> >>     auto t = l.to!Test;
> >>}
> >>---
> >>
> >>It doesn't compile due to the template not instantiating.
> >>
> >>If l is an int, uint or byte, it compiles fine.  I'm assuming the fault lies in the ‘is(S : OriginalType!T)’ constraint.
> >>
> >>So, um, is this intended behaviour?  And why are string enums not supported? Wouldn't the ‘==’ operator work just fine on them too (so the function body would stay the same)?
> >>
> >>Thanks,
> >>Matej
> >
> >Hrm, that's a bug. Could you please submit to d.puremagic.com/issues?
> >
> >Thanks,
> >
> >Andrei
> 
> Never mind, I see we track it already.
[...]

Actually, I just fixed issue 6893:

	https://github.com/D-Programming-Language/phobos/pull/1504

but the OP's code still doesn't work. This modified version does, though:

	import std.conv;
	enum Test : ulong { a = 0 }
	void main() {
		ulong l = 0;
		auto t = l.to!Test;
	}

The reason is that ulong doesn't implicitly convert to int, which is the default base type of enum. Whether to() *should* attempt the conversion is a different matter, though. I think we should still file a separate bug for this (issue 6893 is a similar bug with the same ulong > int conversion issue, but the fix doesn't address this particular problem).


T

-- 
Computers are like a jungle: they have monitor lizards, rams, mice, c-moss, binary trees... and bugs.
August 23, 2013
On 8/23/13, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
> to!() is used for save conversions

I meant safe.
August 23, 2013
On 8/23/13, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote:
> Whether to() *should* attempt the conversion
> is a different matter, though.

to!() is used for save conversions, so it should try to convert and throw an exception if conversion fails. For example:

byte x = to!byte(int.max);

std.conv.ConvOverflowException@conv.d(1335): Conversion positive overflow
August 23, 2013
On Fri, Aug 23, 2013 at 03:37:11AM +0200, Andrej Mitrovic wrote:
> On 8/23/13, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote:
> > Whether to() *should* attempt the conversion
> > is a different matter, though.
> 
> to!() is used for save conversions, so it should try to convert and throw an exception if conversion fails. For example:
> 
> byte x = to!byte(int.max);
> 
> std.conv.ConvOverflowException@conv.d(1335): Conversion positive overflow

Alright, opened a new bug for this:

	http://d.puremagic.com/issues/show_bug.cgi?id=10874


T

-- 
It is the quality rather than the quantity that matters. -- Lucius Annaeus Seneca
August 23, 2013
On Thu, Aug 22, 2013 at 06:54:45PM -0700, H. S. Teoh wrote:
> On Fri, Aug 23, 2013 at 03:37:11AM +0200, Andrej Mitrovic wrote:
> > On 8/23/13, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote:
> > > Whether to() *should* attempt the conversion
> > > is a different matter, though.
> > 
> > to!() is used for save conversions, so it should try to convert and throw an exception if conversion fails. For example:
> > 
> > byte x = to!byte(int.max);
> > 
> > std.conv.ConvOverflowException@conv.d(1335): Conversion positive overflow
> 
> Alright, opened a new bug for this:
> 
> 	http://d.puremagic.com/issues/show_bug.cgi?id=10874
[...]

And now it's fixed:

	https://github.com/D-Programming-Language/phobos/pull/1505

Turned out to be another signature constraint wrong-assumption bug.

Makes me wonder how many more such bugs lurk in Phobos. This isn't the first time I've seen the signature constraints test for something, then the code uses something else that doesn't necessarily follow from the signature constraints. This is an especially inviting trap to fall into when you have nice syntactic sugar like isIntegral or is(A : B); you start reasoning in the abstract and overlook the concrete details, like ulong not being implicitly convertible to int.


T

-- 
The best compiler is between your ears. -- Michael Abrash
August 23, 2013
Well, that was fast! I'm glad it's fixed. :)