Thread overview
[Issue 21287] Delegate in global template can't call non-anonymous nested function passed as alias
Aug 23, 2021
Iain Buclaw
Aug 23, 2021
Iain Buclaw
Aug 23, 2021
Iain Buclaw
Aug 23, 2021
Dlang Bot
Dec 17, 2022
Iain Buclaw
August 23, 2021
https://issues.dlang.org/show_bug.cgi?id=21287

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ibuclaw@gdcproject.org

--- Comment #1 from Iain Buclaw <ibuclaw@gdcproject.org> ---
1. Lambdas that don't have any non-local access are implicitly typed as function pointers.  So the equivalent nested function would be:

static void fun(Value)(Value _) {}

2. Template function literals are special in that they are implicitly enclosed in their lexical context.  Nested function templates are not enclosed, and so cannot access the surrounding frame when instantiated non-locally.

--
August 23, 2021
https://issues.dlang.org/show_bug.cgi?id=21287

--- Comment #2 from Iain Buclaw <ibuclaw@gdcproject.org> ---
(In reply to Iain Buclaw from comment #1)
> 2. Template function literals are special in that they are implicitly enclosed in their lexical context.  Nested function templates are not enclosed, and so cannot access the surrounding frame when instantiated non-locally.
Saying that, the documentation on this disparity is somewhat lacking.

10.23.10-7 seems to be the only place that vaguely mentions the existence of template function literals:
---
If the function literal is assigned to an alias, the inference of the parameter types is done when the types are needed, as the function literal becomes a template.
---

10.23.10-13 seems says that function literals should be equivalent to their nested function equivalent.  It doesn't say what kind, so the assumption is that this applies to both function literals and template-function literals.
---
Note: When comparing function literals with nested functions, the function form is analogous to static or non-nested functions, and the delegate form is analogous to non-static nested functions. I.e. a delegate literal can access non-static local variables in an enclosing function, a function literal cannot.
---

However, in your example, `fun` is not a nested function, it's a function-template.  Is there really a distinction?  Will have to have a think about it.

https://dlang.org/spec/expression.html#function_literals https://dlang.org/spec/template.html#function-templates


The location in the compiler where the deviation occurs is in `TemplateInstance.hasNestedArgs`.

https://github.com/dlang/dmd/blob/45a07c0a7d24485ef78d3196a029b8d1d8a0cdf7/src/dmd/dtemplate.d#L7290

During the inspection of all instantiation arguments, only only kind of template considered to be a local symbol are template function literals.

Global and static templates are `TemplateDeclaration.isstatic`, so nested templates could be added to this condition with:

if ((td && (td.literal || !td.issstatic)) || ...)

The consequences of opening this particular floodgate is unknown.  It is only anticipated to affect `alias` template-parameters, of which currently nested templates just result in an error.

--
August 23, 2021
https://issues.dlang.org/show_bug.cgi?id=21287

--- Comment #3 from Iain Buclaw <ibuclaw@gdcproject.org> ---
(In reply to Iain Buclaw from comment #2)
> if ((td && (td.literal || !td.issstatic)) || ...)
This change also allows issue 15298 to compile.

--
August 23, 2021
https://issues.dlang.org/show_bug.cgi?id=21287

Dlang Bot <dlang-bot@dlang.rocks> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull

--- Comment #4 from Dlang Bot <dlang-bot@dlang.rocks> ---
@ibuclaw created dlang/dmd pull request #13006 "fix Issue 15298 - Can't call nested template function unless it's anonymous" fixing this issue:

- fix Issue 21287 - Delegate in global template can't call non-anonymous nested function passed as alias

https://github.com/dlang/dmd/pull/13006

--
December 17, 2022
https://issues.dlang.org/show_bug.cgi?id=21287

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P1                          |P3

--
December 13
https://issues.dlang.org/show_bug.cgi?id=21287

--- Comment #5 from dlangBugzillaToGithub <robert.schadek@posteo.de> ---
THIS ISSUE HAS BEEN MOVED TO GITHUB

https://github.com/dlang/dmd/issues/17990

DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB

--