On Thursday, 16 March 2017 at 17:20:10 UTC, Carl Sturtivant wrote:
OK, but if I try to do this,

char[2] u;
string s = u;

Yeah, that's because `u` is not necessarily unique like a function return value:

char[2] u;
char[] mutable = u[];
string s = u[];

char before = s[0];

mutable[0] = 'n';

char after = s[0];

assert(before == after); // fails! because mutable[0] changed it.



But, with a function return value, there's no opportunity to insert that sneaky `char[] mutable = u[];` alias, so the compiler is free to assume that it is the only reference and do the immutable thing.

If it returns a value type, the compiler can cast to immutable at any time because it knows there is no chance to insert an alias at all - the function return is the only way to access it.

If it returns a reference type, the compiler can cast to immutable if the function is *strongly* pure, because the purity rules also don't give you an opportunity to sneak a mutable reference out (pure cannot write to stuff outside the return values).

I said *strongly* because the compiler will correctly complain if you try to pass a mutable argument back as the return value. It realizes whomever passed the argument might still have an alias and will not allow the implicit cast:

pure char[] foo(char[] a) { return a; }
char[] lolStillMutable;
string tricky = foo(lolStillMutable); // illegal


Reply via email to