Thread overview
'return this' allows binding rvalues to references
Apr 08, 2013
Ali Çehreli
April 08, 2013
foo() below takes by-ref. Normally, rvalues cannot be passed to it:

struct S
{
    ref S memFunc()
    {
        return this;
    }
}

void foo(ref S s)
{}

void main()
{
    // As expected, fails to compile:
    // foo(S());

    // No problem: Just call a function that returns ref... :)
    foo(S().memFunc());
}

Obviously, it is the same problem for rvalues returned from functions:

    S bar()
    {
        return S();
    }

    foo(bar().memFunc());    // <-- compiles

This may be a trap especially in opAssign() because it is recommended to return by-ref unless there is a reason not to. (I wonder whether this is a reason not to. :) )

struct S
{
    ref S opAssign(S rhs)
    {
        return this;
    }
}

void foo(ref S s)
{}

void main()
{
    // As expected, fails to compile:
    // foo(S());

    // No problem; just assign... :)
    foo(S() = S());
}

Allowing assignment to rvalue feels like a bug there but I don't think we can prevent the programmer from doing S().memFunc() as in the first case.

Ali

P.S. I should have checked before writing this post. The following bugs seem related:

  http://d.puremagic.com/issues/show_bug.cgi?id=1596

  http://d.puremagic.com/issues/show_bug.cgi?id=3008

No, I haven't read them yet.
April 08, 2013
On Mon, 08 Apr 2013 13:58:17 -0400, Ali Çehreli <acehreli@yahoo.com> wrote:

> foo() below takes by-ref. Normally, rvalues cannot be passed to it:
>
> struct S
> {
>      ref S memFunc()
>      {
>          return this;
>      }
> }
>
> void foo(ref S s)
> {}
>
> void main()
> {
>      // As expected, fails to compile:
>      // foo(S());
>
>      // No problem: Just call a function that returns ref... :)
>      foo(S().memFunc());
> }

It has been brought up before.

Essentially, the compiler turns a blind eye when passing rvalues by reference if binding to this. It's kind of unavoidable, to prevent it would be a major pain point, since simple accessors should easily be able to be called on rvalues, and you can't remove the 'ref' of 'this'.

I recall in the past, Andrei wishes to remove that possibility (maybe I'm wrong), but I think it would be too impractical.

-Steve
April 08, 2013
On 4/8/13 2:18 PM, Steven Schveighoffer wrote:
> Essentially, the compiler turns a blind eye when passing rvalues by
> reference if binding to this. It's kind of unavoidable, to prevent it
> would be a major pain point, since simple accessors should easily be
> able to be called on rvalues, and you can't remove the 'ref' of 'this'.
>
> I recall in the past, Andrei wishes to remove that possibility (maybe
> I'm wrong), but I think it would be too impractical.

Yes, that's a major hole. I'm mulling over a technique that fixes the general issue while not breaking much code.

Andrei