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.

Reply via email to