Thread overview
Escape this in pure members
Sep 19, 2020
Per Nordlöw
Sep 19, 2020
Per Nordlöw
Sep 19, 2020
Jacob Carlborg
Sep 19, 2020
Per Nordlöw
Sep 22, 2020
Jacob Carlborg
Sep 23, 2020
DlangUser38
Sep 23, 2020
Per Nordlöw
Sep 23, 2020
ag0aep6g
September 19, 2020
If an aggregate member is pure but not scope when can it escape the `this` pointer?.

Only via return?

In the struct and class case?
September 19, 2020
On Saturday, 19 September 2020 at 16:07:24 UTC, Per Nordlöw wrote:
> If an aggregate member is pure but not scope when can it escape the `this` pointer?.

Or rather when and, if so, how can the member allow its `this` pointer to escape?

It seems to me like the `scope` qualifier is no effect in this case.
September 19, 2020
On 2020-09-19 18:07, Per Nordlöw wrote:
> If an aggregate member is pure but not scope when can it escape the `this` pointer?.
> 
> Only via return?

I'm not sure if returning the `this` pointer is considered escaping it. The caller already had access to it. Under the hood, the `this` pointer is just another argument passed to the function.

> In the struct and class case?

A nested class seems to be able to escape the `this` reference:

class Foo
{
    Bar b;

    class Bar
    {
        void bar() pure
        {
            b = this;
        }
    }
}

-- 
/Jacob Carlborg
September 19, 2020
On Saturday, 19 September 2020 at 18:48:31 UTC, Jacob Carlborg wrote:
> A nested class seems to be able to escape the `this` reference:

Ahh, thanks.

I just realized that it can escape into other parameters without the `scope` qualifier?

This

class Bar
{
    void bar(scope Bar b) @safe pure
    {
        b = this;
    }
}

compiles but this

class Bar
{
    scope void bar(scope Bar b) @safe pure
    {
        b = this; // Error: scope variable `this` assigned to `b` with longer lifetime
    }
}

fails as

foo.d(6,11): Error: scope variable `this` assigned to `b` with longer lifetime
September 22, 2020
On 2020-09-19 21:50, Per Nordlöw wrote:
> On Saturday, 19 September 2020 at 18:48:31 UTC, Jacob Carlborg wrote:
>> A nested class seems to be able to escape the `this` reference:
> 
> Ahh, thanks.
> 
> I just realized that it can escape into other parameters without the `scope` qualifier?
> 
> This
> 
> class Bar
> {
>      void bar(scope Bar b) @safe pure
>      {
>          b = this;
>      }
> }
> 
> compiles but this
> 
> class Bar
> {
>      scope void bar(scope Bar b) @safe pure
>      {
>          b = this; // Error: scope variable `this` assigned to `b` with longer lifetime
>      }
> }

Hmm, why would `b` have longer lifetime? Isn't the lifetime of `b` throughout `bar`?

-- 
/Jacob Carlborg
September 23, 2020
On Tuesday, 22 September 2020 at 18:21:10 UTC, Jacob Carlborg wrote:
> On 2020-09-19 21:50, Per Nordlöw wrote:
>> On Saturday, 19 September 2020 at 18:48:31 UTC, Jacob Carlborg wrote:
>>> A nested class seems to be able to escape the `this` reference:
>> 
>> Ahh, thanks.
>> 
>> I just realized that it can escape into other parameters without the `scope` qualifier?
>> 
>> This
>> 
>> class Bar
>> {
>>      void bar(scope Bar b) @safe pure
>>      {
>>          b = this;
>>      }
>> }
>> 
>> compiles but this
>> 
>> class Bar
>> {
>>      scope void bar(scope Bar b) @safe pure
>>      {
>>          b = this; // Error: scope variable `this` assigned to `b` with longer lifetime
>>      }
>> }
>
> Hmm, why would `b` have longer lifetime? Isn't the lifetime of `b` throughout `bar`?

The following analysis might be wrong but I think that `scope` as a **member** function attribute is not supposed to be used as that is not even documented.

So it would works "by default". The compiler thinks that `this` is a scope variable that will stop living after `bar()`.

Also as `b` is not `ref` this is clearly a wrong diagnostic. There's a special case missing in the compiler.
September 23, 2020
On Wednesday, 23 September 2020 at 00:06:38 UTC, DlangUser38 wrote:
>> Hmm, why would `b` have longer lifetime? Isn't the lifetime of `b` throughout `bar`?
>
> The following analysis might be wrong but I think that `scope` as a **member** function attribute is not supposed to be used as that is not even documented.

Where's the other scope analysis documented?

> So it would works "by default". The compiler thinks that `this` is a scope variable that will stop living after `bar()`.

So are you saying that this code should compile with and without the member being `scope`?

> Also as `b` is not `ref` this is clearly a wrong diagnostic. There's a special case missing in the compiler.
September 23, 2020
On 23.09.20 02:06, DlangUser38 wrote:
> The following analysis might be wrong but I think that `scope` as a **member** function attribute is not supposed to be used as that is not even documented.

It's documented here:
https://dlang.org/spec/memory-safe-d.html#scope-return-params

Quote: "[`scope` and `return`] may appear after the formal parameter list, in which case they apply either to a method's this parameter, or [... irrelevant ...]."

It's less than ideal that the documentation of `scope` is spread over two pages.