Comment #0 by petar.p.kirov — 2016-06-22T18:17:52Z
void main()
{
fun1(2); // Error: mismatched function return type inference
fun2(2); // OK
}
class A {}
class B : A {}
class C : A {}
auto fun1(int a)
{
if (a < 3)
return new B();
else if (a < 5)
return new C();
else
return new A();
}
auto fun2(int a)
{
if (a < 3)
return new A();
else if (a < 5)
return new B();
else
return new C();
}
Comment #1 by hbaelx — 2016-06-22T18:43:51Z
In other words, the compiler apparently extracts info about the return type from the first return statement it comes across, rather than trying to find a common type that matches all of the return statements.
As an obvious workaround, I suggest you avoid using the auto keyword here. The compiler might have some trouble looking for common types, and I doubt this is something that need urgent attention.
Comment #2 by petar.p.kirov — 2016-06-22T20:29:59Z
No, I think this is specific only to class sub-typing. For example the following compiles successfully and prints "4", "3.4" and "99". In other words, it actually finds the common type of all return statements (in this case - double)
void main()
{
import std.stdio;
fun(2).writeln();
fun(4).writeln();
fun(6).writeln();
}
auto fun(int a)
{
if (a < 3)
return 4;
else if (a < 5)
return 3.4;
else
return 'c';
}
I'm not particularly bothered by this deficiency of the compiler, just wanted to report it.
Also note that this deficiency is does not affect type inference of array literals:
void main()
{
import std.stdio;
[1, 'c', 3.4].writeln();
[2.3, 'c', true].writeln();
['c', 2, 3.5].writeln();
[new A(), new B(), new C()].writeln();
[new B(), new A(), new C()].writeln();
[new C(), new B(), new A()].writeln();
}
class A {}
class B : A {}
class C : A {}
Prints:
1, 99, 3.4]
[2.3, 99, 1]
[99, 2, 3.5]
[test.A, test.B, test.C]
[test.B, test.A, test.C]
[test.C, test.B, test.A]
Comment #3 by razvan.nitu1305 — 2023-10-09T12:05:55Z
*** Issue 24178 has been marked as a duplicate of this issue. ***
Comment #4 by robert.schadek — 2024-12-13T18:48:32Z