digitalmars.D.bugs - [Issue 15591] New: order of base interface list affects semantics
- via Digitalmars-d-bugs (97/97) Jan 22 2016 https://issues.dlang.org/show_bug.cgi?id=15591
https://issues.dlang.org/show_bug.cgi?id=15591 Issue ID: 15591 Summary: order of base interface list affects semantics Product: D Version: D2 Hardware: x86_64 OS: Windows Status: NEW Severity: normal Priority: P1 Component: dmd Assignee: nobody puremagic.com Reporter: r.97all gmail.com In the code below, interface P inherits three interfaces BP, AP, NP. The order of these interfaces changes the program behavior. Which is, or should be, the correct one? * compilation error * infinite recursion * my expectation import std.stdio; void main() { BP c = new C(new CAP, new CNP); c.p(new A); // expected: output "a" c.p(new N); // expected: output "n" } /// A base class and two derived classes. abstract class B { abstract void a(P p); } /// ditto class A : B { override void a(P p) { /* Since typeof (this) is A here, the programmer expects the better match p.AP.p to be called. */ p.p(this); } } /// ditto class N : B { override void a(P p) { /* Since typeof (this) is N here, the programmer expects the better match p.NP.p to be called. */ p.p(this); } } /// interfaces which can process a data of B, A and N. interface BP{void p(B);} /// ditto interface AP{void p(A);} /// ditto interface NP{void p(N);} /// trivial implementations fon AP and NP. class CAP : AP{void p(A a){"a".writeln;}} /// ditto class CNP : NP{void p(N n){"n".writeln;}} /** The order of interfaces does matter, is this intended behavior? Case: `P : AP, BP, NP` does not compile with Error: function AP.p(A) is not callable using argument types (N). Case: `P : BP, AP, NP` does compile, but to infinite recursion: A.a(P) and N.a(P) calls NP.p(B). */ interface P : BP, AP, NP {} /// Implement AP and NP by delegation, and BP by calling the method a. class C : P { this (AP ap, NP np) { this.ap = ap; this.np = np; } void p(B b) { b.a(this); // forwards to either A.a or N.a, since B.a is abstract. } AP ap; void p(A a) { ap.p(a); } NP np; void p(N n) { np.p(n); } } --
Jan 22 2016