This code
import std.stdio;
class A
{
final print() { writeln(this); } // no return type
}
class B : A
{
final void print() { writeln(this); }
}
void main()
{
auto b = new B;
b.print();
A a1 = b;
a1.print();
A a2 = new A;
a2.print();
}
compiles and runs, giving
q.B
q.B
q.A
as output. Putting
pragma(msg, typeof(print));
after the declartion for A.print results in compilation printing
@system void()
q.d(11): Error: function q.B.print cannot override final function q.A.print
whereas putting the same pragma after B.print results in
void()
If A.print is changed to have void, then you get the error and the type that's printed is the same as B.print.
I find it odd that @system void() and void() would any different, since the default is @system - so that may or may not be a bug - but it's definitely a bug that there isn't a compilation error in all cases, since A.print is final and returns the same type as B.print (whether inferrence is involved or not). The fact that whether the pragma is there or not affects whether you get a compilation error is particularly disturbing, but it's a bug regardless.
Comment #1 by kozzi11 — 2017-05-03T08:51:26Z
final print() { writeln(this); }
is a template!!!. So I believe this is the main source of this "bug".
When you add void it makes print normal member function.
final print() { writeln(this); }
is not same as
final void print() { writeln(this); }
It is more like
final void print()() { writeln(this); }
Comment #2 by destructionator — 2017-05-03T12:53:36Z
No, it isn't a template. Try putting `import external.module;` inside. If it is a template, there's no "cannot find module" error unless you actually call it (lazy local imports), but for a function, the error does exist.
final foo() { import...} DOES produce the error. Ditto for `auto ref` parameters, they aren't allowed here either.
Comment #3 by destructionator — 2017-05-03T13:04:17Z
My guess is that func.d's findVtblIndex function fails to find the base class method because `type.equals` and `type.covariant` fail to take into account inference.
Looking at mtype.d, there is
if (!t1n || !t2n) // happens with return type inference
goto Lnotcovariant;
Which I'm guessing isn't right, it should actually analyze the body and fill those types in.
Comment #4 by robert.schadek — 2024-12-13T18:52:08Z