Bug 24656 – enums with explicit EnumBaseType incorrectly matching multiple overloads.

Status
NEW
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2024-07-09T19:15:41Z
Last change time
2024-12-13T19:36:22Z
Keywords
rejects-valid
Assigned to
No Owner
Creator
dave287091
Moved to GitHub: dmd#20484 →

Comments

Comment #0 by dave287091 — 2024-07-09T19:15:41Z
The following code fails to compile due to matching multiple overloads, which shouldn’t be correct. ``` import std; void foo(ubyte x){ writeln("foo(ubyte)"); } void foo(byte x){ writeln("foo(byte)"); } enum E: ubyte { A = 0, B = 1, Z = 255, } void main(){ ubyte a = 1; byte b = 2; foo(a); // ok foo(b); // ok foo(E.Z); // ok foo(E.A); // matches both foo(ubyte) and foo(byte) } ```
Comment #1 by dave287091 — 2024-07-09T19:20:35Z
Furthermore, the following additional function values to compile, which is very counter-intuitive as E shouldn’t implicitly convert to byte as its EnumBaseType is ubyte and it has a value outside the range of byte. ``` void indirect(E e){ foo(e); } ```
Comment #2 by dave287091 — 2024-07-09T19:21:11Z
(In reply to dave287091 from comment #1) > Furthermore, the following additional function values to compile, which is “values to compile” -> “fails to compile"
Comment #3 by b2.temp — 2024-07-09T22:23:46Z
This looks invalid to me. Implcit conversions between signed and unsigned allows things like ``` void main(){ byte a; a = ubyte(255); } ``` Problem in the original report is more about signess but signess does not play a role in overload resolution.
Comment #4 by b2.temp — 2024-07-09T22:49:22Z
Also "to which point enum members are strongly-typed ?" is the underlying question. You expect some kind of VRP (or maybe constant folding) but that is not the case.
Comment #5 by dave287091 — 2024-07-09T22:56:38Z
(In reply to basile-z from comment #4) > Also "to which point enum members are strongly-typed ?" is the underlying > question. You expect some kind of VRP (or maybe constant folding) but that > is not the case. I expect that specifying a base type means that enum is converted to that type before any other implicit conversion.
Comment #6 by b2.temp — 2024-07-09T23:37:28Z
(In reply to dave287091 from comment #5) > (In reply to basile-z from comment #4) > > Also "to which point enum members are strongly-typed ?" is the underlying > > question. You expect some kind of VRP (or maybe constant folding) but that > > is not the case. > > I expect that specifying a base type means that enum is converted to that > type before any other implicit conversion. That goes a bit against how subtyping works: ``` class A {} class B : A {} void test(A a){ assert(0, "no the top-most type is tried first"); } void test(B b){} void main(){(new B).test();} ``` That being said, I'll stop to argument there. I'm not a big fan of the overloading principle. The issue you've opened is exactly what it leads to, i.e confusion. Side note: sure in D it's a bit more complex, as overloading participate to pick the right template, based on how constraints are evaluated ;)
Comment #7 by robert.schadek — 2024-12-13T19:36:22Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/20484 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB