D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 3051 - Passing alias to member function does not work (1/2)
Summary: Passing alias to member function does not work (1/2)
Status: RESOLVED DUPLICATE of issue 5710
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: Other Linux
: P2 normal
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-06-04 11:43 UTC by Andrei Alexandrescu
Modified: 2019-06-26 12:57 UTC (History)
5 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Andrei Alexandrescu 2009-06-04 11:43:38 UTC
This is the first of two related bug reports.

class A
{
    A next;
    
    void fun(alias fun)()
    {
        assert(0);
    }
    
    void gun()
    {
        void hun(A a)
        {
        }
        next.fun!(hun)();
    }
}

Error: template instance cannot use local 'hun' as parameter to non-global template fun(alias fun)

This might not work due to an implementation limitation in the current dmd (the "this" pointer and the stack frame pointer compete for the same register), but as the next bug will show, the code doesn't work even if said limitation is worked around.
Comment 1 anonymous4 2009-06-05 05:20:57 UTC
how on earth templates can be parameterized with values unevaluatable at compile time?
Comment 2 Steven Schveighoffer 2009-06-05 06:17:44 UTC
I thought the same as you at first, but I tried this code, and it works:

    void fun(alias fx)()
    {
        fx();
    }

    void main()
    {
        int x = 0;
        void hun()
        {
             x++;
        }
        fun!(hun)();
        writefln("%s", x); // outputs 1
    }

So I think Andrei is right, it is probably a conflict of 2 this pointers required.  The second bug is legit, as it is equivalent to what I wrote here, but I think this one is invalid (need 2 this pointers).
Comment 3 anonymous4 2009-06-05 07:36:54 UTC
huh... &fun is a delegate! Does it take stack pointer with all needed information? Quite hackish, I would say... foreign function messing my stack... ugh...
So it behaves as nested function, but they are said to access this pointer through stack, not register.
Comment 4 Steven Schveighoffer 2009-06-05 08:00:23 UTC
Since the template is instantiated differently for each function that it is called with, it's entirely possible to "know" the stack frame pointer since it will be a constant offset from the current stack pointer.  I think that is why it can work.

In fact, I'm now unsure why that can't work in the other bug too...
Comment 5 Steven Schveighoffer 2009-06-05 08:10:38 UTC
(In reply to comment #4)
> In fact, I'm now unsure why that can't work for both these bugs too...

One other thing about having two "this" pointers, how come this can work (tested with dmd 1.043)?

void foo(delegate void() dg)
{
  dg();
}

class C
{
   int y;
   void fun()
   {
       int x = 0;
       void gun()
       { x++; y++; } // 2 this pointers needed here!
       foo(&gun);
   }
}

So probably there should be no conflict.  And the "this" pointer of the alias'd function in the bug's example should be statically calculatable, so it doesn't need to occupy a register.
Comment 6 anonymous4 2009-06-10 03:30:25 UTC
void foo(delegate void() dg)
{
  dg();
}

class C
{
   int y;
   void fun()
   {
       int x = 0;
       auto me=this;
       void gun()
       { stack.x++; stack.me.y++; }
       foo(&gun); //closure
   }
}
Comment 7 Dicebot 2013-08-02 06:09:54 UTC
So old and so annoying ;)
Comment 8 Dennis 2019-06-26 12:57:00 UTC
It is a bit weird to mark this as a duplicate of an issue filed later, but since 5710 has been marked as fixed this works too now.

*** This issue has been marked as a duplicate of issue 5710 ***