Bug 18827 – scope delegate literal allocates GC closure

Status
RESOLVED
Resolution
INVALID
Severity
major
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2018-05-04T14:56:57Z
Last change time
2021-06-02T14:04:28Z
Keywords
industry
Assigned to
No Owner
Creator
Martin Nowak

Comments

Comment #0 by code — 2018-05-04T14:56:57Z
cat > bug.d << CODE int func(int delegate(int) dg) { return dg(2); } int templ(alias dg)() { return dg(2); } void bar() { int a = 3; scope dg = (int x) => x * a; func(dg); // does not allocate closure, GOOD templ!((int x) scope => x * a)(); // does not allocate closure, GOOD func((int x) scope => x * a); // does allocate closure, BAD } CODE Passing a delegate literal with scoped context should never allocate a closure, but it does when the delegate is being passed by value. With DIP1000 escaping of the context within the delegate should be statically forbidden, right now it depends on programming correctness. Still an explicit scope should disable allocations anyhow, though prolly mark the delegates as unsafe.
Comment #1 by dkorpel — 2021-06-02T14:04:28Z
It should allocate a closure, since `func` is free to escape the delegate, e.g.: ``` int delegate(int) global; int func(int delegate(int) dg) { global = dg; return dg(2); } void bar() { int a = 3; scope dg = (int x) => x * a; func(dg); // passing scope dg to non-scope parameter makes bar @system func((int x) scope => x * a); } ``` When marking the input delegate of `func` `scope`, it works: ``` @safe: int func(scope int delegate(int) @safe @nogc dg) @nogc { return dg(2); } void bar() @nogc { int a = 3; scope dg = (int x) => x * a; func(dg); func((int x) scope => x * a); } ```