I have no idea whether this is a very specific case. class SomeClass { enum E : short { init } E e1; E foo() const { //E ret = e1 ? E.init : e1; // OK //E e2; //return e2 ? E.init : e2; // OK return e1 ? E.init : e1; // NG } } DMD gives: Error: cannot implicitly convert expression (this.e1 ? 0 : cast(int)this.e1) of type int to E
Because E.init has type E and e1 has type const(E), it misses the t1->equals(t2) condition in CondExp::semantic, and goes to typeMerge, which calls toBaseType on both, giving short, which it then promotes to int. CondExp::semantic and/or typeMerge need to be fixed to prefer const conversion over promotion.
Reduced testcase (the issue has nothing to do with `const` functions): This code should compile: --- enum E { a } void main() { const E ce; auto x = 1 ? ce : E.a; E e = x; // line 7 static assert(is(typeof(x) == const E)); // line 8 } --- main.d(7): Error: cannot implicitly convert expression (x) of type int to E main.d(8): Error: static assert (is(int == const(E))) is false ---