On 09/26/2016 05:24 PM, Nordlöw wrote:
I just discovered the following interesting fact about the current state
of DMD:
[...]
void top(T)(T a) // TODO infer that `a` is passed as an
r-value?
{
assert(a.copyCount == 0);
sub(a); // so we can do move construction here
aswell?
}
[...]
unittest
{
[...]
top(C());
}
namely that D will infer move semantics of `top`'s parameter when
passing an r-value in the call to `top()` but not transitively in
`top`'s call to `sub` even though this is possible.
The move happens because `C()` is an rvalue. This happens at the call
site. The code generation for `top` is not affected by this. `top`
doesn't know or care if the argument it gets is the result of a copy or
a move.
Inside `top`, `a` is an lvalue. It wouldn't be correct to move `a` just
because it originated from an rvalue.
There may be cases where `sub(a)` could move `a` into position instead
of copying it, but `a` having been moved or copied before is not the
only thing to consider, if it even needs consideration.