Get parent function of nested delegate

Jonathan M Davis newsgroup.d at jmdavisprog.com
Tue Mar 18 00:28:19 UTC 2025


On Sunday, February 16, 2025 12:38:09 AM MDT Anonymouse via Digitalmars-d-learn wrote:
> I want to get a reference to a parent function from inside a
> nested function. I need it for `getUDAs!(parentFunction,
> attribute)`.
>
> `__traits(parent, mixin(__FUNCTION__))` works inside the parent
> function and gives me the module, but `mixin(__FUNCTION__)` alone
> inside the nested function immediately errors.
>
> ```d
> module foo;
>
> void bar(string s, int i)
> {
>      assert(__FUNCTION__ == "foo.bar");
>      alias parentModule = __traits(parent, mixin(__FUNCTION__));
>      assert(is(parentModule == module));
>
>      void dg()
>      {
>          assert(__FUNCTION__ == "foo.bar.dg");
>          alias parentFunction = __traits(parent,
> mixin(__FUNCTION__));
>      }
> }
>
> void main() {}
> ```
>
> ```
> onlineapp.d(12): Error: function `bar` is not callable using
> argument types `()`
> onlineapp.d(12):        too few arguments, expected 2, got 0
> onlineapp.d(3):        `foo.bar(string s, int i)` declared here
> ```
>
> So `mixin(__FUNCTION__)` seems to be trying to call the parent
> function rather than giving me the symbol of the nested one, like
> `foo.bar().dg`. I tried making it `mixin("&" ~ __FUNCTION__)` but
> it did not help.
>
> How can I make this work?

If I had to guess, the problem is that when you're passing the name of the
function to __traits(parent, ...), it's grabbing that symbol via the normal
lookup rules, meaning that the visibility rules apply, and nested functions
are not visible from outside the function. Now, you're inside the function
in the example, but since you don't normally use the full path for a nested
function when using it, the compiler probably isn't even set up to do so.
I would guess that it was simply never thought of.

Really, what would be ideal here would be something like __FUNCTION_SYMBOL__
which gave the symbol of the function rather than its name as a string,
since that would bypass this whole issue (as well as negate the need to use
a mixin to get the symbol for the function).

However, there is a pretty simple workaround. Just get the symbol from
within the parent function instead of within the nested function, e.g.

    alias parentFunction = mixin(__FUNCTION__);

    void dg()
    {
        // access parentFunction here
    }

It even works if the nested function is static.

- Jonathan M Davis





More information about the Digitalmars-d-learn mailing list