Comment #0 by pro.mathias.lang — 2020-06-19T06:13:49Z
```
import std.stdio;
struct Container { int[10] arr; }
void main () @safe
{
auto dg = getDg(42);
stompStack();
dg();
}
auto getDg (int val) @safe
{
Container c;
c.arr[] = val;
return forwardDg(c);
}
auto forwardDg (scope ref Container c) @safe
{
return () => writeln(c);
}
void stompStack () @safe
{
int[256] oops = int.max;
}
```
This should print:
```
Container([42, 42, 42, 42, 42, 42, 42, 42, 42, 42])
```
Instead it prints:
```
Container([2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647])
```
Compiled with `-preview=dip1000`. I would have tried `-preview=dip1021` if it didn't SEGV the compiler.
```
% dmd | head -n 1
DMD64 D Compiler v2.092.1
```
Comment #1 by dkorpel — 2022-01-04T11:52:46Z
Reduced a bit more:
```
@safe:
alias DG = void delegate() @safe;
void main()
{
DG dg = getDg(42);
stompStack();
dg();
}
DG getDg(int val)
{
return forwardDg(val);
}
DG forwardDg(ref int c)
{
return () {assert(c == 42);};
}
void stompStack()
{
int[256] oops = int.max;
}
```
Also, it fails both with or without -dip1000. I think closing over a ref parameter should be an error (at least in `@safe` code), because it's really hard for `forwardDg` to create a closure including the stack frame of `getDg`: it has to be done at runtime, since you can't statically know where the `ref` parameter came from.