On Tuesday, 13 May 2014 at 18:48:14 UTC, Walter Bright wrote:
On 5/13/2014 10:52 AM, Dicebot wrote:
It has to be transitive to be useful as borrowed pointer.
Consider this example:
{
scope A a; // has some internally managed resources
foo(a);
}
It is not safe to destruct a in the end of the scope here
because foo may have
stored references to a owned resources. But if foo signature
is `foo(scope ref A
a)` then compiler can statically verify that it is safe which
is the very point
of borrowing guarantees. It must be transitive to guarantee
anything of course.
If those internal resources of A are marked as refcounted, then
transitivity is not necessary. Consider also that a struct A
can completely control any escaping references - transitive
borrowing is not necessary.
No, it still can be necessary. `scope` can greatly help not only
with resource releasing, it is also missing tool to safely cast
from shared. Locking shared variable can return same variable
casted to scope qualifier which will guarantee that no reference
has been stored to shared object by the time lock is released.
And "if those are marked as refcounted" as assumption is no
better than "if those are owned by GC" ;)
Also A can only control escaping of any internal references only
by completely prohibiting access to it which is not good. You
have no means to say "feel free to use this reference as long as
you don't keep it outside of current scope". And you effectively
say "make all your array members private to keep borrowing
guarantees".
Rust situation is quite different here because all their safe
pointers have ownership/lifetime annotation. D doesn't and thus
imaginary scope/borrowed rules need to assume worst case
scenarios (which is still good enough for many cases).