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