December 12, 2016
On 12/12/2016 7:21 AM, Mathias Lang wrote:
> The P.R. and bug report are still open. When was it fixed ?

It's ready to go.
December 12, 2016
On Monday, 12 December 2016 at 21:54:38 UTC, Walter Bright wrote:
> On 12/12/2016 7:21 AM, Mathias Lang wrote:
>> The P.R. and bug report are still open. When was it fixed ?
>
> It's ready to go.

Oh, I haven't noticed that you updated it, great!

@Martin: Could you make sure the scope branch is updated to include what's in master once everything gets merged back?
December 13, 2016
On 12/12/2016 1:53 PM, Walter Bright wrote:
> Thanks. Will investigate.

I have it corrected now. Dunno which branch to push it to at the moment, will check with Martin.
December 15, 2016
On Saturday, 10 December 2016 at 05:00:42 UTC, Walter Bright wrote:
>> - what about return ref without scope
>>
>> Does return ref on parameters makes sense without scope?
>
> Yes, see dip25.
>
>> Can you take the address of an unscoped return ref result?
>
> Taking the address of a ref makes it a scope.

Thanks, that was likely the piece of information I was missing.
So even with all the scope changes, a return ref parameter provides the same guarantees, it can't be escaped in a @safe function.
December 15, 2016
On Monday, 12 December 2016 at 07:17:11 UTC, Mathias Lang wrote:
> Not quite: https://issues.dlang.org/show_bug.cgi?id=16037

Thanks for all the test cases, it's really the most useful approach to close all escape holes. How about tracking all scope bugs in Bugzilla using "[scope]" in the title and safe as keyword?

If there are still design-concerns/unclarities about (non-)transitivity, we could benefit from a good test case illustrating the problem.
December 16, 2016
On Thursday, 15 December 2016 at 20:34:28 UTC, Martin Nowak wrote:
>
> Thanks for all the test cases, it's really the most useful approach to close all escape holes. How about tracking all scope bugs in Bugzilla using "[scope]" in the title and safe as keyword?

IMO bugzilla is a more public setup than this NG is - people not familiar with the design of scope, or it's goal, might misinterpret it. I also doubt it would scale to more feature branches. But I have no strong feeling about it so if it fits your workflow better, I'm fine with that.

> If there are still design-concerns/unclarities about (non-)transitivity, we could benefit from a good test case illustrating the problem.

Lack of transitivity is one thing, inability to express something more complex than a top level scope is another.

There is no way to have a scope pointer to a scope pointer to an non scope pointer.
When it comes to scope, you actually want the inverse effect we have for const transitivity: the transitivity should go "up" instead of going "down".

If we borrow C's syntax for `const` for a minute, you could have:
- `scope * scope * int*` => scope ptr to scope ptr to non scope int ptr
- `scope * scope * scope int*` => scope ptr to scope ptr to scope ptr to int
- `      * scope * int*` => non scope ptr to a scope ptr to a non scope int ptr

The first 2 examples are valid as long as each "level" has a lifetime <= to the previous one. What we absolutely want to disallow is the ability to have a pointer to something with `>` lifetime.

With our current grammar, if scope was transitive, you could express the second example by:
`scope int***` or `scope(scope(scope(int*)*)*)`, or any variation.
However, there would be no ability to express the first, valid case.

Obviously we can put a blanket ban on those cases, but to me they sound valid.

Now, a more practical issue, once again related to changing the STC of some variable mid-way through a function semantic analysis:

```
struct Foo { int* ptr; }

void main () @safe
{
    int* a = escape();
}

int* escape () @safe
{
    int i;
    Foo f;
    scope int** x = &f.ptr;
    f.ptr = &i;

    return bar(x);
}

int* bar ( scope int** ptr ) @safe
{
  return *ptr;
}
```

Compiles with `./src/dmd -transition=safe -dip25 test.d` on commit fbbfce8f6e0afb716ec96ba3dc2e82b3536cbaac (with the latest 2 P.R. merged).
December 16, 2016
On Friday, 16 December 2016 at 16:43:30 UTC, Mathias Lang wrote:
>
> Lack of transitivity is one thing, inability to express something more complex than a top level scope is another.

Another, hopefully even better test case for what I'm trying to express:

```
void main () @safe
{
    int* a = escape();
}

int* escape () @safe
{
    int i;
    int*[3] a = [ &i, null, null ];
    return bar(&a[0]);
}

int* bar (scope int** x) @safe
{
    return foo(*x);
}

int* foo (int* x) @safe { return x; }
```

As long as we have:
- No way to express different `scope` levels (the "backward" transitivity)
- A way to take the address of `scope` pointers

We will still have that hole.

> Compiles with `./src/dmd -transition=safe -dip25 test.d` on commit fbbfce8f6e0afb716ec96ba3dc2e82b3536cbaac (with the latest 2 P.R. merged).

December 16, 2016
On 12/16/2016 9:08 AM, Mathias Lang wrote:
> As long as we have:
> - A way to take the address of `scope` pointers

Taking the address of a scope pointer is invalid, I'll fix the method you used to do it.
December 17, 2016
On 12/16/2016 8:43 AM, Mathias Lang wrote:
> ```
> struct Foo { int* ptr; }
>
> void main () @safe
> {
>     int* a = escape();
> }
>
> int* escape () @safe
> {
>     int i;
>     Foo f;
>     scope int** x = &f.ptr;
>     f.ptr = &i;
>
>     return bar(x);
> }
>
> int* bar ( scope int** ptr ) @safe
> {
>   return *ptr;
> }
> ```
>
> Compiles with `./src/dmd -transition=safe -dip25 test.d` on commit
> fbbfce8f6e0afb716ec96ba3dc2e82b3536cbaac (with the latest 2 P.R. merged).

https://github.com/dlang/dmd/pull/6328
December 17, 2016
On 12/16/2016 9:08 AM, Mathias Lang wrote:
> void main () @safe
> {
>     int* a = escape();
> }
>
> int* escape () @safe
> {
>     int i;
>     int*[3] a = [ &i, null, null ];
>     return bar(&a[0]);
> }
>
> int* bar (scope int** x) @safe
> {
>     return foo(*x);
> }
>
> int* foo (int* x) @safe { return x; }

https://github.com/dlang/dmd/pull/6329