Implicit conversion of concatenation result to immutable

H. S. Teoh hsteoh at quickfur.ath.cx
Thu Apr 1 21:59:21 UTC 2021


On Thu, Apr 01, 2021 at 09:21:02PM +0000, Per Nordlöw via Digitalmars-d wrote:
> Can somebody explain the logic behind the compiler disallowing both line 3
> and 4 in
> 
> ```d
> const(char)[] x;
> string y;
> string z1 = x ~ y; // errors
> string z2 = y ~ x; // errors
> ```
> 
> erroring as
> 
> ```
> Error: cannot implicitly convert expression `x ~ cast(const(char)[])y` of
> type `char[]` to `string`
> Error: cannot implicitly convert expression `cast(const(char)[])y ~ x` of
> type `char[]` to `string
> ````

It is illegal to implicitly convert const to immutable, because there
may be a mutable alias to the data somewhere. If so, it will violate
immutability. For example:

	char[] evil;
	const(char)[] x = evil;	// x now aliases evil
	string y = x;		// y is now aliases evil <----
	evil[0] = 'a';		// Oops, immutability violated

The implicit conversion on the line marked `<----` is the cause of the
problem.

Now, when you append a string to a const(char)[], the compiler has to
promote `string` to `const(char)[]` first, so that the operands of ~
have the same type. And obviously, the result of concatenating two
const(char)[] must be const(char)[], since you don't know if one of them
may have mutable aliases somewhere else.  So the result must likewise be
const(char)[].

One may argue that appending in general will reallocate, and once
reallocated it will be unique, and there safe to implicitly convert to
immutable.  However, in general we cannot guarantee this, e.g., one of
the strings could be empty and not reallocate at runtime, so it may
continue to be aliased by some mutable reference somewhere else. So the
result must be typed as const(char)[], along with the restriction that
it cannot implicitly convert to immutable.


[...]
> This problem regularly crops up for me during assembling of strings
> passed as a string parameter for instance an exception constructor.

Just use .idup on the result.


T

-- 
What's a "hot crossed bun"? An angry rabbit.


More information about the Digitalmars-d mailing list