On Sunday, 29 May 2016 at 14:27:51 UTC, Nick Treleaven wrote:
What about if the RCArray (of ref count 1) is assigned to a
different one after the local ref is initialised? That is what
we're discussing -it's your example above(!)
Exactly, and then one of the two suggested approaches will have
to be used to prevent the use-after-free. But that's something
that needs to happen on assignment, not when the reference is
created.
It can be solved in one of two ways: Either by making the
owner (`arr`) non-mutable during the existence of the
references, thereby forbidding the call to `bar()` (I would
prefer this one, as it's cleaner and can be used for many
more things, e.g. the byLine problem)
I don't see directly how this affects byLine.front, that does
not return a reference.
It returns a reference in the wider sense, namely a slice to a
private buffer that gets overwritten by each call to `byLine`.
Currently, DIP25 only applies to `ref`s in the narrow sense,
but I'm assuming it will be generalized to include pointer,
slices, class references, AAs and hidden context pointers.
Making the ByLine range constant as long as there's a
reference to its buffer would prevent surprises like this:
auto lines = stdin.byLine.array;
// => all elements of `lines` are the same, should have
used `byLineCopy`
So your solution would statically prevent popFront because
front has escaped.
Yes.
I think we should just prevent front from escaping.
It doesn't necessarily need to escape for the problem to occur.
Well, it does in this example, but it can be trivially rewritten:
auto tmp = stdin.byLine;
auto lines = tmp.array;
Here, `lines` contains references to the buffer owned by `tmp`,
but doesn't escape (assuming `array` takes its argument by
`scope` or however the final solution will look like).