July 31, 2019
On 7/19/2019 9:39 AM, Timon Gehr wrote:
> @safe:
> class C{
>      Array a;
>      this(Array a){ this.a=move(a); }
> }
> 
> void maybe_bad(C c, ref int i){
>      c.a = Array();
>      i++;
> }
> 
> void main(){
>      auto c=new C(Array());
>      c.a.append(5);
>      auto d=c;
>      maybe_bad(c,d.a.get());
> }

If Array was ref-counted, then it will be safe. The problem with ref-counted objects, as you pointed out years ago, is this:

    maybe_bad(c,c.a.get());

Copying c to d will increase the ref count and so it will be safe.

Without this DIP, ref-counted objects can't be safe. With it, they can.
July 31, 2019
On Wednesday, 31 July 2019 at 09:25:26 UTC, Walter Bright wrote:
> On 7/19/2019 9:39 AM, Timon Gehr wrote:
>> @safe:
>> class C{
>>      Array a;
>>      this(Array a){ this.a=move(a); }
>> }
>> 
>> void maybe_bad(C c, ref int i){
>>      c.a = Array();
>>      i++;
>> }
>> 
>> void main(){
>>      auto c=new C(Array());
>>      c.a.append(5);
>>      auto d=c;
>>      maybe_bad(c,d.a.get());
>> }
>
> Copying c to d will increase the ref count and so it will be safe.

You misread the above example.

c is an instance of a class holding an Array, not an instance of an Array. So copying c to d doesn't involve calling Array's copy constructor.
August 01, 2019
On Wednesday, 31 July 2019 at 09:25:26 UTC, Walter Bright wrote:
> Copying c to d will increase the ref count and so it will be safe.

As Olivier said, c and d are just class references to the same class instance, so there is only one instance of Array, a ref count would still be 1.

This problem can also happen with slices, here's a simplified struct that shows the problem and disables the struct postblit:

struct S
{
    private byte* data;
    import core.stdc.stdlib;
    @nogc:

    this(byte b) @trusted
    {
        data = cast(byte*)malloc(1);
        *data = b;
    }
    @disable this(this);

    ref byte get() @trusted return
    {
        return *data;
    }

    ~this() @trusted
    {
        if (data) free(data);
    }
}

@safe:

void maybe_bad(ref S s, ref byte i)
{
    s = S(); // frees s.data
    i++;
}

void main()
{
    auto s = S(5);
    // DIP error: Can't pass multiple mutable references owned by `s`
    maybe_bad(s, s.get());
    //auto t = s; // S is not copyable

    auto c = new C;
    c.s = S(4);
    auto d = c;
    // not detected by DIP
    maybe_bad(c.s, d.s.get());

    auto a = [S(3)];
    auto b = a;
    // not detected by DIP
    maybe_bad(a[0], b[0].get());
}

class C
{
    S s;
}

August 02, 2019
On 7/15/2019 8:55 AM, Paul Backus wrote:
> On Monday, 15 July 2019 at 15:23:32 UTC, Mike Parker wrote:
>> This is the feedback thread for the first round of Community Review for DIP 1021, "Argument Ownership and Function Calls":
>>
>> https://github.com/dlang/DIPs/blob/793f83911fdc8c88c6ef34e6a36b5e11e3e574e5/DIPs/DIP1021.md 
>>
> 
> Do these new checks also handle the case where one of the references is passed implicitly to a delegate or nested function via their context?

Yes. Access to such variables is treated "as if" they were passed by reference as arguments to the function. Of course, in reality they actually are passed by ref!


> In other words, if we re-write the example from the DIP to use a nested function, like so:
> 
> struct S {
>      byte* ptr;
>      ref byte get() { return *ptr; }
> }
> 
> void test() {
>      S s;
>      s.ptr = cast(byte*) malloc(1);
> 
>      void foo(ref byte b) {
>          free(s.ptr);
>          b = 4;
>      }
> 
>      foo(s.ptr);
> }
> 
> Will the call to `foo` here be correctly flagged as taking multiple mutable references to `s`?

Yes, the parameter list will be treated as:

    void foo(ref byte b, ref S s);

and the call:

    foo(s.ptr, s);

August 02, 2019
On 7/15/2019 1:31 PM, Max Haughton wrote:
> I think this DIP should at least consider expanding its scope to use the reaching definition analysis.
> 
> It seems slightly pointless if, even if it's already opt in, that we can bypass it so easily e.g. by assigning a temporary.
> 
> Or is it really *that* complicated to allow the compiler to analyse this?

