On 04/02/2018 12:53 PM, Steven Schveighoffer wrote:
On 4/2/18 11:57 AM, Andrei Alexandrescu wrote:
On 04/02/2018 10:59 AM, ag0aep6g wrote:

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`.

Problem is we don't have head-mutable in the language.

This is the wrong way to look at it. Head mutable is a specialized concept already implemented in constructors:

struct S
{
    int x;
    int *ptr;
    int *ptr2;
    this(int xval, immutable int *ptrval, int *cantuse) immutable
    {
       x = xval; // ok, head mutable
       //x = x + 1; // error, immutable field initialized multiple times
       ptr = ptrval; // ok
       // ptr2 = cantuse; // error, can't assign mutable to immutable
    }
}

I've asked Razvan to document how immutable constructors are exactly typechecked. My understanding is that they don't rely on some form of internal "head const" but instead on simple data flow - the first assignment counts as a constructor call. Consider the following example, which contains opaque methods instead of built-ins:

struct S
{
    int[] payload;
    S* another;
    this(int) immutable;
}

struct HasS
{
    S member;
    this(int  x) immutable
    {
        member = immutable S(1);
    }
}

This fails to link; the assignment is just a call to the (declared but undefined) constructor.

Such behavior is nice and easy to generalize to copy construction.

We could have the same mechanism for postblit. Essentially, you should be able to assign immutable fields once, but they shouldn't lose their const protections (note the cantuse example).

Yes, with the distinction that is not "assign" but really "construction with assignment syntax".

As was mentioned, because postblit on an immutable (or const) is ONLY allowed for new data, there shouldn't be an issue.

The problem with postblit is there's "double construction", one done by the compiler, after which the user may want to assign something else. That's more difficult to typecheck than direct initialization.


Andrei

Reply via email to