Deprecating this(this)
ag0aep6g
anonymous at example.com
Mon Apr 2 14:59:50 UTC 2018
On Monday, 2 April 2018 at 14:24:20 UTC, Nicholas Wilson wrote:
> On Monday, 2 April 2018 at 14:07:21 UTC, Steven Schveighoffer
> wrote:
>> On 4/1/18 10:34 AM, ag0aep6g wrote:
[...]
>>> I'm not so sure if that's fundamental. Can't we just say that
>>> the copy is head-mutable at the time when the postblit
>>> function is called, and it only becomes fully const after
>>> that?
[...]
>> Yes, precisely what I had been arguing here:
>> https://issues.dlang.org/show_bug.cgi?id=18417#c5
[...]
> Andrei did post an example where treating the designation as
> mutable, stuffing references to mutable data into is and then
> treating it as immutable leaves you with an immutable reference
> to immutable data.
This one?
----
int[] sneaky;
struct A
{
private int[] innocent;
this(this)
{
sneaky = innocent;
}
}
void main()
{
immutable a = A([1, 2, 3]);
auto b = a;
sneaky[1] = 42; // oops
import std.stdio;
writeln(a.innocent); // ooooops
}
----
That wouldn't be possible if `innocent` were only head-mutable in
the postblit function, instead of fully mutable as it is
currently (bug).
`innocent` would be typed as `immutable(int)[]`, and you could
not assign it to the fully mutable `sneaky`.
> However i think that loophole is fixed if you only allow
> assignment to const/immutable from a pure postblit.
Still must be head-mutable only. With fully mutable, you can
mutate data that is seen as immutable elsewehre, even if the
postblit function is pure:
----
struct S
{
int* x;
this(this) pure { *x = 13; }
}
void main()
{
auto s = immutable S(new int(42));
auto s2 = s;
assert(*s.x == 42); /* fails; immutability has been broken */
}
----
Issue 18357 covers both Andrei's example, and this one.
https://issues.dlang.org/show_bug.cgi?id=18357
More information about the Digitalmars-d
mailing list