This is what will happen in a later proposal which will do comprehensive data flow analysis per function.
August 03, 2019
On Friday, 2 August 2019 at 08:09:22 UTC, Walter Bright wrote:
> On 7/15/2019 1:31 PM, Max Haughton wrote:
>> I think this DIP should at least consider expanding its scope to use the reaching definition analysis.
>> 
>> It seems slightly pointless if, even if it's already opt in, that we can bypass it so easily e.g. by assigning a temporary.
>> 
>> Or is it really *that* complicated to allow the compiler to analyse this?
>
> This is what will happen in a later proposal which will do comprehensive data flow analysis per function.

So... still not addressing the safety holes pointed out in above comments?

Or is it coming in the next DIP iteration?
August 03, 2019
On Saturday, 3 August 2019 at 09:52:24 UTC, Olivier FAURE wrote:
> On Friday, 2 August 2019 at 08:09:22 UTC, Walter Bright wrote:
>> On 7/15/2019 1:31 PM, Max Haughton wrote:
>>> I think this DIP should at least consider expanding its scope to use the reaching definition analysis.
>>> 
>>> It seems slightly pointless if, even if it's already opt in, that we can bypass it so easily e.g. by assigning a temporary.
>>> 
>>> Or is it really *that* complicated to allow the compiler to analyse this?
>>
>> This is what will happen in a later proposal which will do comprehensive data flow analysis per function.
>
> So... still not addressing the safety holes pointed out in above comments?
>
> Or is it coming in the next DIP iteration?

It's obvious where this is going, it's going to get added without a thought out complete DIP like DIP1000. This review process is just a charade.
August 30, 2019
On Thursday, 25 July 2019 at 12:03:19 UTC, Nick Treleaven wrote:
> On Friday, 19 July 2019 at 22:36:40 UTC, Olivier FAURE wrote:
>>     byte* identity(ref return byte b) @safe {
>>         return &b;
>>     }
>
> When I saw this (last week), I was surprised it compiled, but it does (with -dip1000). The returned pointer is scope, but that has a different lifetime from ref returns, which only last for the line that called the function.
>
> I don't think `return &b` should compile

https://issues.dlang.org/show_bug.cgi?id=20183



August 31, 2019
On Monday, 15 July 2019 at 15:23:32 UTC, Mike Parker wrote:
> This is the feedback thread for the first round of Community Review for DIP 1021, "Argument Ownership and Function Calls":
>
> https://github.com/dlang/DIPs/blob/793f83911fdc8c88c6ef34e6a36b5e11e3e574e5/DIPs/DIP1021.md

The problem with this DIP is that it's just a small part of some bigger thing, and it looks like no one understands this bigger thing except maybe Walter. It also seems that some people don't believe that Walter actually knows what the end result will be. Maybe he's just making it up as he goes along?
Anyway, all of this confirms my opinion - D is a language supposed to work with GC, and all these contortions are just trying to fit a square peg into a round hole.
Just use Rust instead.
September 11, 2019
On Monday, 15 July 2019 at 15:23:32 UTC, Mike Parker wrote:
> This is the feedback thread for the first round of Community Review for DIP 1021, "Argument Ownership and Function Calls":
>
> https://github.com/dlang/DIPs/blob/793f83911fdc8c88c6ef34e6a36b5e11e3e574e5/DIPs/DIP1021.md
>
> All review-related feedback on and discussion of the DIP should occur in this thread. The review period will end at 11:59 PM ET on July 30, or when I make a post declaring it complete.
>
> At the end of Round 2, if further review is deemed necessary, the DIP will be scheduled for another round of Community Review. Otherwise, it will be queued for the Final Review and Formal Assessment.
>
> For some additional context on this DIP, please see Walter's latest post on the D Blog titled "Ownership and Borrowing in D":
>
> https://dlang.org/blog/2019/07/15/ownership-and-borrowing-in-d/
>
> But *please do not discuss the blog post or its topic in this thread*! Use my post in the Announce forum for that:
>
> https://forum.dlang.org/post/hetwxvibgqcmoltvnoda@forum.dlang.org
>
> Anyone intending to post feedback in this thread is expected to be familiar with the reviewer guidelines:
>
> https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md
>
> I will be moving (copying, deleting, and pasting in a new thread) posts that do not adhere to the reviewer guidelines. So please keep all comments in this thread focused on DIP 1021.
>
> Thanks in advance to all who participate.

I recently discovered a programming language called "Pony" (https://www.ponylang.io/) and I believe it has an interesting take on the pointer aliasing problem that is quite different than Rust and is more akin to how D addresses such problems (e.g. through attribution).

Pony uses what they call "Reference Capabilities" to tell the compiler how references can or cannot be aliased, and I think it is relevant to the same problem that this DIP and other efforts within D are trying to solve.

You can find more information here:
https://tutorial.ponylang.io/reference-capabilities
https://zartstrom.github.io/pony/2016/08/28/reference-capabilities-in-pony.html
https://www.youtube.com/watch?v=HGDSnOZaU7Y&t=1869s

I hope you find it interesting if not influential.

Mike
1 2 3 4 5 6 7 8