January 23

Add a new parameter storage class __rvalue.

  • For extern(C++) functions, mangles like the rvalue reference of the corresponding C++ compiler.
  • Inside the function, it’s like a ref, except that __traits(isRef) returns false on them. Add trait isRvalue to test if a parameter is __rvalue.

It cannot bind lvalues except via __rvalue(lvalue). Any true rvalue, that is, any rvalue that’s not __rvalue(lvalue), is materialized in the caller and referenced, just like it would be for in with big types under -preview=in or for ref under -preview=rvaluerefparam. An __rvalue(lvalue) is bound as if the lvalue were passed to a normal ref.

Example:

void f(__rvalue int x);

void main()
{
    int n;
    f(0); // good
    f(n); // error: `n` cannot be bound to `__rvalue` parameter `x`
    f(__rvalue(n)); // good
}

That would also enable structs’ move constructors to be defined with this(__rvalue typeof(this)).

February 01
C++ identifies move constructors with a special syntax on the constructor. D does move construction by specifying that the argument is an rvalue.

The only purpose I can see for specifying a move constructor in D is to call a C++ move constructor. But do we really need to do that? A constructor that takes an rvalue parameter is already a move constructor, even in C++, it's just that C++ didn't notice that (I presume, as I wasn't privy to those discussions).

Adding a 3rd parameter form adds a terrifying new layer of overload resolution. I already had a terrible time folding in __rvalue arguments to the overloading without breaking existing code.

This proposal would need a really strong motivation for it, as I'm pretty sure we're good to go with our existing move constructors.