December 22, 2018
Fun times:

---------------
void main() {
    Foo foo;
    takesRef(foo.create.i);  // oops
}

struct Foo {
    int i;
    Foo create() {
        return Foo();
    }
}

void takesRef(ref int x) { }
---------------

Even more fun with auto ref:

https://issues.dlang.org/show_bug.cgi?id=19507


December 22, 2018
On Saturday, 22 December 2018 at 16:26:31 UTC, Atila Neves wrote:
> Fun times:
>
> ---------------
> void main() {
>     Foo foo;
>     takesRef(foo.create.i);  // oops
> }
>
> struct Foo {
>     int i;
>     Foo create() {
>         return Foo();
>     }
> }
>
> void takesRef(ref int x) { }
> ---------------
>
> Even more fun with auto ref:
>
> https://issues.dlang.org/show_bug.cgi?id=19507

Per https://p0nce.github.io/d-idioms/

mixin template RvalueRef()
{
    alias T = typeof(this); // typeof(this) get us the type we're in
    static assert (is(T == struct));

    @nogc @safe
    ref T byRef() pure nothrow return
    {
        return this;
    }
}

struct A {

   mixin RvalueRef;
}


void foo( ref A a );

foo( A().byRef ); // ok

The whole argument against 1016 is that if it were implemented you couldn't distinguish between rvalues and lvalues. But that is already the case, same with your example.

This code just adds a unneeded bloat, including the extra mixin for boilerplate code:

    void foo( ref Vector2 );

    foo( (a + b * c).byRef );

Why can't we just do:

    foo( a + b * c );