Bug 21460 – implicit conversion between two unrelated enum is accepted

Status
NEW
Severity
enhancement
Priority
P4
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2020-12-08T11:57:29Z
Last change time
2024-12-13T19:13:20Z
Assigned to
No Owner
Creator
basile-z
See also
https://issues.dlang.org/show_bug.cgi?id=6226, https://issues.dlang.org/show_bug.cgi?id=18146
Moved to GitHub: dmd#19836 →

Comments

Comment #0 by b2.temp — 2020-12-08T11:57:29Z
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
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/19836 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB