Bug 23835 – Accessing variable outside nested function creates delegate even if it is static

Status
NEW
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2023-04-12T09:16:22Z
Last change time
2024-12-13T19:28:17Z
Assigned to
No Owner
Creator
Richard (Rikki) Andrew Cattermole
See also
https://issues.dlang.org/show_bug.cgi?id=23815
Moved to GitHub: dmd#20259 →

Comments

Comment #0 by alphaglosined — 2023-04-12T09:16:22Z
This will error with: Error: function `onlineapp.main.__lambda2` cannot access variable `builder` in frame of function `D main` Builder.perform is static, which means no context pointer is required for perform to be callable inside a nested function. ```d alias Function = int function(); void main() { Builder builder; Function func = () { return builder.perform(); }; assert(func() == 2); } struct Builder { static int perform() { return 2; } } ``` This should not be creating a delegate. Possibly a duplicate of: https://issues.dlang.org/show_bug.cgi?id=10877
Comment #1 by razvan.nitu1305 — 2023-04-12T12:52:38Z
As a workaround you can just use Builder.perform.
Comment #2 by alphaglosined — 2023-04-12T12:57:48Z
Yeah I went with ``typeof(builder).perform;`` since the real thing is templated non-trivially. Not ideal for example code though (which is what triggered this).
Comment #3 by razvan.nitu1305 — 2023-04-12T13:27:31Z
Looking at the compiler code, it seems that when `builder.perform()` is encountered you have a CallExp that points to a DotIdExp (builder.perform). To analyze it, the compiler first needs to semantically analyze `builder`. Once it does that it also checks whether it is accessed from a nested function and issues the error you are seeing. Between the analysis site of the call exp and the analysis site of `builder` there are multiple calls so at the point where `builder` is analyzed you have no idea whether it comes from a CallExp or a DotIdExp or something else. As such, I think that supporting this case will make the compiler code much uglier (passing a parameter down the call stack or duplicating the code path that analyzes `builder` at at the point of the analysis of the call expression) for a small gain in expressiveness. Since the workaround is very easy, I think that this will most likely be a WONTFIX.
Comment #4 by razvan.nitu1305 — 2023-04-13T10:24:57Z
@Rikki ok to close?
Comment #5 by alphaglosined — 2023-04-13T10:28:55Z
It's still a valid bug, even if it may be a little difficult or not worth the time to solve right now. Bug reports like this shouldn't be closed, because they may be worth it to be fixed later on.
Comment #6 by b2.temp — 2023-04-13T14:48:08Z
I think this is a dup of 23815.
Comment #7 by alphaglosined — 2023-04-13T14:57:54Z
*** Issue 23815 has been marked as a duplicate of this issue. ***
Comment #8 by robert.schadek — 2024-12-13T19:28:17Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/20259 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB