D-Programming-Language/dmd — pull request #1726 by 9rnsr (2013-03-07 06:25:29+00:00)
Title: Fix qualified constructor call semantics.

By this change, one of following is required for immutable object construction:

1. immutable constructor
That is described in TDPL.

```d
struct S {
int[] value;
this(int v, int n) immutable { foreach (_; 0 .. n) value ~= v; }
}
void main() {
auto i = immutable S(1, 3); // OK
assert(i.value == [1,1,1]);

auto c = const S(1, 3); // also OK
// because immutable object is implicitly convertible to const

static assert(!__traits(compiles, S(1, 3))); // not allowed
}
```

2. inout constructor
The qualifier of generated object by inout constructor is calculated as if that is returned value from inout function.

```d
struct S {
int[] value;
this(inout int[] arr) inout { value = arr; }
}
void main() {
auto m = S([1,2,3]); // OK
auto c = const S([1,2,3]); // OK
auto i = immutable S([1,2,3].idup); // OK

static assert(!__traits(compiles, immutable S([1,2,3]))); // not allowed
static assert(!__traits(compiles, S([1,2,3].idup))); // not allowed
}
```

3. unique constructor
If a pure constructor can create *unique* object, the generated object can be implicitly convertible to any qualifier.

```d
struct S {
int[] value;
this(inout int[] arr) pure {
value = arr.dup;
}
}
void main() {
auto m = S([1,2,3]); // OK
auto c = const S([1,2,3]); // OK
auto i = immutable S([1,2,3].idup); // OK

auto m2 = S([1,2,3].idup); // also OK
auto i2 = immutable S([1,2,3]); // also OK

auto s = shared S([1,2,3]); // OK!
auto sc = shared S([1,2,3]); // OK!
}
```