[Issue 19399] Different Conversion Rules for Same Value and Type -- Enum

d-bugmail at puremagic.com d-bugmail at puremagic.com
Fri Jun 26 08:30:22 UTC 2020


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

--- Comment #10 from Walter Bright <bugzilla at digitalmars.com> ---
(In reply to Simen Kjaeraas from comment #5)
> I started out thinking this was not a bug, since enum values are basically
> inserted verbatim into the code. And indeed, this is exactly what should
> happen in cases like this:
> 
> int fun(ubyte) { return 0; }
> int fun(ulong) { return 1; }
> 
> enum M = 10;
> // Exactly equivalent to foo(10); - will call the ubyte overload.
> static assert(fun(M) == 0);

Correct, because M is typed as an int and matches with conversion to both
fun(ubyte) and fun(ulong), then partial ordering picks fun(ubyte).


> However, this intuition breaks down when the enum has a specified type:
> 
> enum ulong N = 10;
> // Will always call the ulong overload.
> static assert(fun(N) == 1);

Correct, because here N is typed as a ulong, and so will pick fun(ulong) which
is an exact match, while fun(ubyte) is a match with conversion.


> Both of these cases are working correctly. The error is with enums with
> curly brackets. If no type is specified for the enum, the behavior is
> correct:
> 
> enum O {
>     O = 10
> }
> // Exactly equivalent to foo(10); - will call the ubyte overload.
> static assert(fun(O.O) == 0);

Yes, because O is an enum that converts to both ubyte and ulong, then partial
ordering picks f(ubyte).


> However, when the type is explicitly specified, the error occurs:
> 
> enum P : ulong {
>     P = 10
> }
> // Should call the ulong overload, but type information is discarded and the
> ubyte overload is called instead. This assert will fail.
> static assert(fun(P.P) == 1);

ulong is NOT the type. The type is an enum that is implicitly convertible to
its base type, which is ulong.

The match to both functions is by conversion, which is resolved by partial
ordering, again picking fun(ubyte).

> VRP, as pointed out by Simon in comment 1, is what causes the conversions,
> even in the array examples in comment 4. Simply put, the compiler prefers to
> interpret a number as an int, but will try other types if they are a better
> fit. The only issue is that VRP is used when a type is explicitly specified
> for an enum with braces.

No, this is not what is happening here.

The compiler is working correctly as specified by the language.

--


More information about the Digitalmars-d-bugs mailing list