Bug 17800 – [2.076] "static foreach" allocates closures in GC without reason
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2017-09-02T06:49:27Z
Last change time
2017-10-01T20:40:58Z
Keywords
rejects-valid
Assigned to
No Owner
Creator
Илья Ярошенко
Comments
Comment #0 by ilyayaroshenko — 2017-09-02T06:49:27Z
struct S
{
enum N = 1;
}
void foo(S v) @nogc
{
static foreach(_; 0 .. v.N)
{
}
}
----
Error: function mir.ndslice.slice.foo is @nogc yet allocates closures with the GC
source\mir\ndslice\slice.d(290,23):
foo.__lambda2.__lambda1 closes over variable v
Comment #1 by ilyayaroshenko — 2017-09-02T07:05:37Z
struct S
{
enum N = 1;
}
S foo(S v) @nogc
{
static foreach(_; 0 .. typeof(return).N)
{
}
return S.init;
}
----
Error: cannot use typeof(return) inside function __lambda1 with inferred return type
Comment #2 by timon.gehr — 2017-09-04T08:56:35Z
The closure allocation error is not a bug in the `static foreach` implementation. Reduced test case:
---
struct S{
enum N=1;
}
void foo(S v) @nogc{
enum x=()=>v.N;
}
---
Workaround:
---
int foo(S v)@nogc{
enum x=typeof(v).N;
}
---
The second case is due to an oversight on my side.
It can be worked around using an alias:
struct S{
enum N = 1;
}
S foo(S v)@nogc{
alias R=typeof(return);
static foreach(_;0..R.N){ }
return S.init;
}
Comment #3 by timon.gehr — 2017-09-04T09:56:48Z
https://github.com/dlang/dmd/pull/7118
The fix for the second case is at the same time a workaround for the first case. I'll file another bug report for the underlying cause.