On Tuesday, 26 May 2015 at 15:21:04 UTC, Marc Schütz wrote:
On Tuesday, 26 May 2015 at 14:59:38 UTC, Per Nordlöw wrote:
On Tuesday, 26 May 2015 at 10:19:52 UTC, Marc Schütz wrote:
... to be used in templates and for enforcing these rules:
http://wiki.dlang.org/User:Schuetzm/scope3#.40safe-ty_violations_with_borrowing
There's at least a plan. Nice!
One thing, though. I'm lacking a section in the document
linked above on how `foreach` could be `scope`-enhanced so
that an element reference of an aggregate doesn't escape its
foreach scope.
char[] saved_line;
string saved_str;
foreach (scope line; File("foo.txt").byLine)
{
saved_line = line; // should give error
saved_line = line.dup; // should be ok
saved_str = line.to!string; // should be ok
}
provided that `byLine` returns a reference to a volatile
internal buffer.
Assuming you mean by "volatile" that the buffer is released
upon destruction:
No, with volatile I mean that the buffer contents changes with
each iteration.
The compiler is supposed to do that automatically, i.e. `scope`
annotations on local variables are always inferred. In your
No, DMD cannot currently handle scope on foreach elements. It
errors as
Error: basic type expected, not scope
example, it would figure out that you're assigning a reference
to a value with shorter lifetime (i.e. the slice to the buffer)
to a value with longer lifetime (saved_line), which it would
disallow. (Btw, I don't think to!string is enough, because it
is probably a no-op in this case: string -> string).
No to!string is not a no-op in this case. It allocates but it
needs to create an immutable char array that is: char[] -> string
However, byLine has another problem, which boils down to the
same cause as the problem with RCArray, namely that the content
of the buffer is reused in each iteration.
This is what I meant with volatile. Is there a better word for
this?
the "owner" can be modified while references to it exist. For
byLine, this is not a safety violation, but for RCArray it is.
A solution applicable to both is to detect this and then either
treat such a situation as @system, or make the owner `const` as
long as the references are alive.
AFAIK: Allowing scope in foreach would solve this problem in my
case.