Thread overview |
---|
March 22, 2006 [Bug 65] New: Strange results overriding interface return with class return | ||||
---|---|---|---|---|
| ||||
http://d.puremagic.com/bugzilla/show_bug.cgi?id=65 Summary: Strange results overriding interface return with class return Product: D Version: 0.150 Platform: PC URL: http://www.digitalmars.com/drn- bin/wwwnews?digitalmars.D.bugs/3287 OS/Version: Windows Status: NEW Keywords: wrong-code Severity: critical Priority: P2 Component: DMD AssignedTo: bugzilla@digitalmars.com ReportedBy: smjg@iname.com The compiler allows a method with an interface return type to be overridden with a class return type. However, when this is done, strange things happen, from AVs to doing things that seem to have no relation to the method that was called. Two similar testcases: ----- covariant_int2.d ----- import std.stdio; interface Father {} class Mother { Father test() { writefln("Called Mother.test!"); return new Child(42); } } class Child : Mother, Father { int data; this(int d) { data = d; } override Child test() { writefln("Called Child.test!"); return new Child(69); } } void main() { Child aChild = new Child(105); Mother childsMum = aChild; Child childsChild = aChild.test(); Child mumsChild = cast(Child) childsMum.test(); } ----- covariant_int4.d ----- import std.stdio; interface Father { void showData(); } class Mother { Father test() { writefln("Called Mother.test!"); return new Child(42); } } class Child : Mother, Father { int data; this(int d) { data = d; } override Child test() { writefln("Called Child.test!"); return new Child(69); } void showData() { writefln(data); } } void main() { Child aChild = new Child(105); Mother childsMum = aChild; aChild.test(); Father mumTest = childsMum.test(); aChild.showData(); mumTest.showData(); } ---------- D:\My Documents\Programming\D\Tests\bugs>covariant_int2 Called Child.test! Called Child.test! Error: Access Violation D:\My Documents\Programming\D\Tests\bugs>covariant_int4 Called Child.test! Called Child.test! 105 Child ---------- I'm guessing that the underlying cause of both is the same - as speculated before http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/2070 interface references aren't compatible with class references. This means that when a method is covariantly overridden from interface to class, and it is then called through the base class, a class reference is returned, which is no good as the base class method, and hence the caller through it, needs an interface reference. The spec doesn't explicitly forbid this, but if it isn't supposed to work then the compiler should be giving an error (and the spec updated accordingly). Otherwise, it could be fixed to work like this: - The compiler would detect that a method is being overridden from Father (interface) to Child (class), and compile Child.test to return an interface reference for compatibility. - When the method is called through a Child reference, the caller would need to implicitly convert the returned Father reference to a Child reference. Of course, this conversion can be optimised away if the context dictates that a Father reference is required. - It would be necessary to throw in a restriction or two. A class cannot derive from both a class and an interface, or multiple interfaces, if they define methods with the same name and parameter types but one has a class return and the other has an interface return. Assuming that it would be impossible to compile the method to be compatible with both simultaneously. I haven't experimented with interface-to-interface covariant overrides, so don't know if these work. But I can imagine there being complications when multiple interface inheritance is involved. The question: Is it worth making this work? Or do these complications mean that we ought to disallow interface-to-class overrides altogether? -- |
March 24, 2006 Re: [Bug 65] New: Strange results overriding interface return with class return | ||||
---|---|---|---|---|
| ||||
Posted in reply to d-bugmail Attachments: | d-bugmail@puremagic.com schrieb am 2006-03-22: > The compiler allows a method with an interface return type to be overridden with a class return type. However, when this is done, strange things happen, from AVs to doing things that seem to have no relation to the method that was called. [snip] Added to DStress as http://dstress.kuehne.cn/run/i/interface_23_A.d http://dstress.kuehne.cn/run/i/interface_23_B.d http://dstress.kuehne.cn/run/i/interface_23_C.d http://dstress.kuehne.cn/run/i/interface_23_D.d Thomas |
April 03, 2006 [Bug 65] Strange results overriding interface return with class return | ||||
---|---|---|---|---|
| ||||
Posted in reply to d-bugmail | http://d.puremagic.com/bugzilla/show_bug.cgi?id=65 deewiant@gmail.com changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |deewiant@gmail.com ------- Comment #2 from deewiant@gmail.com 2006-04-03 14:43 ------- I presume this is related, though not quite the same - the return type is not overridden, only the type of what is returned. If that made any sense. Testcase follows: ------------------ interface I { I[] foo(); uint x(); } class Class : I { I[] foo() { // changing this to I[] f = new Class[1] fixes the bug Class[] f = new Class[1]; f[0] = new Class; return f; } uint x() { return 0; } } void main() { Class c = new Class(); assert (c.x == 0); assert (c.foo[0].x == 0); } ------------------ Note also the array of length 1 - if "new Class" is returned directly, the code generated is fine. -- |
April 04, 2006 [Bug 65] Strange results overriding interface return with class return | ||||
---|---|---|---|---|
| ||||
Posted in reply to d-bugmail | http://d.puremagic.com/bugzilla/show_bug.cgi?id=65 ------- Comment #3 from smjg@iname.com 2006-04-04 06:16 ------- That's about converting between array of class and array of interface, and not to do with return type covariance. So it warrants a separate bug report. -- |
April 04, 2006 [Bug 65] Strange results overriding interface return with class return | ||||
---|---|---|---|---|
| ||||
Posted in reply to d-bugmail | http://d.puremagic.com/bugzilla/show_bug.cgi?id=65 ------- Comment #4 from deewiant@gmail.com 2006-04-04 11:06 ------- (In reply to comment #3) > That's about converting between array of class and array of interface, and not to do with return type covariance. So it warrants a separate bug report. > Bug 85 is now that bug report. -- |
May 09, 2006 [Bug 65] Strange results overriding interface return with class return | ||||
---|---|---|---|---|
| ||||
Posted in reply to d-bugmail | http://d.puremagic.com/bugzilla/show_bug.cgi?id=65 larsivar@igesund.net changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |larsivar@igesund.net ------- Comment #5 from larsivar@igesund.net 2006-05-09 05:03 ------- This bug is listed as fixed in DMD 0.151, could someone verify it? -- |
May 09, 2006 [Bug 65] Strange results overriding interface return with class return | ||||
---|---|---|---|---|
| ||||
Posted in reply to d-bugmail | http://d.puremagic.com/bugzilla/show_bug.cgi?id=65 ------- Comment #6 from smjg@iname.com 2006-05-09 07:18 ------- Testcase interface_23_D still fails. -- |
May 25, 2006 [Bug 65] Strange results overriding interface return with class return | ||||
---|---|---|---|---|
| ||||
Posted in reply to d-bugmail | http://d.puremagic.com/bugzilla/show_bug.cgi?id=65 bugzilla@digitalmars.com changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution| |FIXED ------- Comment #7 from bugzilla@digitalmars.com 2006-05-25 04:17 ------- Fixed 0.158 -- |
Copyright © 1999-2021 by the D Language Foundation