January 19, 2017
A compilation of


struct T
{
    int x;

    @disable this(this); // this has no effect on the issue

    ref inout(T) memberFun() inout
    {
        pragma(msg, "memberFun:", __traits(isRef, this) ? "ref" : "non-ref", " this");
        return this;
    }
}

void freeFun()(auto ref const T x)
{
    pragma(msg, "freeFun:", __traits(isRef, x) ? "ref" : "non-ref", " this");
}

unittest
{
    T t;

    freeFun(t); // `param` passed by reference
    freeFun(T.init); // `param` passed by move

    t.memberFun(); // `this` passed by what?
    T.init.memberFun(); // `this` passed by what?
}


currently prints


memberFun:non-ref this
freeFun:ref this
freeFun:non-ref this


That is, we cannot distinguish an l-value-call to `memberFun` from an r-value-call. Opposite to what we can when combining `auto ref`-parameters with `__traits(isRef)` as shown with function `freeFun` in the code example above.

Disabling the postblit has no effect on the issue.

I need this for enabling efficient delayed evaluation for unary and binary arithmetic operators in my GNU MP wrapper described earlier at

http://forum.dlang.org/thread/plqysfanwuoiuslfywyx@forum.dlang.org

Any clues on how to retrieve this information?
January 19, 2017
On Thursday, 19 January 2017 at 00:44:51 UTC, Nordlöw wrote:
> Any clues on how to retrieve this information?

Another much more common use case:

Chained property setters could be optimized iff the property setter is called on an r-value, that is when

    `__traits(isRef,this)` is `false`

Typically usages such as

    f(S.init.setX(2).setY(3))

and

    auto s = S.init.setX(2).setY(3)

should all result in only *one* single construction of `S` (in the `S.init` expression).