On Thursday, 14 February 2019 at 23:55:18 UTC, SimonN wrote:
std.typecons.Rebindable!(immutable A) is implemented as:
private union {
immutable(A) original;
A stripped;
}
...@trusted assignment operators...
@property inout(immutable(A)) get() @trusted pure nothrow
@nogc inout
{
return original;
}
alias get this;
This conforms with the D safety spec: All access to the unsafe
union goes through the @trusted get() and the trusted
assignment operators.
Rebindable!(immutable A) r = a1;
// r.original is a1
r = a2;
// r.original is a2
But the compiler may assume that immutable variables -- such as
the immutable(A) original -- never change and thus may optimize
code. Since immutable(A) original is assignable in the union,
such optimization would produce wrong behavior: In the final
line, the compiler could think that r.original is a1 without
examining r.original.
How does Rebindable prevent the compiler from optimizing
according to immutable's rules?
It's easy. You cannot use immutable as the only basis of
optimization.
You need to proof actual immutability via data-flow-analysis over
the whole life-time of your immutable.
When you cannot guarantee actual immutability (within the frame
of interest) don't perform optimizations which are dependent on
it.
So much for the theory, in practice I think that most
optimizations based on immutable are disabled.
Think of immutable as hint for the programmer, not for the
compiler.