This code compiles but should not
---
enum Good : ubyte { a = 1 }
enum Bad : ubyte { a = 2 }
void main()
{
Good good;
switch (good)
{
case Bad.a : break;
default:
}
}
---
The compilation halts if the base type, `ubyte`, is not specified.
I dont see a specification for that behavior. The only implicit conv rule related to named enums is:
"A named enum member can be implicitly cast to its EnumBaseType, but
EnumBaseType types cannot be implicitly cast to an enum type."
It is not clear if this covers the problem described in this report.
Comment #1 by b2.temp — 2020-12-08T20:20:12Z
This is caused by the automatic integer promotion on the condition.
It is done before evaluation of the cases so it "mind-fuck" the type checks that are correct when no promotion is involved:
---
enum Good { a = 1 }
enum Bad { a = 2 }
void main()
{
Good good;
switch (good) // no promotion
{
case Bad.a : break; // error as expected
default:
}
}
---
VS
---
enum Good : ubyte { a = 1 }
enum Bad : ubyte { a = 2 }
void main()
{
Good good;
switch (good) // by promotion replaced by 'cast(int) good'
{
case Bad.a : break; // OK because convert to int
default:
}
}
---
Comment #2 by b2.temp — 2020-12-08T20:28:38Z
might be fixed by a revival of https://github.com/dlang/dmd/pull/10603.
Not sure, it can be only be related, e.g another side effect of the premature promotion of the condition.
Comment #3 by b2.temp — 2020-12-08T21:23:20Z
The promotion of a switch condition should be done after checking the cases. Then a second pass should be done on the CaseStatement expressions to implicitly cast them to the, eventually promoted, condition. Which should never be a problem.
This is specifically and **definitively** a front-end bug on the SwitchStatement as for example
---
enum Good : ubyte { a = 1 }
enum Bad : ubyte { a = 2 }
void main(string[] args)
{
Good good;
if (good == Bad.a){}
}
---
is rejected. As the cases of a switch should be.
Comment #4 by bugzilla — 2021-07-22T17:24:10Z
It's not a bug. It is working as designed. Changing it would be an enhancement request. Changing the Importance to Enhancement.
Comment #5 by nick — 2023-02-11T09:21:02Z
> Good good;
> switch (good) // by promotion replaced by 'cast(int) good'
Why is an enumeration type promoted to int? Just because it can implicitly convert doesn't mean it should. The fact that the example with the enums that don't have a base type do not promote to int shows this is inconsistent.
Comment #6 by robert.schadek — 2024-12-13T19:13:20Z