March 02, 2015
On Monday, 2 March 2015 at 22:58:19 UTC, Walter Bright wrote:
> I.e. the postblit manipulates the ref count, but does NOT do payload deletions. The destructor checks the ref count, if it is zero, THEN it does the payload deletion.
>
> Pretty dazz idea, dontcha think? And DIP25 still stands unscathed :-)
>
> Unless, of course, we missed something obvious.

Add me to "we". I'm dazzed! :-)
March 03, 2015
On Monday, 2 March 2015 at 22:58:19 UTC, Walter Bright wrote:
> His insight was that the deletion of the payload occurred before the end of the lifetime of the RC object, and that this was the source of the problem. If the deletion of the payload occurs during the destructor call, rather than the postblit,

RcArray, a struct, already does this. You wouldn't delete in a postblit anyway would you? Do you need opRelease and ~this to be separate for structs too?
March 03, 2015
On 3/2/15 4:01 PM, Zach the Mystic wrote:
> On Monday, 2 March 2015 at 22:58:19 UTC, Walter Bright wrote:
>> His insight was that the deletion of the payload occurred before the
>> end of the lifetime of the RC object, and that this was the source of
>> the problem. If the deletion of the payload occurs during the
>> destructor call, rather than the postblit,
>
> RcArray, a struct, already does this. You wouldn't delete in a postblit
> anyway would you?

Deletion occurs in opAssign.

> Do you need opRelease and ~this to be separate for
> structs too?

Probably not.


Andrei
March 03, 2015
On Monday, 2 March 2015 at 22:58:19 UTC, Walter Bright wrote:
> His insight was that the deletion of the payload occurred before the end of the lifetime of the RC object, and that this was the source of the problem. If the deletion of the payload occurs during the destructor call, rather than the postblit, then although the ref count of the payload goes to zero, it doesn't actually get deleted.
>
> I.e. the postblit manipulates the ref count, but does NOT do payload deletions. The destructor checks the ref count, if it is zero, THEN it does the payload deletion.

I guess you also mean opAssigns -- they would manipulate refcounts too right? In fact, they would be the primary means of decrementing the refcount *apart* from the destructor, right?
March 03, 2015
On Tuesday, 3 March 2015 at 00:05:50 UTC, Zach the Mystic wrote:
> I guess you also mean opAssigns -- they would manipulate refcounts too right? In fact, they would be the primary means of decrementing the refcount *apart* from the destructor, right?

Nevermind. I was a minute too soon with my post!
March 03, 2015
On 3/2/2015 3:47 PM, weaselcat wrote:
> That's actually very old(0.6 - nearly 2 years ago.) I believe rooting was
> dropped from the language completely.
>
> http://doc.rust-lang.org/book/ownership.html
>
> also, rust by example chapter 17-19 cover this
> http://rustbyexample.com/move.html

Thanks for the info. But I don't see how Marc's example is prevented by this.
March 03, 2015
On Tuesday, 3 March 2015 at 00:08:10 UTC, Walter Bright wrote:
> On 3/2/2015 3:47 PM, weaselcat wrote:
>> That's actually very old(0.6 - nearly 2 years ago.) I believe rooting was
>> dropped from the language completely.
>>
>> http://doc.rust-lang.org/book/ownership.html
>>
>> also, rust by example chapter 17-19 cover this
>> http://rustbyexample.com/move.html
>
> Thanks for the info. But I don't see how Marc's example is prevented by this.

It wouldn't be compilable(it borrows the same object mutably twice)
I think so, anyways. I'm not that big on rust.


    During a borrow, the owner may NOT (a) mutate the resource, or (b) mutably lend the resource.
    During a mutable borrow, the owner may NOT (a) access the resource, or (b) lend the resource.
March 03, 2015
On Monday, 2 March 2015 at 22:51:03 UTC, Walter Bright wrote:
> On 3/2/2015 1:12 PM, deadalnix wrote:
>> I do think you are confusing how Rust does it. In Rust, borrowing makes the
>> source and borrowed reference immutable by default. So by default the problem do
>> not occurs.
>
> May I refer you to:
>
> http://static.rust-lang.org/doc/0.6/tutorial-borrowed-ptr.html#borrowing-managed-boxes-and-rooting
>
> "Again the lifetime of y is L, the remainder of the function body. But there is a crucial difference: suppose x were to be reassigned during the lifetime L? If the compiler isn't careful, the managed box could become unrooted, and would therefore be subject to garbage collection. A heap box that is unrooted is one such that no pointer values in the heap point to it. It would violate memory safety for the box that was originally assigned to x to be garbage-collected, since a non-heap pointer---y---still points into it.
> [...]
> For this reason, whenever an & expression borrows the interior of a managed box stored in a mutable location, the compiler inserts a temporary that ensures that the managed box remains live for the entire lifetime. [...] This process is called rooting."
>
>
> It's possible that this is an old and obsolete document, but it's what I found.

Yes, this page is obsolete, but it is still very interesting as it is a viable solution for us.
March 03, 2015
On Tuesday, 3 March 2015 at 00:08:10 UTC, Walter Bright wrote:
> On 3/2/2015 3:47 PM, weaselcat wrote:
>> That's actually very old(0.6 - nearly 2 years ago.) I believe rooting was
>> dropped from the language completely.
>>
>> http://doc.rust-lang.org/book/ownership.html
>>
>> also, rust by example chapter 17-19 cover this
>> http://rustbyexample.com/move.html
>
> Thanks for the info. But I don't see how Marc's example is prevented by this.

After moving resources, the previous owner can no longer be used.

That means you cannot borrow twice, which mean you can't get yourself into the mentioned situation.
March 03, 2015
On Monday, 2 March 2015 at 20:37:46 UTC, Walter Bright wrote:
> On 3/1/2015 12:51 PM, Michel Fortin wrote:
>> That's actually not enough. You'll have to block access to global variables too:
>>
>>     S s;
>>
>>     void main() {
>>         s.array = RCArray!T([T()]);   // s.array's refcount is now 1
>>         foo(s.array[0]);           // pass by ref
>>     }
>>     void foo(ref T t) {
>>         s.array = RCArray!T([]);      // drop the old s.array
>>         t.doSomething();              // oops, t is gone
>>     }

So with Andrei's solution, will s.array ever get freed, since s is a global? I guess it *should* never get freed, since s is a global and it will always exist as a reference.

Which makes me think about a bigger problem... when you opAssign, don't you redirect the variable to a different instance? Won't the destructor then destroy *that* instance (or not destroy it, since it just got a +1 count) instead of the one most recently decremented? How does it hold onto the instance to be destroyed?