D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 8809 - (D1 Only) Cannot statically bind to base class method overridden by derived class
Summary: (D1 Only) Cannot statically bind to base class method overridden by derived c...
Status: RESOLVED WONTFIX
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D1 (retired)
Hardware: All All
: P2 normal
Assignee: No Owner
URL:
Keywords: pull, rejects-valid
Depends on:
Blocks:
 
Reported: 2012-10-12 20:30 UTC by hsteoh
Modified: 2019-10-10 11:54 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description hsteoh 2012-10-12 20:30:12 UTC
class B {
        struct S {
                S delegate() saveImpl;
                S save() { return saveImpl(); }
        }

        S eval() {
                // BUG: B.eval doesn't statically bind to B.eval, but ends up in C.eval, causing stack overflow
                return S(() => B.eval());
                // return S(() => typeof(this).eval()); // this doesn't work either
        }
}

class C : B {
        override S eval() {
                auto s = super.eval();
                auto t = s.save; // stack overflow, 'cos B.eval binds to C.eval

                return t;
        }
}

void main() {
        auto c = new C;
        auto s = c.eval();
}

Basically, there is no way in the base class method to statically bind to the un-overridden method; no matter what is specified (this.eval(), B.eval(), typeof(this).eval(), etc.), it always ends up in C.eval, causing infinite recursion when C.eval calls s.save.

One workaround is to rename B.eval to B.evalImpl, and make B.eval a wrapper that calls B.evalImpl. Then the delegate can be made to call evalImpl directly. But this is quite ugly, since one would have to do this for every base class method that needs to be statically bound in this way. One would expect the language (or compiler) should produce a static binding to B.eval when the code explicitly asks for B.eval.
Comment 1 Kenji Hara 2012-10-14 03:02:36 UTC
https://github.com/D-Programming-Language/dmd/pull/1181

And, this is also a problem in website.
Comment 2 github-bugzilla 2012-10-14 08:31:12 UTC
Commit pushed to master at https://github.com/D-Programming-Language/d-programming-language.org

https://github.com/D-Programming-Language/d-programming-language.org/commit/946692fbad211e84207d41da392a1f60aac9fb65
Add documentation for issue 8809

This language feature has not been clearly documented.
Comment 3 github-bugzilla 2012-10-27 06:10:26 UTC
Commits pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/364bcddf80daf3fcf82237276f0d898cc68d91a2
fix Issue 8809 - Cannot statically bind to base class method overridden by derived class

Collect DotType resolution code to TypeClass::dotExp

obj.Type.foo() calls Type.foo statically.
In the non-static member function, Type.foo() is implicitly translated to this.Type.foo(), and same as well.

https://github.com/D-Programming-Language/dmd/commit/4c11aea5ddd866e1c86d10bdfb4d0acb8469b611
Merge pull request #1181 from 9rnsr/fix8809

Issue 8809 - Cannot statically bind to base class method overridden by derived class
Comment 4 yebblies 2012-10-27 06:18:38 UTC
Fixed D2