4647 – [tdpl] Cannot explicitly call final interface method, ambiguous calls allowed

D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 4647 - [tdpl] Cannot explicitly call final interface method, ambiguous calls allowed
Summary: [tdpl] Cannot explicitly call final interface method, ambiguous calls allowed
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: Other All
: P2 major
Assignee: No Owner
URL:
Keywords: diagnostic, patch, rejects-valid
: 3759 6680 (view as issue list)
Depends on:
Blocks:
Reported: 2010年08月15日 10:32 UTC by Andrej Mitrovic
Modified: 2012年01月30日 18:34 UTC (History)
5 users (show)

See Also:


Attachments
Add an attachment (proposed patch, testcase, etc.)

Note You need to log in before you can comment on or make changes to this issue.
Description Andrej Mitrovic 2010年08月15日 10:32:38 UTC
Code on 2.048:
import std.stdio;
interface Timer
{
 final void run() { writeln("Timer.run()"); };
}
interface Application
{
 final void run() { writeln("Application.run()"); };
}
class TimedApp : Timer, Application
{
}
import std.stdio;
void main()
{
 auto app = new TimedApp;
 app.Timer.run(); // error, no Timer property
 app.Application.run(); // error, no Application property
 app.run(); // This would call Timer.run() if the two calls
 // above were commented out
}
The comments state what happens.
Note that if I changed the order of the TimedApp signature like so:
class TimedApp : Application, Timer
then the Application's run() method would be called instead of Timer's in the app.run() call.
Comment 1 Andrej Mitrovic 2010年08月15日 12:04:34 UTC
Comment from Lukasz Wrzosek
>This:
> app.Timer.run(); // error, no Timer property
> app.Application.run(); // error, no Application property
>
>probably should be:
> (cast(Timer)app).run();
> (cast(Application)app).run();
>
>But app.run() is still ambiguous - should not compile.
I don't see why I would need a cast. I can explicitly call methods from inherited classes, like so:
import std.stdio;
class Base
{
 void test() { writeln("Base.test()"); };
}
class Derived : Base
{
 override void test() { writeln("Derived.test()");}
}
class SecondDerived : Derived
{
}
void main()
{
 auto var = new SecondDerived;
 var.Base.test(); // calls Base.test()
 var.Derived.test(); // calls Derived.test()
}
So why shouldn't I be able to do the same with interfaces? TDPL allows it, I think it should be allowed in DMD.
Comment 2 Lars T. Kyllingstad 2010年08月16日 00:05:38 UTC
I don't have TDPL in front of me right now, but I, too, seem to remember that this should be allowed. Raising the priority of this.
Comment 3 Kasumi Hanazuki 2011年10月25日 12:38:15 UTC
*** Issue 6680 has been marked as a duplicate of this issue. ***
Comment 4 Kenji Hara 2011年12月24日 02:18:52 UTC
Patch for app.Timer.run() / app.Application.run():
https://github.com/D-Programming-Language/dmd/pull/578
----
(In reply to comment #0)
> Note that if I changed the order of the TimedApp signature like so:
> 
> class TimedApp : Application, Timer
> 
> then the Application's run() method would be called instead of Timer's in the
> app.run() call.
I think the behavior is correct, because name lookup is depth-first.
Then app.run() depends on the order of derived bases.
Comment 6 yebblies 2012年01月30日 18:34:12 UTC
*** Issue 3759 has been marked as a duplicate of this issue. ***


AltStyle によって変換されたページ (->オリジナル) /