On 08.02.20 02:38, ag0aep6g wrote:
Simplified, we're looking at this:

----
struct Joiner
{
     int[3] _items;
     int[] _current;
}
void main() @safe
{
     Joiner j;
     j._current = j._items[];
}
----

I.e., a self-referential struct. Or most fundamentally:

----
struct Joiner
{
     Joiner* p;
}
void main() @safe
{
     Joiner j;
     j.p = &j; /* error */
}
----

`dmd -dip1000` complains about the marked line:

     Error: reference to local variable j assigned to non-scope j.p

What if I mark `j` as `scope`? Then I should be able to assign a reference-to-local to `j.p`. Indeed, the error goes away, but another takes its place:

     Error: cannot take address of scope local j in @safe function main

Right. That can't be allowed, because `scope` gives only one level of protection, and `&j` would need two (one for `j` itself and one for the thing it points at).

I went a bit overboard with that second reduction. The original struct is self-referential, but it's not recursive. The errors are the same for the first reduction. But it's not as clear that they're necessary.

In the first reduction, `j` might be `scope`, but `j._items` has no indirections. `scope` doesn't actually mean anything for it. It's just an `int[3]` on the stack. So taking its address could be allowed.

But (the current implementation of) DIP 1000 is apparently too conservative for that. It seems to treat pointers into a struct the same as pointers to the whole thing.

Reply via email to