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

d-bugmail at puremagic.com d-bugmail at puremagic.com
Mon Aug 23 12:54:19 UTC 2021


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

--- Comment #2 from Iain Buclaw <ibuclaw at 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.

--


More information about the Digitalmars-d-bugs mailing list