|Posted by H. S. Teoh|
in reply to Per Nordlöw
Posted in reply to Per Nordlöw
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
> 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:
const(char) x = evil; // x now aliases evil
string y = x; // y is now aliases evil <----
evil = '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
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.
What's a "hot crossed bun"? An angry rabbit.