I encountered an ugly problem. Actually, I had already run into it in my first proposal, but Steven Schveighoffer just posted about it here, which made me aware again:

http://forum.dlang.org/thread/mcqcor$aa$1...@digitalmars.com#post-mcqk4s:246qb:241:40digitalmars.com

    class T {
        void doSomething() scope;
    }
    struct S {
        RC!T t;
    }
    void main() {
        auto s = S(RC!T()); // `s.t`'s refcount is 1
        foo(s, s.t);        // borrowing, no refcount changes
    }
    void foo(ref S s, scope T t) {
        s.t = RC!T();       // drops the old `s.t`
        t.doSomething();    // oops, `t` is gone
    }

This (and similar things) are the reason I introduced "const borrowing", a way for an object to make itself temporarily const, as long as borrowed references to it exist. Unfortunately, this was broken in the presence of aliasing: When another alias (in the above example, imagine another pointer to `s`) of the owning struct existed before the borrowing took place, it was not affected by the change to const.

Now that I know a bit more about linear type systems (but am not an expert by any means), I understand why it happens. I suspect that the only way to really prevent problems of this kind is a full blown linear type system, i.e. one that guarantees that to each object there is at most one mutable reference.

The question is: What do we do about it? Maybe there is actually a way to fix this problem without a borrow checker? Any type system gurus here?

Or we could simply live with it and make it a convention not to pass RC objects (or related types) into situations where it can be a problem. I don't like that option, though.

Or we implement a borrow checker... It doesn't have to be as fancy as Rust's, i.e. we don't need to have data flow analysis. Just a lexical scope based solution would work.

Any other ideas and opinions?

On a positive note, I did some experiments with the inference algorithm, and I'm reasonably sure it works (absent un-@safe operations like `delete` and `free()`, of course). Here are the examples:

http://wiki.dlang.org/User_talk:Schuetzm/scope2

I'm going to try and formalize it during the next days.

Reply via email to