2013/11/10 Timon Gehr <timon.gehr@gmx.ch>
On 11/10/2013 12:07 PM, Kenji Hara wrote:
Condider a case that copying "inout struct" inside inout function.

struct S {
     int[] arr;
     this(this) ??? { }
}
int[] foo(inout S src)
{
     S dst = src; // copy inout S to S
     return dst.arr;
}

If the struct S has postblit, what shold be done for "copying S from
inout to mutable"?

1. You cannot modify elements of arr field, because originally it may be
immutable.
2. You must re-initialize arr field by unique expression, otherwise it
may break type system
...

2. is not necessary in the following case:

inout(int)[] foo(inout S src){
    inout(S) dst = src; // copy inout S to inout S
    return dst.arr;
}

But as far as I understand, there is no other postblit than inout to invoke under the current proposal, hence this could be wasteful.



The requirements are exactly same as what necessary for unique postblit.
Essentially "creating unique copy" is exactly same as "treating the copy
source as inout".

I think it is a good design, but maybe still incomplete.

We could eg. keep

this(this)inout{ ... }

as the unique postblit and have

this(inout this)inout{ ... }

as a postblit for identically qualified source and target.

Hmm.
As a side note, I'm planning unique constructor definition.

struct S {
    // If constructor has one or more inout parameters, it will become inout constructor
    // The constructed object qualifier will be restricted by the argument types.
    this(inout int[] arr) inout { ... }

    // If constructor has no inout parameters, it will become unique constructor
    // The constructed object type can have arbitrary qualifier
    this(int[] arr) inout { ... }
}

So, separating "inout postblit' and 'unique postblit' may be reasonable.

(However, it seems to me that the syntax "this(inout this) inout;" looks weird...

Kenji Hara