On Thursday, 13 November 2014 at 16:56:01 UTC, Nick Treleaven
wrote:
On 12/11/2014 17:16, "Marc Schütz" <[email protected]>" wrote:
On Wednesday, 12 November 2014 at 15:57:18 UTC, Nick Treleaven
wrote:
For example, taking a mutable borrowed pointer for a variable
means
you can't even *read* the original variable whilst the
pointer lives.
I think no one would try to make D do that, but Rust's reason
for
adding it is actually memory safety (I don't quite understand
it, but
it involves iterator invalidation apparently). It's possible
their
feature can be refined, but basically 'mut' in Rust really
means
'unique'.
In my proposal, there's "const borrowing". It still allows
access to the
owner, but not mutation. This is necessary for safe
implementation of
move semantics, and to guard against iterator invalidation. It
also has
other uses, like the problems with "transient range", e.g.
stdin.byLine(), which overwrite their buffer in popFront(). On
the other
hand, it's opt-in; by default, owners are mutable while
borrowed
references exist.
Looks good. Personally I've been meaning to study your (whole)
proposal, I think its a valuable analysis of what problems we
could/should solve.
Just from a quick look, I wonder if 'const borrowing' could
solve the scoped!C premature destruction problem:
C c = std.typecons.scoped!C();
// memory for c has already been freed (need auto c = ...)
If the destruction of Scoped is disallowed whilst an (implicit
alias this) borrow for c is alive, the compiler can generate an
error.
Const borrowing is not even necessary for that. The problem with
`std.typecons.scoped!C` is that it implicitly converts to `C`.
Instead, it should only convert to `scope!this(C)`, then the
assignment will be rejected correctly:
// ERROR: type mismatch: C != scope(C)
C c = std.typecons.scoped!C();
// ERROR: `c` outlives it's owner (temporary)
scope(C) c = std.typecons.scoped!C();
// OK: typeof(c) is now scoped!C
auto c = std.typecons.scoped!C();