dip1000 and preview in combine to cause extra safety errors
Mathias LANG
pro.mathias.lang at gmail.com
Wed Jun 8 19:59:14 UTC 2022
On Wednesday, 8 June 2022 at 19:02:53 UTC, Steven Schveighoffer
wrote:
>
> But for some reason, this specific code doesn't fail with
> `-preview=dip1000` or `-preview=in`, but only when both are
> specified.
>
> Apparently `in` under preview in doesn't really mean the same
> thing as `scope const`. So does it have nothing to do with
> preview in? simple experimentation says it does.
Well the real bug in this code lies in `scope` + array being
allocated on stack. Cherry picking the instance where it happens
with `-preview=in` is just pointing the finger at a subset of the
problem, which is probably where you first encountered the issue
? You unfortunately are at the weird intersection of a few design
decisions made by a few different people.
Story time:
When DIP1000 was first introduced, there was a lot of discussion
to make sure we have it behind a switch. So `-dip1000` was born.
Later on, we introduced the `-preview` / `-revert` /
`-transition` trifecta as more work was being done on potentially
breaking change features.
Now the decision that Walter made, and that I, honestly, still do
not understand to this day, was to make `in` means simply
`const`. The rationale was that it would "break too much code",
and if I'm not mistaken, that people expected `scope` to do
nothing (exception for delegates / class alloc), but changing the
semantic of `in` would have too much of an impact. The DIP1000
changes being behind a preview switch, IMO, it shouldn't have
been a problem.
Later on, there was a push to get rid of most, if not all, usages
of `in`, especially in druntime C bindings were they were favored.
In parallel, Atila submitted a PR for a new `-preview` switch
which would make `in` have its actual meaning (dear old
`-preview=inMeansConstRef`).
I once again expressed my (unfavorable) opinion on the topic
(https://github.com/dlang/dmd/pull/10769#issuecomment-583229694).
Now, that's where I come in. I implemented `-preview=in` as you
see it today.
But there was ONE constraint I had to keep in, when I did so:
`-preview=in` should also make `in` act as `scope`.
That's how you end up with:
https://github.com/dlang/dmd/blob/7e1b115a0c62c04b74fecfed8a220d5e31cf4fe0/src/dmd/mtype.d#L4397-L4399
Does it make sense ? I don't think so. If it was up to me, `in`
would always means `scope`.
Should we change it now ? If we couldn't do it when `scope` had
*no* effect unless `-dip1000` was used, I don't see how we could
now that `scope` does have an effect even without `-dip1000`.
> Whether it's right or wrong, it's a change that silently
> introduces memory corruption. It ought to produce a warning for
> such code. I'm not blaming anybody here for behavior that is
> probably correct per the spec. But is there no mechanism to be
> had for warning about this? D already doesn't allow returning a
> pointer to stack data, even in `@system` code. Doesn't this
> also qualify?
I have argued with Walter for a long time that having `scope`
enforced only in `@safe` code was a grave mistake, and would be
extremely confusing. It would have avoided this situation.
More information about the Digitalmars-d
mailing list