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