Cannot take slice of scope static array in @safe code
Steven Schveighoffer
schveiguy at gmail.com
Sun Feb 2 18:18:28 UTC 2020
On 2/2/20 10:20 AM, ag0aep6g wrote:
> On 02.02.20 14:40, Dennis wrote:
>> Compiling the following with -dip1000 gives an error.
>>
>> ```
>> void main() @safe {
>> string[1] a0;
>> scope int[1] a1;
>> scope string[1] a2;
>>
>> scope string[] b0 = a0[]; // Fine
>> scope int[] b1 = a1[]; // Fine
>> scope string[] b2 = a2[]; // Error: cannot take address of scope
>> local a2
>> }
>> ```
>>
>> Can anyone explain why? I don't see how b2 violates the scope
>> constraint of a2.
>
> To make this easier, let's:
>
> 1) type out `string` as `immutable(char)[]`,
> 2) throw that `immutable` away, because it doesn't matter,
> 3) replace the arrays with pointers.
>
> Then we're looking at this:
>
> void main() @safe
> {
> int* a0;
> scope int** b0 = &a0; /* accepted */
>
> scope int* a2;
> scope int** b2 = &a2; /* rejected */
> }
>
> Now it's important to realize that `scope` only applies to the top-level
> of the type. That means, when you dereference b0 or b2, you get a plain
> `int*` without any `scope` on it.
I think this is wrong. a0 is not a scope array of scope strings, it's a
scope array of strings. string isn't scope, it points to immutable data
that's on the heap or in the static segment (generally).
This is the biggest problem of dip1000 -- there's just no granularity in
scope, it applies to EVERYTHING that is referenced from it.
scope should have been a type constructor.
>
> For b0 that's fine, because a0 isn't `scope` (neither explicit nor
> inferred).
>
> But for b2 it would be a problem, because a2 would lose its `scope`.
> That can't be allowed.
>
>> It might be a compiler bug, but since the int[] case works
>
> With regards to DIP 1000, `string` is very different from `int`.
> `string` has an indirection. `int` doesn't. The analogous type to
> `string[]` is `int[][]`.
How does one declare "I have this array which is scope, because it's
storage is on the stack. But it points at things that are in the GC
heap, so it's cool to reference those without scope."
And if that is a simple matter, what about an array stored on the stack
of arrays stored on the stack, of references to heap data? How do I make
sure the heap pointers are still heap pointers, and not have to cast the
compiler into submission?
I've run into problems like this before, they aren't solvable with
dip1000. And string arrays are usually where it stops working because of
the double indirection.
-Steve
More information about the Digitalmars-d-learn
mailing list