On 8/22/2018 3:52 AM, Atila Neves wrote:
On Wednesday, 22 August 2018 at 09:05:13 UTC, Walter Bright wrote:
On 8/21/2018 8:58 PM, Nicholas Wilson wrote:
On Tuesday, 21 August 2018 at 14:31:02 UTC, Atila Neves wrote:
The problem is that the code we write doesn't deal directly with pointers -
see the recent confusion in this forum over where `scope` on the left
applies to the `this` pointer or the one returned by the member function.
Kagamin just told me I needed to use `return` instead of `scope` to get
things to work and I'm still not sure why.
The way I think about it is if you have a function that takes a pointer, any
pointer, and either returns it or a pointer derived from it (dereferencing or
indexing) that argument must be marked `return`. In your case it was a
pointer derived from `this` so `return` must be applied to `this`.
Another way to think about it is this:
S s;
return &s;
We all know that is an error. The idea is to have a way to express that for:
S s;
return s.foo();
and:
S s;
return foo(&s);
so that the compiler knows that the return value of foo() is attached to the
lifetime of s. Pretty much everything flows from that.
Would the guideline below be correct?
"Add scope to every non-template member function that isn't meant to escape this
and add return to every non-template member function that returns all or part of
`this` by pointer or ref if you want the compiler to check that nothing gets
escaped in @safe code."
Being a template doesn't make any difference, except that it will helpfully
infer these things.
Also, since 'this' is passed by 'ref' to struct member functions, it cannot
escape anyway with dip1000:
struct S {
int x;
@safe ref int foo() { return x; }
}
dmd test -dip1000
test.d(4): Error: returning this.x escapes a reference to parameter this,
perhaps annotate with return
`scope` is for pointers, `ref` does not need further annotation.