Weird DIP1000 issue
tsbockman
thomas.bockman at gmail.com
Wed Feb 8 22:25:32 UTC 2023
On Wednesday, 8 February 2023 at 13:00:35 UTC, ag0aep6g wrote:
> Here's a further reduction of one aspect of your snippet that
> looks like a bug to me:
>
> ```D
> alias VErr = char*;
>
> ref front_r(ref VErr r) { return r; }
> ref front_p(VErr* p) { return *p; }
> ref front_s(VErr[] s) { return s[0]; }
>
> VErr g;
>
> void main() @safe
> {
> VErr[1] _errors;
> g = _errors[0]; /* copy from static array: ok */
> ```
That's inside the same function, so data flow analysis can see
that no `scope` address has been assigned to any element of
`_errors`.
> ```D
> g = front_r(_errors[0]); /* copy from `ref` via `ref`: ok */
> ```
`ref` is head `scope`, and does not infect the `char*` itself.
> ```D
> g = front_p(&_errors[0]); /* copy from `ref` via pointer:
> fails, should work */
> ```
Since `&_errors[0]` is a pointer to a stack variable, it must be
`scope`. Pointers get transitive `scope`, so the `char*` is
infected, too.
> ```D
> g = front_s(_errors[]); /* copy from `ref` via slice:
> fails, should work */
> ```
Again, the `_errors[]` slice contains a pointer to a stack
variable, so it must be `scope`. Slices get transitive `scope`,
like pointers.
> ```D
> }
> ```
I think most of the confusion surrounding `scope` and related
attributes stems from the fact that `scope` is transitive, when
it really shouldn't be.
Instead, we should be allowed to directly specify for each level
of indirection, and for each aggregate field whether it is always
`scope`, follows the `scope`ness of its parent (as now), or is
never `scope`.
The current design is fundamentally confusing and incoherent,
because the true root of most every chain of indirections is some
offset from the stack pointer, which must be `scope` if its
existence is explicitly acknowledged. Since `scope` is
transitive, this implies that most everything should be `scope`,
which is stupid.
More information about the Digitalmars-d
mailing list